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