Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2009.11.08;
Скачать: [xml.tar.bz2];

Вниз

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

 
@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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.007 c
15-1252653672
KSergey
2009-09-11 11:21
2009.11.08
SSI+PHP


15-1252299382
Andy BitOff
2009-09-07 08:56
2009.11.08
Java


8-1199439878
Alex_AA
2008-01-04 12:44
2009.11.08
Как проиграть файл *.avi?


2-1253127151
MoorZik
2009-09-16 22:52
2009.11.08
Вывести ТОЛЬКО папки без файлов


2-1253264946
dmitry1987
2009-09-18 13:09
2009.11.08
Проблема с SELECT (SQL)





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский