MASM и C переходят к функции

У меня есть указатель на функцию __stdcall в C, и в ассемблере x86 и x64 мне бы хотелось иметь функцию asm, которую я могу использовать для перехода к этой функции.

Например возьмем функцию Windows API MessageBoxW

void *fn = GetProcAddress(GetModuleHandle("kernel32.dll"), MessageBoxW);

Тогда в C я буду звонить в ASM, как

void foo()
{
MessageBoxW_asmstub(NULL, "test", "test", NULL);
}

Предположим, что fn является глобальным. Затем в сборке я хотел бы иметь функцию, которая просто пересылает MessageBoxW, а не вызывает его. Другими словами, я хочу, чтобы MessageBoxW очистил переменные, переданные MessageBoxW_asmstub, а затем вернулся к foo

jump (fn) ?

Я не знаю, как это сделать.

1 ответ

Предполагая, что MessageBoxW_asmstub объявлен компилятору C как имеющий правильное соглашение о вызовах (то есть __stdcall для x86; для x64, к счастью, только одно соглашение о вызовах), тогда, как сказал комментарий от Ross Ridge, это так же просто, как перейти к цели функция, которая затем вернется непосредственно к вызывающей стороне. Поскольку у вас есть косвенная ссылка (т. Е. Fn ссылается на указатель на цель), вам, вероятно, понадобится другая инструкция загрузки (хотя мои знания о x86 здесь ограничены - я совсем не удивлюсь, если есть какая-то двойная косвенная) форма jmp). Для этого вы можете использовать любые энергозависимые регистры в соглашении о вызовах, например, для x64 вы можете использовать что-то вроде:

extern fn:qword

MessageBoxW_asmstub:
  mov rax, fn
  jmp rax

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

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