Пользовательское соглашение о вызовах C++

Во время обратного проектирования я наткнулся на очень странную программу, которая использует соглашение о вызовах, которое передает один аргумент в 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, если это имеет значение)


person Listing    schedule 07.10.2011    source источник


Ответы (1)


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

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

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

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

person tenfour    schedule 07.10.2011
comment
Я знаю, но MSVC fastcall использует ECX+EDX, а не EAX, поэтому это не то, что мне нужно :-( - person Listing; 08.10.2011
comment
Спасибо, я прибегнул к встроенному ассемблеру, как вы предложили, сначала я подумал, что вы почти всегда можете избежать встроенного ассемблера, это первая ситуация, с которой я сталкиваюсь, когда вы не можете. - person Listing; 08.10.2011