banner
lca

lca

真正的不自由,是在自己的心中设下牢笼。

《從零開始學IDA逆向》學習筆記-15(轉存並重建導入函數表(IAT))

使用腳本轉存為可執行文件#

此章介紹脫殼後的兩個步驟,轉存可執行文件和重建導入函數表。

image.png

OEP

上一章中,已經調試出來了 OEP,轉到 OEP 處並操作 ida 重新分析程序,準備執行轉存操作,使用如下 idc 腳本來轉存

static Byte(ea) {
	return (ea) & 0xff;
}

static main()
{
    auto fp, ea;
    fp = fopen("dump.bin", "wb");  // 打開要寫入的文件
    for (ea=0x400000; ea < 0x40b200; ea++)  // 循環指定地址範圍
    {
        fputc(Byte(ea), fp);  // 將指定地址中的數據寫入文件中
    }
    fclose(fp);  // 關閉文件
}

注:在實戰的過程中,ida7.7 中使用如上代碼轉存的內容會有問題,轉存的內容不是正常的內容

所以這裡就換成了 python3 的腳本來轉存,腳本如下:

import idaapi
import idc
import struct

start_ea = 0x400000
end_ea = 0x40b200
step = 4  # 每個地址處的數據佔用4個字節

file_path = "dump.bin"
with open(file_path, "wb") as f:
    for ea in range(start_ea, end_ea, step):
        # 讀取指定地址處的4個字節數據並進行小端字節序轉換
        bin_data = struct.pack("<L", idaapi.get_32bit(ea))
        f.write(bin_data)

文件基址是 0x400000,從 ida segments 選項卡中查找轉存的最高地址,從下圖中可以看到 Overlay 區塊的結尾 0x40b200。

image.png

之後打開菜單欄 - 文件 - 腳本文件運行,這個功能 idc 腳本和 python 腳本都可以。idc 腳本執行後,會在 idc 當前目錄下生成一個 bin 文件。

image.png

bin 文件的文件頭如下圖就算是正常的。

image.png

將 dump.bin 文件備份,然後重命名為.exe 的可執行文件。

image.png

這個文件的圖標沒有顯示出來,所以還有問題需要解決。

然後通過 pe editor 打開

image.png

pe editor 1.7

點擊 sections,打開區段視圖。

image.png

區段視圖

在每一個區段上右鍵單擊並選擇 dumpfixer。

image.png

這個時候圖標正常顯示了,但程序還是無法運行,因為還未修復 IAT。

image.png

什麼是 IAT#

IAT(Import Address Table)是 Windows PE 格式中的一種重要的數據結構,用於在程序運行時動態地加載和鏈接外部 DLL 庫(動態鏈接庫)的符號。IAT 保存了外部 DLL 庫中所有要調用的函數的名稱和地址,可被程序動態鏈接器在運行時使用。

IAT 保存程序執行的所有導入函數的地址

image.png

加殼文件解密後的 IAT

image.png

原始文件的 IAT

上面兩張圖都標記了 0x403238 地址,內容看上去差不多。

image.png

打開原始文件的 IDA 左下角顯示了這個內存地址對應的文件偏移是 0x1038,如上圖所示,此時就可以打開十六進制編輯器查看它的內容。

image.png

010editor 打開原始文件 0x1038 處的字節

上圖中0x1038處的值是0x355e

如果0x355e加上基址0x400000就是0x40355e,為了查看這個地址的內容,需要用 ida 重新手動加載文件中的所有區段(加載原始文件)。

image.png

0x40355e 處的內容

選擇加載所有的區段,轉到 0x40355e 處,右側也可以看到 api 的函數名為GetModuleHandleA

通過這些偏移的數值加上基址的值,就能找到對應的函數名字符串,根據這個字符串可以獲取這些函數在系統上的本機地址,本例中獲取了GetModuleHandleA的地址,然後將5E 35 00 00字節替換為本機地址。

系統根據初始值 0x355e 加上基址後獲取對應的函數名字符串,再將函數的本機地址存放到 0x403238。

再打開一個 ida 窗口加載轉存出來的文件dump - bak.exe,轉向0x403238

image.png

上圖中,文件的偏移地址是 0x3238 和原始文件不匹配,主要原因是 dumpfixer 將文件佔用(rawsize)改成和內存佔用(rawsize)一樣,導致了偏移改變。

在 010editor 打開dump - bak.exe,來到 0x3238 處。

image.png

這裡是 api 函數的本機地址,不是指向 api 名稱字符串的偏移。

因為轉存的時候,程序已經獲取了調用 api 函數的本機地址並且將它們保存到 IAT,所以加殼程序中的GetModuleHandleA API本機地址就保存在這個地址上。

image.png

GetModuleHandleA API函數

上述轉存有個問題,就是當程序執行時,會從 IAT 中讀取偏移,再加上基址地址,獲取 API 函數名字符串,通過系統獲取這些 API 函數的本機地址,再保存回 IAT。而轉存時保留的是函數的實際地址,程序無法按這一流程正確地填充 IAT,最終會導致程序崩潰。

重建 IAT#

重建 IAT 的思路就是恢復這些指向 api 函数字符串的偏移值,修復 IAT 需要一個 Scylla 的工具。

image.png

運行 scylla,在 attach to an active process 中,選擇在 ida 中暫停在 OEP 的加殼程序的進程。

image.png

加殼程序運行到 OEP

image.png

填寫 OPE 的值為 00401000,點擊 IAT Autosearch。

image.png

上圖中顯示起始地址是 0x403184,大小是 0x108。

image.png

點擊 Get Imports。

image.png

上圖中,顯示有 22 處未修復。

image.png

右鍵選擇未識別的函數,選擇 scylla plugins-pecompact v2.x 進行修復。

image.png

成功修復未識別的函數

image.png

有一些可疑函數,選擇 show suspect,確認 0x403278 處的函數是否修復成功。

image.png

上圖中,可以看到成功修復,確認沒問題後,點擊 scylla 右下角的 FIX DUMP。

image.png

選擇之前轉存的.exe 文件,寫入修復後的 IAT。

image.png

修復後的程序可正常運行,說明修復成功。

使用 IDA 加載脫殼並完成 IAT 修復的文件,程序從 OEP 也就是 0x401000 開始執行,修復的和原始文件一樣。

image.png

IDA 加載 IAT 修復之後的可執行文件

image.png

修復後的 IAT

這章主要介紹了如何轉存區段內容並重建導入 IAT 函數表,並完成最後的脫殼工作,完成了這個 upx 加殼程序的脫殼,學習了整個脫殼流程。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。