C++ __usercall перехват

Привет в IDA у меня есть функция

void __userpurge Test(int a1<eax>, int a2, int a3, int a4, char a5)

И я хотел бы подключить / вызвать его из моей C++, внедренной DLL Вот как я пытался вызвать его, но.exe падает

DWORD CALL_ORIGINAL = 0x00EAF6D0;
__declspec(naked) void  myHookedFunc(int a1,int a2,int a3,int a4,char a5) {
    __asm
 {

    push a5
    push a4
    push a3
    push a2
    push eax
    call  CALL_ORGIGINAL //maybe use JMP?
    retn

   }
}

И это, как exe вызывает эту функцию

mov     eax, [ebp+arg_4]
add     esp, 8
push    eax
push    ecx
mov     ecx, [edi+2138h]
mov     edx, [ecx+4]
mov     ecx, [edx+30h]
mov     edx, [ecx]
mov     eax, esp
mov     [eax], edx
mov     eax, [edi+20h]
mov     [esp+40h+var_24], esp
push    eax
push    eax
mov     eax, edi
call    Test
pop     edi
pop     esi  
retn

Несколько раз в функции, кажется,

add     esp, 24h
retn    10h

Что означало бы, что есть больше аргументов, или IDA получила неправильные типы аргументов?

1 ответ

__userpurge функции используют соглашение о вызовах, подобное __usercall за исключением того, что вызывающий отвечает за очистку стека. Однако, глядя на дополнительный код, который вы разместили, IDA вполне может указывать неверное количество параметров и неправильное соглашение о вызовах. Я предлагаю вам проверить это, установив точку останова в месте call CALL_ORGIGINAL и смотреть значение ESP до и после звонка. Если ESP отличается, когда он возвращается, то CALL_ORIGINAL очищает стек, и вам больше нечего делать. Если CALL_ORIGINAL очищает стек, вы, вероятно, можете определить количество передаваемых параметров, разделив разницу на 4 (при условии, что каждый параметр равен 32 бита).

Еще одна проблема, вы не должны толкать eax в стек (в соответствии с кодом вызова, включенным в ваше редактирование). Существующий код, который вызывает эту функцию, помещает первый параметр в eax но не помещает его в стек.

Исходя из кода в вашем вопросе и предположения, что количество параметров является правильным, ваша функция ловушки должна выглядеть примерно так, как показано ниже.

__declspec(naked) void  myHookedFunc(int a1,int a2,int a3,int a4,char a5) {
    __asm
 {

    push a5
    push a4
    push a3
    push a2
    // eax is not pushed onto the stack
    call CALL_ORGIGINAL
    retn
   }
}

Если соглашение о вызовах и количество параметров верны, ESP должен быть одинаковым до и после всех до CALL_ORIGINAL, Если это не так, вам нужно исследовать это немного больше, чтобы определить правильное соглашение о вызовах и параметры.

Короче говоря, никогда не доверяйте тому, что IDA, если вы сами не проверите это.

Другие вопросы по тегам