вот с какой задачей столкнулся, нужно перехватывать GetProcAddress в целях реверсирования одной байды. итак имеем следующее: FARPROC (__stdcall* gGetProcAddress)(HMODULE,LPCSTR); - указатель на оригинальную функцию которая вызывается в конце, и собсна сам перехватчик: FARPROC __stdcall fGetProcAddress(HMODULE hmod, LPCSTR proc) { DWORD io; DWORD ret_eip; char buf[200]; __asm{ // вот хз как получить RetEIP push eax; mov eax,[esp+4]; //тут ясен хер в стеке переменные перехватчика mov ret_eip,eax; pop eax; } g_dwCallnum++; itoa(g_dwCallnum, buf, 10); WriteFile(g_hLog, buf, lstrlenA(buf), &io, 0); WriteFile(g_hLog, ") GetProcAddress: ", 18, &io, 0); WriteFile(g_hLog, proc, lstrlenA(proc), &io, 0); WriteFile(g_hLog, " RetEIP: ", 9, &io, 0); itoa(ret_eip, buf, 16); WriteFile(g_hLog, buf, lstrlenA(buf), &io, 0); WriteFile(g_hLog, "\r\n", 2, &io, 0); // В лог пишется таким образом: 1) GetProcAddress: ExitWindowsEx RetEIP: 40178A // Но ессна по вставке асма ясно что RetEIP будет полнейшим бредом. return gGetProcAddress(hmod,proc); } Какбы сделать так чтобы извлекать адрес возврата? была мысль оформить тело перехватчика в стиле __declspec(naked) __stdcall fGetProcAddress(HMODULE hmod, LPCSTR proc) { __asm { // тут код записи лога jmp gGetProcAddress; } } но этож заебешься писать. кто что может посоветовать?
>> // вот хз как получить RetEIP Если не будет локальных переменных, то адрес возврата будет на вершине стека. Я так на асме писала - посмотри в отладчике сколько занимают локальные переменные и учитывай их
Мда, паук-вторжение опять попытался сказать что-то умное... ну да.. охрененное решение) не юзать переменные и надеется на то, что случай подвернется и будет все на вершине.. а про push reg перед использованием (ebx,esi,edi,ebp) мы забыли
>>а про push reg перед использованием м=\. а ну да, ты прав Code: 1000102A 55 PUSH EBP 1000102B 8BEC MOV EBP,ESP 1000102D 83C4 F8 ADD ESP,-8 ; две локальные переменные это если в асме. [esp+0с] - адрес возврата. если без локальных, то [esp+4]
вот ещё одно отличие программиста от хакера с античата... программист не будет делать все через жопу ради быстрого эффекта, а подумает сначала (АСМ вставки это признак необразованости и их надо стараться избегать в программах на С и С++ как минимум) Code: FARPROC (WINAPI *gGetProcAddress)(HMODULE hModule,LPCTSTR lpProcName); FARPROC WINAPI fGetProcAddressEip(ULONG dwRetEip,HMODULE hModule,LPCTSTR lpProcName) { CHAR szMsg[255]; wsprintf(szMsg,"hModule=%08x,lpProcName=%08x,dwRetEip=%08x",hModule,lpProcName,dwRetEip); MessageBox(0,szMsg,"GetProcAddress",0); return gGetProcAddress(hModule,lpProcName); } FARPROC __declspec(naked) WINAPI fGetProcAddressStub(HMODULE hModule,LPCTSTR lpProcName) { __asm { push dword ptr [esp] jmp fGetProcAddressEip } } // ... Splice( (ULONG)(GetProcAddress(GetModuleHandle("kernel32.dll"),"GetProcAddress")), fGetProcAddressStub, (PULONG)&gGetProcAddress ); GetProcAddress(GetModuleHandle("kernel32.dll"),"IsDebuggerPresent");