Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Delphi, .NET, Asm (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   сплайсинг GetProcAddress + получение RetEIP (https://forum.antichat.xyz/showthread.php?t=65485)

sn0w 26.03.2008 15:37

сплайсинг GetProcAddress + получение RetEIP
 
вот с какой задачей столкнулся, нужно перехватывать 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;
}
}

но этож заебешься писать.
кто что может посоветовать?

spider-intruder 26.03.2008 15:59

А че сплайсинг? Хук не катит? хотя что это изменит.. щас я пороюсь

0x0c0de 26.03.2008 16:02

>> // вот хз как получить RetEIP
Если не будет локальных переменных, то адрес возврата будет на вершине стека. Я так на асме писала - посмотри в отладчике сколько занимают локальные переменные и учитывай их

KEZ 26.03.2008 16:08

Цитата:

А че сплайсинг? Хук не катит? хотя что это изменит.. щас я пороюсь
Мда, паук-вторжение опять попытался сказать что-то умное...

Цитата:

Если не будет локальных переменных, то адрес возврата будет на вершине стека. Я так на асме писала - посмотри в отладчике сколько занимают локальные переменные и учитывай их
ну да.. охрененное решение) не юзать переменные и надеется на то, что случай подвернется и будет все на вершине.. а про push reg перед использованием (ebx,esi,edi,ebp) мы забыли

0x0c0de 26.03.2008 16:16

я не говорю что их не юзать. я говорю посмотреть в отладчике

Xserg 26.03.2008 16:28

DWORD ret_eip = (DWORD)&hmod - 4;

вернее

DWORD *p = (DWORD *)&hmod - 1;
DWORD ret_eip = p[0];

0x0c0de 26.03.2008 16:42

>>а про push reg перед использованием
м=\. а ну да, ты прав

Код:

1000102A    55              PUSH EBP
1000102B    8BEC            MOV EBP,ESP
1000102D    83C4 F8        ADD ESP,-8 ; две локальные переменные

это если в асме. [esp+0с] - адрес возврата. если без локальных, то [esp+4]

sn0w 26.03.2008 17:16

всем спасибо, проблема решена :)

KEZ 26.03.2008 21:13

вот ещё одно отличие программиста от хакера с античата... программист не будет делать все через жопу ради быстрого эффекта, а подумает сначала (АСМ вставки это признак необразованости и их надо стараться избегать в программах на С и С++ как минимум)

Код:

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");



Время: 03:49