C ++ пользовательское соглашение о вызовах - PullRequest
3 голосов
/ 08 октября 2011

При обратном проектировании я нашел очень странную программу, которая использует соглашение о вызовах, которое передает один аргумент в eax (очень странный компилятор ??). Я хочу вызвать эту функцию сейчас, и я не знаю, как объявить ее, IDA определяет ее как

bool __usercall foo<ax>(int param1<eax>, int param2);

где param1 передается в регистре eax. Я пробовал что-то вроде

bool MyFoo(int param1, int param2) 
{
    __asm mov eax, param1;
    return  reinterpret_cast<bool(__stdcall *)(int)>(g_FooAddress)(param2);
}

Однако, к сожалению, мой компилятор использует регистр eax при загрузке param2 в стек, есть ли способ, как я могу сделать это чисто, не записывая весь вызов встроенным ассемблером? (Я использую Visual Studio, если это имеет значение)

1 Ответ

2 голосов
/ 08 октября 2011

Существуют "нормальные" соглашения о вызовах, которые передают аргументы через регистры. Например, если вы используете MSVC, __fastcall.

http://en.wikipedia.org/wiki/X86_calling_conventions#fastcall

Вы не можете определить свои собственные соглашения о вызовах, но я бы посоветовал вам создать функцию-обертку, которая выполняет собственный вызов / очистку через встроенную сборку. Вероятно, это наиболее практично для достижения этого эффекта, хотя вы могли бы также сделать это быстрее, используя __fastcall, немного поменяв регистр, а затем jmp на правильную функцию.

Хотя в соглашении о вызовах есть нечто большее, чем передача аргументов, поэтому вариант № 1, вероятно, является наилучшим, поскольку вы получите полный контроль над тем, как действует вызывающая сторона.

...