Комментарии 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);
0
Тобишь, таким макаром можно получить значение локальных переменных перехватываемой функции?
0
Ну, да. [esp+xx].
0
[esp-xx]
0
Спасибо за идею!
0
Переписал часть кода под вашу либу(пока для 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");
}
0
На здоровье, конечно, но на всякий случай хочу предупредить, что не уверен что она является хорошим решением, или хорошей практикой, или вообще чем-то хорошим. Точно помню, что там был какой-то баг )). И, кажется, я перегружал квадратные скобки для регистров. (int*)(void*)(context->ESP+4) вроде это можно как-то по-другому переписать. Или нет. В любом случае, рад, что вам пригодилось.
0
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].
В любом случае, еще раз спасибо, жаль, не могу поднять карму :)
0
Круто, наконец на хабре появился технический топик. Спасибо ТС!
+2
#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 делающая примерно тоже самое.
+1
Спасибо, многое из этого не знал.
-1
Хотя зачем Вам OllyDbg? Если знаете Python то проще запилить расширение для ImmunityDebugger (форк с OllyDbg для активного пентестинга и реверсинга)
0
Мне IDA больше нравится.
0
Насколько Я помню модуль ida-x86emu не слишком стабилен чтобы использовать его для отладки реальных приложений (хотя некоторых это не останавливает)
www.idabook.com/x86emu/
www.idabook.com/x86emu/
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
[В разработке] Перехватчик функций с неизвестными аргументами