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 с задержкой загрузки, вы, вероятно, увидите похожий шаблон, используемый в генерируемых компоновщиком функциях-заглушках.