我正在Win32上编写一个X86应用程序级模拟器,它模拟可执行程序并挂钩其API调用,将它们转发给我的回调。 在那些回调中,我打印一些调试内容,然后调用实际的API,每个回调类似于:
int hook_MessageBoxA( emu_t *emu, mem_t *mem )
{
char *pszText, *pszTitle;
DWORD hwnd, text, title, button;
// pop arguments from the stack
STACK_POP(emu, &hwnd);
STACK_POP(emu, &text);
STACK_POP(emu, &title);
STACK_POP(emu, &button);
// read actual strings from process memory
mem_read( mem, text, &pszText, 256 );
mem_read( mem, title, &pszTitle, 256 );
printf( "* MessageBoxA( %p, %s, %s, %d )\n", hwnd, pszText, pszTitle, button );
// call the real API
int ret = MessageBoxA( hwnd, pszText, pszTitle, button );
// store return value into EAX register
emu->regs->eax = ret;
return 0;
}
对于每个API都可以正常运行,但我在MSVCRT中挂钩 printf API时遇到问题,因为我不知道除了szFormat之外我还要从堆栈中弹出多少个参数。 如何确定我必须弹出的参数数量? printf的工作原理是如何工作的?
由于
答案 0 :(得分:3)
如果你没有首先将它们放在堆栈中,你就不会需要来弹出printf()
的参数。
无论调用约定如何,所有可变函数都被调用者清理,因此他们读取参数而不会弹出它们。