2015-08-15 4 views
3

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

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

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

Тогда в C Я буду иметь призыв к ASM, как

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

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

jump (fn) ? 

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

+0

Необходимо выполнить соглашение о вызове stdcall на x86 и соглашение о вызове Microsoft x64 на x86. (На x86 нет stdcall). В зависимости от того, что вы делаете в MessageBoxW_asmstub, это можно сделать с помощью простой инструкции jmp fn. Это предполагает, что вы оставите все энергонезависимые и аргументные регистры вместе со стеком в том же состоянии, что и в точке входа в asmstub. В большинстве случаев это не должно быть сложно. –

ответ

0

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

extern fn:qword 

MessageBoxW_asmstub: 
    mov rax, fn 
    jmp rax 

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