без CreateFile сплайс работает нормально (вставлял Beep), с CreateFile, SendMessage и т.п. браузеры падают: Код (Text): function HookRecv( s : TSocket; lpBuffers : LPWSABUF; dwBufferCount : DWORD; var lpNumberOfBytesRecvd : DWORD; var lpFlags : DWORD; lpOverlapped : LPWSAOVERLAPPED; lpCompletionRoutine : LPWSAOVERLAPPED_COMPLETION_ROUTINE ): Integer; stdcall; var RetCode : Integer; saddr : TSockAddrIn; slen : Integer; ip, port:Cardinal; WSA_LastError:Cardinal; h:THandle; buf:array [1..10] of char; written:Cardinal; begin RetCode:=MainRecv( s,lpBuffers,dwBufferCount, lpNumberOfBytesRecvd, lpFlags, lpOverlapped , lpCompletionRoutine); // WSA_LastError:=WSAGetLastError; asm pushad // pushf end; h:=CreateFileA('c:\asdasd.txt', GENERIC_WRITE, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); // без этих 3 строк работает WriteFile(h, buf, 2, written, nil); Closehandle(h); asm popad // popf end; Result:=RetCode; // WSAGetLastError(WSA_LastError); end; buf, конечно, заполняется. эти 3 строчки работают в пустой аппликации стэк, по идее, восстанавливается
Фаил 'c:\asdasd.txt' то ранее был создан? А то - OPEN_EXISTING Регистры в принципе не нужно сохранять/восстанавливать, компилятор должен сам оптимизировать.
Неа. Если б файл не был создан, вернулась бы ошибка FILE_NOT_FOUND и INVALID_HANDLE_VALUE Дальше просто не отработали б последующие 2 функции. Но креша не было б. Скорее всего с глобальными что-то не так. Например указатель на строку глобальную строку (с именем файла) в коде невалидный. Либо дельту не посчитал, либо еще что-то. Что говорит отладчик? Конкретно на какой функции падает?
использую любую WinApi и получаю либо крэш, либо "Ошибка 324 (net::ERR_EMPTY_RESPONSE): Сервер разорвал соединение, не отправив данные." следовательно портится возвращаемое значение либо стек, но как и почему
nMaxwell Вообще все зависит от способа передачи управления при сплайсинге фунок. Если вы передаете управление из перехватываемой функи при помощи jmpов ,может возникать следующая проблема. Если функа перехватчик формирует стек-фрейм ,а вызывается при помощи jmpов,это приводит к дестабилизации стека и фолтам на возврате из основной. Не знаю как на дельфях,на сишке эта проблема решается объявлением функи-перехватчика как _naked-ф-и.
Значит скорее всего то что я написал. Кстати,по поводу патчей неплохо в "The rootkit arsenal" написано. Magnum А какую вы видите связь между сплайсингом при помощи троянской длли и дельта-смещением?
проблема происходит именно при сплайсе recv (WSARecv), т.к. хук CreateProcessInternalW прекрасно отработал проблемы многопоточности быть не может, т.к. затирамые байты я самостоятельно воспроизвожу и ничего не восстанавливаю при вызове оригинальной функции
Ну что тут сказать... Если так ,то искать фолт под отладчиком. Я просто когда сам кодил такие вещи,часто сталкивался с проблемами со стек-фреймами и нарушениями конвенций вызовов (__cdecl вместо __stdcall) ,это второй вариант. Просто симптомы ,описанные вами сильно напоминают,то что я видел в своей поделке. Это довольно часто возникающие проблемы. Если описанный вами случай специфичен для recv, тогда только отладчик.
бред... написал программу-заглушку, вызывающую WSARecv и выводящую все параметры. затем сделал перехват, изменил все параметры, и оказалось, что все правильно хучится. следовательно вопрос: что не нравится хрому и опере? отлаживать в хроме несколько проблематично, точнее я не знаю чем это сделать максимально удобно (пытался в оле)
следовательно вопрос: что может не нравиться вашему аверскому ПО? )) Вчера хучил send в хроме патчем на возврате - никаких проблем.
А Shell extension? Всякие Яндекс-бары и прочее говно не стоит? Имхо где-то перехват ,на каком-то уровне. Возможно какие-то функи, специфичные для протокола. Хотя Http-функи вроде только IE юзает. Лучший способ - отладчик. Вроде в браузерах код хороший - дизасм легко разобрать.
AndjellaArtavazdovna можно сорец? =) возможно реально проблема в сплайсе, проявляющаяся только в WinSock :O голый хром, голый опера
Можно попробовать исполнить код в проекции ,но это возня с pebом и тогда лучше патчить проекцию,а не модуль.
AndjellaArtavazdovna я на коне и, чувствую, скоро забью на сплайс и буду в таблице импорта хучить GetProcAddress =( added: да
Ну в общем вот: Код (Text): #pragma comment (lib,"ws2_32.lib") #define STRICT #define WIN32_LEAN_AND_MEAN #include <stdio.h> #include <windows.h> #include <winsock2.h> char LogMessage[200]; #include "Error_log.h" #include "HttpLog.h" #define ARRAY_OF_PATCHES_SIZE 1 #pragma pack (push,1) typedef struct PrologData { BYTE PushCode; DWORD Address; BYTE RetCode; }PROLOG_DATA,*PPROLOG_DATA; #pragma pack (pop) typedef struct PatchData { PROLOG_DATA OrigCode; PROLOG_DATA PachCode; DWORD Address; DWORD NewAddress; }PATCH_DATA,*PPATCH_DATA; #define SEND_PTR (int (__stdcall*) (SOCKET,const char*,int,int)) PATCH_DATA Patches[ARRAY_OF_PATCHES_SIZE]; int _stdcall send_wraper(SOCKET socket, const char* buffer, int lenght, int flags) { wsprintfA(LogMessage,"%s started!\r\n",__FUNCTION__); WriteLogData(LogMessage); HANDLE hProcess = GetCurrentProcess(); DWORD Cnt; int Result; if(!WriteProcessMemory(hProcess, reinterpret_cast <LPVOID> (Patches[0].Address), &Patches[0].OrigCode, sizeof(PROLOG_DATA), &Cnt) || Cnt != sizeof(PROLOG_DATA)) { //ERROR wsprintfA(LogMessage,"WriteProcessMemory failed with error %d,%s\r\n",GetLastError(),__FUNCTION__); WriteLogData(LogMessage); } HttpWriteLogData(buffer,lenght); Result = (SEND_PTR Patches[0].Address)(socket,buffer,lenght,flags); Cnt = 0; if(!WriteProcessMemory(hProcess, reinterpret_cast <LPVOID> (Patches[0].Address), &Patches[0].PachCode, sizeof(PROLOG_DATA), &Cnt) || Cnt != sizeof(PROLOG_DATA)) { wsprintfA(LogMessage,"WriteProcessMemory failed with error %d,%s\r\n",GetLastError(),__FUNCTION__); WriteLogData(LogMessage); } wsprintfA(LogMessage,"%s exit!\r\n",__FUNCTION__); WriteLogData(LogMessage); return Result; } void PatchDataInitialize(PPATCH_DATA Array) { wsprintfA(LogMessage,"%s started!\r\n",__FUNCTION__); WriteLogData(LogMessage); //send hook: Array[0].Address = reinterpret_cast <DWORD> (GetProcAddress(GetModuleHandle(L"ws2_32.dll"), "send")); if(!Array[0].Address) { wsprintfA(LogMessage,"can not find send with error %d\r\n",GetLastError()); WriteLogData(LogMessage); } Array[0].NewAddress = reinterpret_cast <DWORD> (&send_wraper); WriteLogData(__FUNCTION__ "success!\r\n"); //Other: } void ProcessAllFunctions(PPATCH_DATA Array,BOOL Flag = TRUE) { int i; HANDLE hProcess = GetCurrentProcess(); SIZE_T Cnt; WriteLogData(__FUNCTION__ "started\r\n"); for(i = 0;i <= ARRAY_OF_PATCHES_SIZE-1;i++) { if(Flag) { Array[i].PachCode.PushCode = 0x68;//push Array[i].PachCode.Address = Array[i].NewAddress; Array[i].PachCode.RetCode = 0xC3; if(!ReadProcessMemory(hProcess, reinterpret_cast <LPCVOID> (Array[i].Address), &Array[i].OrigCode, sizeof(PROLOG_DATA), &Cnt) || Cnt != sizeof(PROLOG_DATA)) { //ERROR! wsprintfA(LogMessage,"ReadProcessMemory failed with error %d,%s\r\n",GetLastError(),__FUNCTION__); WriteLogData(LogMessage); } if(!WriteProcessMemory(hProcess, reinterpret_cast <LPVOID> (Array[i].Address), &Array[i].PachCode, sizeof(PROLOG_DATA), &Cnt) || Cnt != sizeof(PROLOG_DATA)) { wsprintfA(LogMessage,"WriteProcessMemory failed with error %d,%s\r\n",GetLastError(),__FUNCTION__); WriteLogData(LogMessage); } } else { if(!WriteProcessMemory(hProcess, reinterpret_cast <LPVOID> (Array[i].Address), &Array[i].OrigCode, sizeof(PROLOG_DATA), &Cnt) || Cnt != sizeof(PROLOG_DATA)) { wsprintfA(LogMessage,"WriteProcessMemory failed with error %d,%s\r\n",GetLastError(),__FUNCTION__); WriteLogData(LogMessage); } } } WriteLogData(__FUNCTION__ "exit\r\n"); } BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD Reason, LPVOID Reserved) { switch(Reason) { case DLL_PROCESS_ATTACH: if(LogInit() != NULL) { if(HttpLogInit() != NULL) { PatchDataInitialize(Patches); ProcessAllFunctions(Patches,TRUE); } } CloseHandle(LogFile); break; case DLL_PROCESS_DETACH: break;//Unhook case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; } return TRUE; }
AndjellaArtavazdovna спасибо, такой же сплайс у меня не работает.. видимо, есть другой коряво поставленный хук, из-за которого броузер падает. попробую на чистой хрюше