Форум: "Сети";
Текущий архив: 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