Comments 16
Тоже сталкивался с подобным. Написал обертку над mhook, чтобы в функцию-перехватчик передавались регистры. Перехват выглядит примерно так: надо прототипами функций особо не заморачиваюсь, зато можно ставить перехват где-нибудь посредине функции. Не уверен что это очень здорово, но мне нравится.
void hookProc(Context &context) {
SomeClass *someObj = (SomeClass*)context.ECX.value;
DWORD someval = context.EAX.value;
}
RegisterHook(0x0A0A0A0A, hookProc);
void hookProc(Context &context) {
SomeClass *someObj = (SomeClass*)context.ECX.value;
DWORD someval = context.EAX.value;
}
RegisterHook(0x0A0A0A0A, hookProc);
Тобишь, таким макаром можно получить значение локальных переменных перехватываемой функции?
Ну, да. [esp+xx].
[esp-xx]
Спасибо за идею!
Переписал часть кода под вашу либу(пока для 1 функции). Похоже, что работает великолепно для большинства соглашений о вызовах. Огромное спасибо!
Получилось что-то в таком духе:
void con_hook(Context *context)
{
int *ptr = (int*)(void*)(context->ESP+4);
debug_msg(«Advanced»,true,"--%s arg list started--", __FUNCTION__);
for(int i=0; i*4<resources_arg_amount; i++)
{
debug_msg(«Advanced»,true," |---Element %d: %d", i, ptr[i]);
}
debug_msg(«Advanced»,true,"--arg list finished--\n");
}
Получилось что-то в таком духе:
void con_hook(Context *context)
{
int *ptr = (int*)(void*)(context->ESP+4);
debug_msg(«Advanced»,true,"--%s arg list started--", __FUNCTION__);
for(int i=0; i*4<resources_arg_amount; i++)
{
debug_msg(«Advanced»,true," |---Element %d: %d", i, ptr[i]);
}
debug_msg(«Advanced»,true,"--arg list finished--\n");
}
На здоровье, конечно, но на всякий случай хочу предупредить, что не уверен что она является хорошим решением, или хорошей практикой, или вообще чем-то хорошим. Точно помню, что там был какой-то баг )). И, кажется, я перегружал квадратные скобки для регистров. (int*)(void*)(context->ESP+4) вроде это можно как-то по-другому переписать. Или нет. В любом случае, рад, что вам пригодилось.
clip2net.com/s/4LOCCZ
clip2net.com/s/4LODE9
Ну, с учетом того, что теперь функциональная часть выглядит как-то так, то еще как пригодилась) Что до багов — попробовал несколько функций, включая WSASend — полет нормальный.
(int*)(void*)(context->ESP+4) — вроде должен принимать как &context[EAX+4].
В любом случае, еще раз спасибо, жаль, не могу поднять карму :)
clip2net.com/s/4LODE9
Ну, с учетом того, что теперь функциональная часть выглядит как-то так, то еще как пригодилась) Что до багов — попробовал несколько функций, включая WSASend — полет нормальный.
(int*)(void*)(context->ESP+4) — вроде должен принимать как &context[EAX+4].
В любом случае, еще раз спасибо, жаль, не могу поднять карму :)
Круто, наконец на хабре появился технический топик. Спасибо ТС!
#define cdecl_hook(name1)\ /*Macro definition*/
void name1##_hook(int a1, ...)\ /*Declare hooker*/
{\
int check_s = 0;\
__asm{mov check_s, esp}\ /*Save esp state*/
int *ptr = &a1;\ /*Get pointer to 1st arg, equialent of va_list*/
debug_msg("Advanced",true,"--%s arg list started--", __FUNCTION__);\ /*debug_msg() - vfprintf wrapper*/
for(int i=0; i*4<name1##_arg_amount; i++)\
{\
debug_msg("Advanced",true," |---Element %d: %d", i, ptr[i]);\
}\ /*Arg list -> file(Advanced.txt)*/
debug_msg("Advanced",true,"--arg list finished--\n");\
__asm{lea ecx, a1}\ /*Move addr of a1 to ecx*/
__asm{mov eax, name1##_arg_amount}\ /*move size of args in stack(can get from IDA, for ex.) to eax*/
__asm{label_loop: }\ /*Start loop*/
__asm{mov ebx, dword ptr[ecx+eax-4]}\ /*Move args from stack to ebx in loop and push ebx*/
__asm{push ebx}\
__asm{sub eax,4}\
__asm{cmp eax,0}\
__asm{jg label_loop}\
__asm{call dword ptr[name1##_Detour]}\ /*Call original function*/
__asm{mov esp, check_s}\ /*Restore stack, same as __asm{add esp, name1##_arg_amount}*/
}\
Зачем было городить такой огород если можно сохранить весь контекст целиком? ASM вставки и С++ код как по мне так ней айс + Вы изменяете регистры — таким образом на fastcall у Вас будет геммор.
1) На данный момент не работает с __stdcall'ом, __thiscall'ом и другими соглашениями о вызовах. Не откажусь от помощи или совета по данному поводу.
Сохраняйте весь контекст + стэк, дальше идет детекция на аргументы в стэке, если не помогло — то только ручками указывать тип функции.
2) Как я уже упоминал, опыта в данном вопросе достаточно мало, так что вполне могут быть косяки, которых я не учел, так что просьба сильно не тролить.
Если любите OllyDbg то можете запилить расширение на эту тему в виде внешнего плагина. (кстати там в примерах есть пример breakpoint менеджера)
3) Не нашел аналогов, однако это не значит, что нету более адекватных способов / нельзя оптимизировать текущий. Замечания по данному поводу также были бы кстати.
Есть например утилита API Logger делающая примерно тоже самое.
Спасибо, многое из этого не знал.
Хотя зачем Вам OllyDbg? Если знаете Python то проще запилить расширение для ImmunityDebugger (форк с OllyDbg для активного пентестинга и реверсинга)
Мне IDA больше нравится.
Насколько Я помню модуль ida-x86emu не слишком стабилен чтобы использовать его для отладки реальных приложений (хотя некоторых это не останавливает)
www.idabook.com/x86emu/
www.idabook.com/x86emu/
Sign up to leave a comment.
[В разработке] Перехватчик функций с неизвестными аргументами