1
我在Win32上编写了一个模拟可执行程序的X86应用程序级模拟器,并将它的API调用挂接,并将它们转发给我的回调函数。 在这些回调我打印一些调试东西,然后调用实际的API,每个回调是一样的东西:模拟printf堆栈弹出
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的东西如何工作低水平?
感谢
好的,一半的问题解决了,那么我怎么知道有多少参数被压入堆栈,所以我可以读取它们(没有弹出,这只是一个regs-> esp + = 4;)并将它们打印出来用于调试目的? –
@SimoneMargaritelli你必须以同样的方式做printf - 通过检查其各种%元素的格式字符串。 – mah
为此,恐怕唯一的办法就是像printf()那样做:解析格式字符串。请记住,“long long”和“double”参数需要两个单词,因此您不能只计算未转义的百分号:您实际上必须读取格式才能确定类型。 – Medinoc