Windows PE导出表编程3(暴力覆盖导出函数)
今天要嘗試的導出表相關編程內容是:覆蓋函數地址部分的指令代碼。
這種覆蓋技術,是將AddressOfFunctions指向的地址空間指令字節碼實施覆蓋,這種技術又繁衍出兩種:
暴力覆蓋,即將所有的代碼全部替換為新代碼。新代碼可能含有原來代碼的全部功能,也可能不包含原有代碼功能。
完美覆蓋,通過構造指令,實施新代碼與源代碼的共存和無遺漏運行。因為完美覆蓋涉及代碼的重定位,相對復雜一些,今天嘗試暴力覆蓋。目標是我自己寫了一個dll導出一個加法函數,然后我要用另一個自定義函數替換這個函數,讓他直接返回0。
1.首先定義測試用的dll,以及測試用的exe。
?
?
?
2.找到要替換的函數的FOA,這里面是指找到_Add函數,思路是先通過PE頭找到導出表,信息,根據導出表信息(RVA)計算FOA從而找到導出表在文件中的位置,然后分析導出表結構,找到導出函數列表地址(RVA),計算FOA,在計算的導出表地址處找到導出函數地址(ROA),計算FOA,這樣就算是找到了函數的代碼段了。細節如下如:
上圖是找到了導出函數列表地址24A8.
導出函數列表地址24A8轉成FOA是12A8,在這里找到了導出函數地址1010,然后繼續轉成FOA位410?,?so?410就是該導出函數實現的代碼段了。
3.接下來的事就是把自己寫好的新功能函數的機器碼拷貝到上面的代碼段就行了,獲取機器碼也有個方法,就是先自己用C++寫好,然后調試看反匯編,在內存里直接把翻譯好的機器碼整個(整個函數)拿出來就行了。
這樣得到的直接返回一個0的函數的機器碼是:55?8b?ec?33?c0?5d?c3
4.替換2找到的代碼段位置,也是替換到5d?c3,剩余的不夠的位置用90(NOP)補齊。
5.保存文件之后再繼續測試一發,發現不管給_Add()函數傳什么都會直接返回0的。
去看此時加載的D.dll的Add函數再次確認下函數代碼對應機器碼已經被修改,同時反匯編代碼的匯編解釋也是錯的。
最后提示一點就是這個姿勢需要注意一點就是堆棧平衡問題,上面的測試其實都是基于C++dll調用的,默認是調用者負責釋放參數堆棧:
? ? 而有的時候需要在函數里面去把這個函數的堆棧平衡了,這個地方要注意一下。還有就是覆蓋的時候最好是把內容少的覆蓋到內容多的函數里,不然的話可能會破壞掉其他的函數,如果你覺得我只要這個覆蓋的函數的功能就行了,別的破壞就破壞了,這樣還是不行,因為這個函數的實現有可能依賴于里面自己實現的其他函數的支持。
總結
以上是生活随笔為你收集整理的Windows PE导出表编程3(暴力覆盖导出函数)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows PE导出表编程2(重组导
- 下一篇: Windows PE导出表编程4(重构导