Simone Margaritelli
Simone Margaritelli

Reputation: 4733

Emulating printf stack popping

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

Answers (1)

Medinoc
Medinoc

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

Related Questions