C 模拟printf堆栈弹出

C 模拟printf堆栈弹出,c,winapi,x86,printf,emulation,C,Winapi,X86,Printf,Emulation,我正在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 ST

我正在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中挂接printfAPI时遇到了问题,因为我不知道除了szFormat之外,还要从堆栈中弹出多少参数。 如何确定必须弹出的参数数量?printf是如何在低级别工作的

谢谢

如果您没有将
printf()
的参数放在堆栈上,那么就不需要弹出它们


不管调用约定如何,所有变量函数都是调用方清理的,因此它们读取参数时不会弹出参数。

好的,问题解决了一半,那么我如何知道堆栈上有多少个参数被推送,这样我就可以读取它们(不弹出,这只是一个regs->esp+=4;)并将其打印出来以进行调试?@SimoneMargaritelli您必须像printf一样,检查格式字符串中的各种%元素。为此,恐怕唯一的方法就是像printf()那样:解析格式字符串。请记住,
long-long
double
参数需要两个字,因此您不能只计算未替换的百分号:您实际上必须阅读格式以确定类型。似乎合法:D我已经在考虑该解决方案,但我希望有一个更好/更简单的解决方案:P tnx