|
論壇說明 |
歡迎您來到『史萊姆論壇』 ^___^ 您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的! 請點擊這裡:『註冊成為我們的一份子!』 |
|
主題工具 | 顯示模式 |
2003-12-12, 01:20 PM | #1 (permalink) |
榮譽會員
|
貼個初級問題,高手莫入:使用PE文件中引入表中的函數的方法
當我們修正檔一個PE文件時,常常要用到使用這個PE文件引入表中的函數,那麼怎樣來使用呢?要想很透徹的瞭解其原理,需要對引入表很熟悉,並且要對PE文件的載入機制有所瞭解。
對於引入表的介紹和PE載入機制,看雪老大的著作上已經介紹的很清楚,只要花點時間,很容易弄清楚。按照下面步驟,即使對不太熟悉引入表的朋友,也能直接使用其中的函數。 準備的工具:LoadPe、Softice或TRW2000 步驟: 1、用LoadPe開啟PE文件,檢視其目錄中的匯入表,選要使用的DLL並紀 錄下它的FirstThunk的值(這是IAT表的起始RVA),假設為:E1B7。 2、找到要在這個DLL中要使用的函數,假設為:LoadLibraryA。 3、數一數這個函數在這個DLL函數列表中是第幾個,假設為:第3個。 4、那麼在修正檔中使用這個函數就是: call dword ptr[e1b7+ImageBase][(3-1)*4] 5、ImageBase的獲得: 當我們修正檔一個程序時,修正檔的起始RVA是已知的(可以根據VA用LoadPe 的FLC計算出來),請看下面程序: 假設修正檔開始位址(VA)為:0040d000,通過計算知道對應的RVA為n 0040d000ushad 0040d001:call 0040d006 0040d006op ebp xxxxxxxx:sub ebp-n-6 ;此時,ebp就是ImageBase,減6是 ;pushad 和 call 0040d006的指令長度 xxxxxxxx:call dword ptr[ebp+e1b7][(3-1)*4] ;使用 ;LoadLibraryA . . . xxxxxxxxopad 僅此拋磚引玉,歡迎高手賜教其他方法。 貼一篇稍微複雜點的:對於DLL通過增加重定位項直接使用引入表函數 對於DLL文件,還有一種比較簡單的方法,通過在沖定位表中增加IAT的重定位項實現。 先看下面修正檔程序: . 0167:01077228 PUSH EBX ;函數名字 0167:01077229 PUSH EDX ;Kernel32的hModule 0167:0107722A NOP 0167:0107722B NOP 0167:0107722C NOP 0167:0107722D NOP 0167:0107722E NOP 0167:0107722F NOP 0167:01077230 CALL [KERNEL32!GetProcAddress] 0167:01077236 TEST EAX,EAX 0167:01077238 JZ 010772AC . . 在SoftIce中寫修正檔時候就像上面一樣寫,完成後,0167:01077230處的指令程式碼將為:FF 15 xx xx xx xx,我們需要做的就是將xx xx xx xx處寫入沖定位表。在本例子中,基位址為1040000,所以1077230處的RAV為37230,由於重定位表都是1000對齊的,所以要在重定位表中RVA為37000的索引中增加。 1、找到重定位表中索引為37000的地方,如果沒有這個索引,就給 它加上,並將它的長度字段(第2個雙字)加2 2、計算重定位項目值:37230 - 37000 + 2 = 232,加2是跳過指令 字FF 15,指令字之後才是要重定位的位址。 3、加上內容:232 or 3000 = 3232,項目值是字服務機構,高4位是屬 性。 4、將項目值3232按照記憶體存放規律--低位址放低字元,高位址放高 字元加到這個索引(37000)中,在這個例子中,高低一樣了。 5、將重定表最後為0的字元刪掉2個。同理,你要增加2個項目,就 要刪掉4個0;增加了索引,最好刪掉同樣長度的0字元。否則如 果.reloc節不是最後一個節的話,這個節後面的資料或程序就出 錯了。若是最後一個節,可以不刪,但要注意對齊PE文件。 6、將匯入表長度加2;若增加了n個項目,就要加n*2;若增加了索 引,要加上同樣的長度。 現在一切ok了,程序執行時,你使用的引入表函數被PE裝載器給重定位了。可以用LoadPe檢視改造後的.reloc表,將會多了一項: Index RVA 偏移 Type Far Address Data Interpretion 5 37232 37232 HIGHLOW(3) 1002C1A8 IAT thunk of "Kernel32" 需要注意的事項:增加索引或項目時,要注意PE文件對齊,並要注意當.reloc不是最後一個節的特殊情況(往往是加了殼或打了修正檔的才會這樣)。 EXE文件往往沒有重定位表,能不能這樣做呢?沒有試過。 再貼一篇稍微複雜點的:對於DLL通過增加重定位項直接使用引入表函數 對於DLL文件,還有一種比較簡單的方法,通過在沖定位表中增加IAT的重定位項實現。 先看下面修正檔程序: . 0167:01077228 PUSH EBX ;函數名字 0167:01077229 PUSH EDX ;Kernel32的hModule 0167:0107722A NOP 0167:0107722B NOP 0167:0107722C NOP 0167:0107722D NOP 0167:0107722E NOP 0167:0107722F NOP 0167:01077230 CALL [KERNEL32!GetProcAddress] 0167:01077236 TEST EAX,EAX 0167:01077238 JZ 010772AC . . 在SoftIce中寫修正檔時候就像上面一樣寫,完成後,0167:01077230處的指令程式碼將為:FF 15 xx xx xx xx,我們需要做的就是將xx xx xx xx處寫入沖定位表。在本例子中,基位址為1040000,所以1077230處的RAV為37230,由於重定位表都是1000對齊的,所以要在重定位表中RVA為37000的索引中增加。 1、找到重定位表中索引為37000的地方,如果沒有這個索引,就給 它加上,並將它的長度字段(第2個雙字)加2 2、計算重定位項目值:37230 - 37000 + 2 = 232,加2是跳過指令 字FF 15,指令字之後才是要重定位的位址。 3、加上內容:232 or 3000 = 3232,項目值是字服務機構,高4位是屬 性。 4、將項目值3232按照記憶體存放規律--低位址放低字元,高位址放高 字元加到這個索引(37000)中,在這個例子中,高低一樣了。 5、將重定表最後為0的字元刪掉2個。同理,你要增加2個項目,就 要刪掉4個0;增加了索引,最好刪掉同樣長度的0字元。否則如 果.reloc節不是最後一個節的話,這個節後面的資料或程序就出 錯了。若是最後一個節,可以不刪,但要注意對齊PE文件。 6、將匯入表長度加2;若增加了n個項目,就要加n*2;若增加了索 引,要加上同樣的長度。 現在一切ok了,程序執行時,你使用的引入表函數被PE裝載器給重定位了。可以用LoadPe檢視改造後的.reloc表,將會多了一項: Index RVA 偏移 Type Far Address Data Interpretion 5 37232 37232 HIGHLOW(3) 1002C1A8 IAT thunk of "Kernel32" 需要注意的事項:增加索引或項目時,要注意PE文件對齊,並要注意當.reloc不是最後一個節的特殊情況(往往是加了殼或打了修正檔的才會這樣)。 EXE文件往往沒有重定位表,能不能這樣做呢?沒有試過。 Spring.W |
送花文章: 3,
|