Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.11.08;
Скачать: CL | DM;

Вниз

Перехват Сокетов   Найти похожие ветки 

 
@dimon   (2007-01-25 08:23) [0]

В своей программе мне необходимо перехватить функцию Send библиотеки WinSock. Использую глобальный Хук, но почему -то приложение вызывающее WinSock выдает ошибку: "Приложение выполнело недопустимую операцию и будет закрыто". Для других API перехват происходи нормально. В чем может быть причина? Приведу процедуру перехвата.

function MySock(s:TSocket; var Buf; len, flags: Integer): Integer; stdcall;
begin
 result:=Send(s,Buf,len,flags);
 MessageBoxA(0, PChar(Buf), "my hook", 0);
end;

procedure ProcessImports(PImports:PImageImportDescriptor);
   Var
       PImport:PImageImportDescriptor;
       PRVA_Import:LPDWORD;
       ProcAddress:pointer;
       Temp_Cardinal:cardinal;
   begin
     ProcAddress:=GetProcAddress(GetModuleHandle("WINSOCK.DLL"), "Send");
     PImport:=PImports;
     while PImport.Name<>0 do
       begin
         PRVA_Import:=LPDWORD(pImport.FirstThunk+ImageBase);
         while PRVA_Import^<>0 do
         begin
           if PPointer(PRVA_Import)^=ProcAddress
              then
                begin
                  VirtualProtect(PPointer(PRVA_Import),4,PAGE_READWRITE,Temp_Cardinal);
                  PPointer(PRVA_Import)^:=@MySock;  
                 VirtualProtect(PPointer(PRVA_Import),4,Temp_Cardinal,Temp_Cardinal);
                end;
           Inc(PRVA_Import);
         end;
      Inc(PImport);
  end;
end;

Примерно так.


 
Сергей М. ©   (2007-01-25 09:36) [1]


> function MySock(s:TSocket; var Buf; len, flags: Integer):
>  Integer; stdcall;
> begin
>  result:=Send(s,Buf,len,flags);
>  MessageBoxA(0, PChar(Buf), "my hook", 0); //<- здесь брейкпойнт ловишь ?
> end;
>


 
@dimon   (2007-01-25 16:00) [2]


> Сергей М. ©

Я пытаюсь посмотреть текст проходящий через Сокет. Для эксперимента ставлю
MessageBoxA. Возможно на нем и происходит ошибка, по крайней мере окно MessageBox не появляется.


 
Сергей М. ©   (2007-01-25 16:08) [3]


> @dimon   (25.01.07 16:00) [2]


тебе профому, а ты все про ерему)

Вопрос поставлен - жду ответа ...


 
Сергей М. ©   (2007-01-25 16:09) [4]


> текст проходящий через Сокет


Это тебе Gушкин сказал. что там "проходит" именно текст ?


 
@dimon   (2007-01-25 17:32) [5]


> что там "проходит" именно текст ?

Да проходит именно тект. А вообще на счет MessageBox возникли сомнения. Почему - то не проходит динамическая загрузка библиотеки WinSock. Т.е. код:

Type
T=function (s: TSocket; var Buf; len, flags: Integer): Integer; stdcall;
var
 Msg:T;
 h:THandle;
begin
   h:=LoadLibrary("WinSock.dll");
   @Msg:=GetProcAddress(H,"Send");
   if @Msg=nil then
    ShowMessage("");
end;


Выдает ошибку :Библиотека WinSock не является образом программы для Windows NT


 
Сергей М. ©   (2007-01-26 08:15) [6]

Грузи ws2_32.dll


 
@dimon   (2007-01-26 08:28) [7]


> Грузи ws2_32.dll


Вызов @Msg:=GetProcAddress(H,"Send"); Возвращает nil


 
@dimon   (2007-01-26 08:40) [8]


> Вызов @Msg:=GetProcAddress(H,"Send"); Возвращает nil

C этим разобрался (Send = SendTo).Что за библиотека ws2_32.dll? Почему WinSock не грузится?


 
Сергей М. ©   (2007-01-26 08:41) [9]


> Вызов @Msg:=GetProcAddress(H,"Send"); Возвращает nil


потому что ф-ция называется "send", а не "Send".
Прочувствуй разницу)

p.s. Коль уж ты занялся нетривиальной задачей - перехватом, стыдно не знать такие элементарные вещи, как регистрочувствительность сист.загрузчика к именам экспортируемых символов.


 
@dimon   (2007-01-26 09:06) [10]

потому что ф-ция называется "send", а не "Send".
Вопрос не в этом. Интересно почему не грузится библиотека Winsock.dll. И существует ли другие способы отправки сообщений в сеть, кроме функции send?


 
Сергей М. ©   (2007-01-26 09:32) [11]


> почему не грузится библиотека Winsock.dll


Потому что этот модуль не является PE-модулем


> существует ли другие способы отправки сообщений в сеть,
> кроме функции send?


SendTo, WSASend


 
@dimon   (2007-01-26 09:38) [12]

На сколько я знаю WSASend из другой версии Winsock. В какой библиотеки она находится? Можно ли получить IP - адрес получателя сообщения посланного функцией send, не перехватывая подключение к серверу?


 
Сергей М. ©   (2007-01-26 09:52) [13]


> WSASend из другой версии Winsock. В какой библиотеки она
> находится?


ws2_32.dll


> Можно ли получить IP - адрес получателя сообщения посланного
> функцией send, не перехватывая подключение к серверу?


Можно, но зачем ?
Гораздо проще перехватить [WSA]Connect


 
@dimon   (2007-01-26 10:00) [14]


> Можно, но зачем ?


Просто нужно одновременно получить и текст сообщения и кому он предназначен, при том, что функция отправки сообщения неизвестна.


 
Сергей М. ©   (2007-01-26 10:08) [15]


> функция отправки сообщения неизвестна



> функция отправки сообщения неизвестна


Их не так уж и много, всего-то 4 - send, sendto, WSASend, WSASendTo.
Перехватывай все.


> нужно одновременно получить и текст сообщения и кому он
> предназначен


Это возможно только для connectionless-протоколов и ф-ции [WSA]SendTo - там в параметре фигурирует адресат.


 
Verg ©   (2007-01-26 10:20) [16]

Либо прилож. делает [WSA]sendto, либо можно узнать via getpeername.


 
@dimon   (2007-01-26 10:35) [17]


> либо можно узнать via getpeername

Можно подробнее?


 
@dimon   (2007-01-26 10:39) [18]

Вообще перехватывать необходимо сообщение от Proxy cервера Web Браузеру. Может ли в таком случае использоваться [WSA]send?


 
Сергей М. ©   (2007-01-26 10:52) [19]


> перехватывать необходимо сообщение от Proxy cервера Web
> Браузеру


Прокси - это сервер.
А сервер никогда не вызывает [WSA]Connect.

И если уж дело обстоит именно так (т.е. задача - перехватить прикладной траффик между прокси-сервером и его клиентом), то перехват WinsockAPI тут нафиг не нужен - пишется свой прокси-сервер и подключается в цепочку прокси-каскадирования:

Было:
Клиент <-> Имеющийся прокси <-> Тырнет

Стало:
Клиент <-> Имеющийся прокси <-> Твой прокси <-> Тырнет

И все ! И незачем все эти выкрутасы с "перехватом")


 
Verg ©   (2007-01-26 11:07) [20]

int getpeername(
 SOCKET s,
 struct sockaddr* name,
 int* namelen
);

The getpeername function retrieves the name of the peer to which a socket is connected.


 
@dimon   (2007-01-26 11:18) [21]


> Имеющийся прокси <-> Твой прокси

И все это на одной машине?


 
Verg ©   (2007-01-26 11:23) [22]


> Сергей М. ©   (26.01.07 10:52) [19]
>
> > перехватывать необходимо сообщение от Proxy cервера Web
>
> > Браузеру
>
>
> Прокси - это сервер.
> А сервер никогда не вызывает [WSA]Connect.


Ой ли?

Если сервер - это прокси , то connect-ов там будет.
На то он и proxy.


 
Сергей М. ©   (2007-01-26 11:29) [23]


> @dimon   (26.01.07 11:18) [21]
> И все это на одной машине?


На любой)
Как браузер и прокси настроишь, так и оно будет.


> Verg ©   (26.01.07 11:23) [22]


Имелась ввиду серверная ипостась прокси-приложения. Разумеется, прокси-приложение в другой его ипостаси само выступает клиентом для других серверов, об этом речь пока не идет.


 
@dimon   (2007-01-26 16:12) [24]

Снова проблема! Код
     ProcAddress:=GetProcAddress(GetModuleHandle("ws2_32.DLL"), "send"); возвращает nil. Вообще Handle библиотеки (GetModuleHandle("ws2_32.DLL")) возвращяется 0, хотя loadlibrary работает.


 
Сергей М. ©   (2007-01-26 16:55) [25]


> @dimon   (26.01.07 16:12) [24]


ну ты и упертый мужик, однако)

ты порло прокси-какскад проинтуичил ? Или об стенку горох ?


 
@dimon   (2007-01-28 09:14) [26]


> Сергей М. ©  

Уже просто интересно как это делается (перехват соектов). Может есть рабочий пример?


 
Сергей М. ©   (2007-01-29 08:20) [27]


> @dimon   (28.01.07 09:14) [26]


Ну ты же сделал перехват, и , сам говоришь, успешно)
Что ж тебе еще надобно, старче ?)


 
@dimon   (2007-01-29 16:57) [28]


> Сергей М. ©


Перехват я сделал, но тестировал его на других функциях. Работало. Переделал его по сокет ( библиотека ws2_32.dll функция send), есть программа (тестовая),которая явно вызывает send, перехватывающая програмка при тестирование ничего не выдает. Приведу полный текст своей Dll, посмотри пожалуйста, что не так.

library MSock;

uses
 sysutils,
 windows,
 winsock,
 messages;

type
  TImageImportDescriptor=packed record
   OriginalFirstThunk    : DWORD;
   TimeDateStamp         : DWORD;
   ForwarderChain        : DWORD;
   Name                  : DWORD;
   FirstThunk            : DWORD;
 end;
 PImageImportDescriptor=^TImageImportDescriptor;

var filename:array[0..max_path-1] of char;
   hook:HHook=0;
   PEHeader:PImageNtHeaders;
   ImageBase:cardinal;

function Mysend(s: TSocket; var Buf; len, flags: Integer): Integer;
stdcall;
begin
 MessageBox(0,PAnsiChar(Buf),"Перехват сокета",0);
 result:=   Send(s,Buf,Len,flags);
 //Но уже через нашу табл. импорта
end;
function MyGetProcAddress(hModule: HMODULE; lpProcName: LPCSTR): FARPROC;
stdcall;
begin
if lpProcName= "send" then
 result:=@MySend
 else
 result:=GetProcAddress(hModule,lpProcName);
 //Но уже через нашу табл. импорта
end;

procedure ProcessImports(PImports:PImageImportDescriptor);
   Var
       PImport:PImageImportDescriptor;
       PRVA_Import:LPDWORD;
       ProcAddress:pointer;
       GetAdr:pointer;
       Temp_Cardinal:cardinal;
   begin{1}
     ProcAddress:=GetProcAddress(Loadlibrary("ws2_32.DLL"), "send");
     MessageBox(0,"","",0);
     GetAdr:=GetProcAddress(GetModuleHandle("KERNEL32.DLL"), "GetProcAddress");

     PImport:=PImports;
     while PImport.Name<>0 do
       begin{2}
         PRVA_Import:=LPDWORD(pImport.FirstThunk+ImageBase);
         while PRVA_Import^<>0 do
         begin{3}
           if PPointer(PRVA_Import)^=ProcAddress
              then
                begin{4}
                  VirtualProtect(PPointer(PRVA_Import),4,PAGE_READWRITE,Temp_Cardinal);
                  PPointer(PRVA_Import)^:=@MySend; //пишем свою...
                  VirtualProtect(PPointer(PRVA_Import),4,Temp_Cardinal,Temp_Cardinal);
                end;{1}
            if PPointer(PRVA_Import)^=GetAdr
              then
                begin{4}
                  VirtualProtect(PPointer(PRVA_Import),4,PAGE_READWRITE,Temp_Cardinal);
                  PPointer(PRVA_Import)^:=@MyGetProcAddress; //пишем свою...
                  VirtualProtect(PPointer(PRVA_Import),4,Temp_Cardinal,Temp_Cardinal);
                end;{1}
           Inc(PRVA_Import);
         end;{2}
      Inc(PImport);
  end;{3}
end;{4}

procedure DllEntryPoint(reson:longint);stdcall;
begin
case reson of
 DLL_PROCESS_ATTACH:
    begin
     DisableThreadLibraryCalls(hInstance);
     ZeroMemory(@FileName, SizeOf(FileName));
     GetModuleFileName(GetModuleHandle(nil), @FileName, SizeOf(FileName));
     ImageBase:=GetModuleHandle(nil);
     PEHeader:=pointer(int64(ImageBase)+PImageDosHeader(ImageBase)._lfanew);//pe header
     ProcessImports(pointer(PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENT RY_IMPORT].VirtualAddress+ImageBase));
     end;
 end;
end;

function nexthook(code:integer;wParam,lParam:longint):longint;stdcall;
begin
 result:=callnexthookex(hook,code,wParam,lParam);
end;

procedure sethook(flag:bool);export; stdcall;
begin
if flag then
   hook:=setwindowshookex(wh_getmessage,@nexthook,hInstance,0)
else
  begin
   unhookwindowshookex(hook);
   hook:=0;
  end;
end;

exports sethook;

begin
 DLLProc:=@DllEntryPoint;
 DllEntryPoint(DLL_PROCESS_ATTACH)
end.
 


 
Сергей М. ©   (2007-01-29 17:07) [29]

Что говорит отладчик ?


 
@dimon   (2007-01-30 08:45) [30]

Отладчик ничего не говорит, но странно:
GetProcAddress(Loadlibrary("ws2_32.DLL"), "send");
возвращает nil. Что на счет рабочего примера?


 
Сергей М. ©   (2007-01-30 09:11) [31]


> @dimon   (30.01.07 08:45) [30]


> возвращает nil


Пробуй так:

hLib := Loadlibrary("ws2_32.DLL");
Win32Check(hLib <> 0);
ProcAddress := GetProcAddress(hLib, "send");
Win32Check(Assigned(ProcAddress));

Какие сообщения показывает этот код ?


 
@dimon   (2007-01-31 11:12) [32]


> Какие сообщения показывает этот код ?

Перехватывающая программа по прежнему ничего не выдает.


 
Сергей М. ©   (2007-01-31 11:34) [33]


> Перехватывающая программа по прежнему ничего не выдает.
>


Раз не выдает, значит твое утверждение в [30] насчет nil заведомо ложное.


 
@dimon   (2007-01-31 11:44) [34]

И что делать?


 
Сергей М. ©   (2007-01-31 11:56) [35]

Как что ? Трассировать дальше ..


 
имя   (2007-08-08 20:35) [36]

Удалено модератором


 
имя   (2007-08-08 20:35) [37]

Удалено модератором


 
имя   (2007-11-27 05:18) [38]

Удалено модератором


 
имя   (2008-05-04 02:43) [39]

Удалено модератором



Страницы: 1 вся ветка

Текущий архив: 2009.11.08;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.01 c
2-1252574162
vegarulez
2009-09-10 13:16
2009.11.08
Вопрос про Edit1.OnKeyPress (D7)


6-1169702635
@dimon
2007-01-25 08:23
2009.11.08
Перехват Сокетов


8-1198161253
ZXMaster
2007-12-20 17:34
2009.11.08
chroma key DirectShow


2-1253899875
tassa
2009-09-25 21:31
2009.11.08
Построение графика


15-1252604993
TUser
2009-09-10 21:49
2009.11.08
Самый главный вопрос Вселенной, жизни и всего такого ...