有做過 API Hook 的人都知道,要能 hook 感興趣 API 的首要條件是你一定得知道這個 API 的 address ,也就是函式的進入點,透過改變這個函式進入點讓他導向我們自定義的 detour 函式。
但對於那些沒有 export 出來的 API ,我們無法簡單透過 GetProcAddress 取得 API 的記憶體位置,這篇文章會告訴你如何使用 WinDBG 去取得 unexport API 的 address 。
本篇以 Firefox 的 PR_Write 示範:
Step1. Attach to process
把 WinDBG attach 到 Firefox 上
Step2. load symbol
把 Firefox 的 symbol server 加進去 symbol path 裡,如果不 load symbol 的話,後面反組譯出來的 function name 會不正確也無法帶出 function 的 signature。
Step2. 找到 API 所屬的 dll
如果你只知道 API 名稱而不知道它位在哪個 dll 內,可以使用 x {dll}!{API_name}
全域搜尋 symbol,這個指令支援萬用字元,可以把不確定的部分使用 *
取代 。
透過上面那個指令,馬上就可以找到 PR_Write 是位在 nss3 的 dll 內!
Step3. Unassemble function
你可以使用 uf {dll}!{API_name}
或是 uf {function address}
透過反組譯 的指令將 target API 轉成 machine code,以取得 API 的 pattern。
Step4. Pattern matching
現在有了 PR_Write 反組譯後的 pattern ,接下來就是寫個小程式找出這個 pattern 當前所在的記憶體位址。
// Output
GetProcAddress = 00007FFACF2DB870
GetPatternAddress = 00007FFACF2DB870
這篇為了方便比較所以使用了 export 的 PR_Write ,從 output 可以看到兩者取得的記憶體位址是一樣的,是不是很簡單 😃
上面那些操作 windbg 的步驟都可以透過 pykd 自動化掉,不知道有沒有人對這塊有興趣 ,之後整理完發篇文章跟大家分享,希望不要因為我的怠惰導致拖很久才發 😅