Reputation: 4733
I'm writing a X86 application level emulator on Win32 which emulates an executable program and hooks its API calls forwarding them to my callbacks. In those callbacks I print some debug stuff and then call the actual API, each callback is something like:
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;
}
This is working flawlessly for every API, but I have problems hooking the printf API inside MSVCRT because I don't know how many arguments I have to pop from the stack besides the szFormat. How can I determine the number of arguments I have to pop? How does the printf stuff works low level ?
Thanks
Upvotes: 1
Views: 357
Reputation: 6608
You don't need to pop printf()
's arguments if you didn't put them on the stack in the first place.
Regardless of calling convention, all variadic functions are caller-cleaned, so they read their arguments without popping them.
Upvotes: 3