Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Сети > Зависание приложения


Автор: ZaDoXliK 6.12.2009, 23:35
Вечер добрый.
Есть 3 приложения, A - клиент, B - сервер, С - моя программа.
А и В обмениваются данными через сокет. Я с помощью программы C внедряюсь в программу A и посылаю пакет на В от имени А. Все прекрасно работает, пакет отсылается как положено но возникает проблема.

Проблема такая:
Приложение В зависает.

Для внедрения в чужой сокет использую DuplicateHandle.
Код

...
  AH,CH:Cardinal;
  NewHWND:HWND;
...
DuplicateHandle(AH,SName,CH,@NewHWND,0,False,DUPLICATE_SAME_ACCESS)

АН-сервер
SName-хендл сокета
СН-моё приложение.
NewHWND-дубликат.

Собственно говоря приложение А зависает после:
Код

TargetSocket:THandle;
...
TargetSocket:=NewHWND;
Send(TargetSocket,pointer(paket)^,Length(paket),0);


Пакет доходит нормально но приложение А зависает.
Если вызвать WSACleanup то приложение А перезапустится и все.
Т.е. после WSACleanup я так понимаю соединение с сервером теряется просто напросто, по этому и перезапускается А . Как избавится от зависания клиента (А)?

Автор: ZaDoXliK 7.12.2009, 02:48
Вариантов, идей, мыслей никаких нет? smile 

Автор: Демо 7.12.2009, 16:05
ZaDoXliK, 
Ты уверенЮ, что сервер понимает, что ты ему посылаешьь и умеет это обрабатывать?

Автор: ButtonOFF 7.12.2009, 16:32
Полный код в студию

Автор: kami 7.12.2009, 21:40
Цитата(ButtonOFF @  7.12.2009,  16:32 Найти цитируемый пост)
Полный код в студию

А смысл?
Демо, сказал правильно - неизвестно. как приложения отреагируют на отправку незапланированных данных. Например, в моих приложениях из-за этого пойдет неправильный учет переданной информации (причем - и на передающем и на приемном концах), из-за особенностей протокола обмена. Во что это выльется - без малейшего понятия, но ничего кроме AV и других исключений в голову не приходит...
Посему - не знаешь протокола обмена - нечего соваться.

Автор: ZaDoXliK 7.2.2010, 17:04
Цитата(Демо @ 7.12.2009,  14:05)
ZaDoXliK, 
Ты уверенЮ, что сервер понимает, что ты ему посылаешьь и умеет это обрабатывать?


Я отслеживал свой пакет программой WPE Pro. Так же пробовал и отсылать свой пакет через WPE Pro.
Результат один и тот же если.Пакет доходит,действие выполняетя на сервере но через WPE приложение А(клиент)не виснет и продолжает работать без изменений, а через мою программу оно зависает после команды Send.

Автор: ZaDoXliK 9.2.2010, 11:03
Еще вопрос.
Вот так работает.
Код

paket:=#$87#$98#$65#$87#$98#$AB
S:=Send(TargetSocket,pointer(paket)^,Length(paket),0);

Тут paket после отправки=6. Это правильно.Тут читается как hex значение.

А вот так не работает.
Код

В Memo1 перврй строкой написано (#$87#$98#$65#$87#$98#$AB) без скобок.
paket:=memo1.Lines.ValueFromIndex[номер строки];
S:=Send(TargetSocket,pointer(paket)^,Length(paket),0);


Тут paket после отправки=24. Это не правильно.Тут как обычный текст.

Как сделать что бы из Memo читалось hex значение?

Автор: ZaDoXliK 14.2.2010, 11:13
Странно,добавил строчку после DuplicateHandle  и приложение иногда не зависает.
Теперь код выглядит так:
Код

DuplicateHandle(AH,SName,CH,@NewHWND,0,False,DUPLICATE_SAME_ACCESS)
Application.ProcessMessage;
...
//Дальше посылка пакета.
Send(TargetSocket,pointer(paket)^,Length(paket),0);
//Тут сразу картинка приложения "А" застывает.Но действия посланные ему оно выполняет.

Возникло пару вопросов.
1)Когда делаю копию сокета,использую её-оригиналу нужно возвращать управление или оно и не теряется?
2)Может проблема зависания в том что приложение "А"(сокет которого я дублирую) построено на флешь?Ведь иногда оно не виснет,и я вижу все действия которые выполняются,а иногда экран просто замерзает, но пакеты отправляются на сервер и обрабатываются правильно.Тут уже наверно проблема с обновлением самого приложения.Т.е. нужно его как то обновить но без реконекта к серверу. Что то типа refresh или repaint.

Есть у кого идеи,может какие то предположения? Не боимся отвечать,все делаем ошибки,на этом же и учимся smile .

З.Ы.Сделал тестовый сервер и приложение которые обмениваются данными,и в этом случае ничего ни где не виснет.Думаю всё таки что проблема зависания экрана в приложении "А" это как раз то что оно на флеш построено.И там тупо картинка не обновляется после того как я посылаю пакет.

Автор: ZaDoXliK 16.2.2010, 15:54
Ребята,может кто ни будь продемонстрировать как использовать WSADuplicateSocket на примере? Гугл пишет одно и тоже,везде копипаст и нет толковых примеров.
Я там понимаю WSADuplicateSocket действует совсем по другому,не так как DuplicateHandle.
Последовательность действий подскажите хотя бы.
В DuplicateHandle я делаю так:
Код DLL
Код

library Hook;

uses
  Windows,
  Winsock,
  messages,
  SysUtils,
  madRemote,
  madCodeHook;

{$R *.RES}

var
 sendNextHook: function(s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
var
 strAppExe: string;

function GetModuleFileName: string;
var
 Buffer: array[0..MAX_PATH] of Char;
  begin
   ProcessIdToFilename(ProcessHandleToId (GetCurrentProcess()),Buffer);
 Result := StrPas(Buffer);
end;

procedure IPCLog(strWhat : String);
var
 Result : Integer;
begin
 strWhat := strAppExe + '-' + strWhat;
 SendIpcMessage('whooklib', pchar(strWhat), Length(strWhat), @result, sizeOf(result));
end;

function sendHookProc(s: TSocket; var Buf; Len, Flags: Integer): Integer; stdcall;
begin
 ipclog(inttostr(s));
 Result :=sendNextHook(s, Buf, Len, Flags);
end;

begin
 strAppExe := GetModuleFileName();
 hookapi('ws2_32.dll','send', @sendHookProc, @sendNextHook);
 hookapi('wsock32.dll','send', @sendHookProc, @sendNextHook);

end.


Использование в программе:
Код

//Процедура которая принимает данные из DLL. Сюда передаётся имя программы и ID сокета.
//В S2 хранится имя "жертвы",за ранее указанно в варах.
procedure RecvIPCmsg(name: pchar; messageBuf: pointer;
messageLen: dword; answerBuf: pointer; answerLen: dword);stdcall;
begin
S1:=StrPas(messageBuf);
PName:=Copy(S1,1,13);//В PName копирую первые 13 букв из названия найденного приложения.
Delete(S1,1,18);//Тут отсекаю лишний мусор из названия.
If PName=S2 then
begin
SName:=StrToInt(Copy(S1,1,4));//Тут выдераю ID сокета найденного окна.
Form1.M.Lines.Add('UNINJECTING');
UnInjectLibrary(ALL_SESSIONS or SYSTEM_PROCESSES, 'Hook.dll');//после нахождения нужного окна и получения ID сокета - выгружаю хук.
end;
end;
...
//процедура на нажатие кнопки.
...
CProc:=GetCurrentProcessID;//Находим свой ID процесса
GetWindowThreadProcessID(Arena,AProc);//Находими ID потока "Жертвы"
CH:=OpenProcess(PROCESS_ALL_ACCESS,FALSE,CProc);//Получаем дескриптор потока своего приложения
AH:=OpenProcess(PROCESS_ALL_ACCESS,FALSE,AProc); //Получаем дескриптор потока "Жертвы"
...
DuplicateHandle(AH,SName,CH,@NewHWND,0,False,DUPLICATE_SAME_ACCESS);//В AH хранится дескриптор "жертвы" от него мы берем копию,в SName ID сокета "жертвы" его мы дублируем для дальнейшего использования,CH-дескриптор моего приложения,ему я передаю копию,NewHWND это новый дублированный сокет.
...
//Тут я всё правильно делаю?
WSAStartup(2,WSA);
Paket:='Передаваемая информация';
Send(NewHWND,pointer(paket)^,Length(paket),0);//Длинна пакета и его содержимое правильные.
//Теперь возникает вопрос, что делать дальше? Нужно ли как то передать управление обратно "Жертве"?
//В том смысле что "жертва" получает мой паке, выполняет действие,можно сразу и другой пакет послать,он тоже отправится и обработается как положенно,но само приложение при этом будет висеть мёртвым грузом...

Автор: ZaDoXliK 9.4.2010, 14:00
Проблема решена другим способом. Простым и безболезненным  smile .

Тему можно закрывать.  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)