環境配置#
遠程調試的大體架構如下圖
由於在 mac 上不能運行 windows 的調試器,所以可以通過遠程調試來實現通過 mac 進行調試。
首先將加殼的文件和遠程調試服務文件複製到TARGET(win10)
機器中,遠程調試服務文件位於 dbgsrv 目錄。
TARGET(win10)
最終結構如下
加殼程序是通過 upx 進行加殼,32 位程序。
遠程調試#
在遠程調試之前,將加殼程序PACKED_PRACTICA_1.EXE
在 mac(ida7.0)上進行局部分析,勾選 MANUAL LOAD 手動加載,加載文件所有區段。
在運行調試之前,IDA 加載器會轉到已加殼程序的入口。
程序入口
注意:不能重命名數據庫文件 IDB
在TARGET(win10)
中運行 win32_remote.exe 遠程調試服務器,-i 指定 ip 地址。
調試器選擇Remote Windows debugger
。
在 Process options 中,在 Hostname 中輸入TARGET(win10)
的 ip 地址和端口,在 Application 和 Input file 中寫入位於TARGET(win10)
中的加殼程序的絕對路徑,Directory 中寫入目錄路徑即可,配置完成後,點擊 ok。
打開調試器菜單選擇 Start process,調試開始之後會在程序入口處暫停(修改:需要在 0x638ec 處設置斷點才會在此處暫停)。
可執行文件進行了隨機化處理,因此每次執行的地址都會變化,所以必須在同一次運行中完成轉存和重建 IAT 的工作,中途不能關閉程序。
打開 segments 選項卡,觀察 header 文件頭之後的第一個代碼區段,該區段的起始地址是 631000,終點地址是 238000。
尋找 OEP#
第一種方式可以嘗試文本搜索功能搜索 popad 或者 popa 指令,在此程序中可以搜索到一處 popa 指令
從圖中可以看出這個地址 0x63146e 處就是 OEP。
第二種方式通過之前學習的覆蓋第一個區段的執行斷點來尋找 OEP。
雙擊段視圖中的第一個區段,跳轉到 0x631000,查看區段數據,地址是隨機化的,基址並不是 0x401000,但內存佔用都是 0x7000,upx0 區段從 0x631000 到 0x638000,差值是 0x7000 字節。
按 F2 鍵在 upx0 區段的起點設置斷點,這裡是 0x601000,斷點大小是 0x7000
刪除其它斷點,只留下這個斷點,按 F9 鍵開始調試。
程序在此處暫停,確定和之前的 OEP 位置一致,然後刪除這個斷點,去掉紅色背景。
點擊界面左下角的 Reanalyze program,重新分析程序。
OEP 之後的內容被 IDA 識別為 STUB 的一部分,所以並沒有加上sub_
而是標記為loc_
。
轉存及 IAT 重建#
找到 OEP 後,開始轉存及重建 IAT,先查看文件基址和最高地址。
在這裡文件基址是 0x630000,最高地址是 0x63B000,拿出轉存的腳本文件,修改文件中的地址,然後加載運行腳本。
腳本如下:
import idaapi
import idc
import struct
start_ea = 0x630000
end_ea = 0x63b000
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)
運行完成後,生成轉存文件(腳本文件在 mac 上運行,所以轉存文件也生成在 mac 上。)。
將 dump.bin 文件複製到 windows 上,通過 peeditor 打開,
在每個區段上右鍵單擊選擇 dumpfixer,操作完成後,然後將.bin 改成.exe 文件,效果如下:
將 dump.exe 文件通過 scylla 打開,加載加殼程序進程。
輸入 OEP 地址,此處為 0x63146e,然後點擊 IAT Autosearch 和 Get Imports,發現一處未能識別的 API 函數。
將 API 地址加上基址,0x630000+0x20d4=0x6320d4,轉到 16 進制視圖,並不像 IAT 的一部分。
轉向反匯編視圖查看該處的引用,內容如下:
按 x 鍵顯示了 2 處引用。
而0x6320d4
指向的地址只返回 RET 指令,如下:
0x6320d4
指向的是程序內的一個固定地址,而且只是個 RET 指令,並不是引用的 API 函數,所以可以刪除,在 Syclla 中,右鍵單擊 API 函數報錯處 CUT THUNK 從 IAT 中刪除。
刪除後如下:
最後點擊 Fix Dump 對 dump.exe 重建 IAT,最後生成 dump_SCY.exe 可執行程序。
如果此時運行 dump_SCY.exe,還是黑屏一閃而過。
取消隨機基址#
因為出了 IAT 之外在運行時生成的地址沒有被重定向因為它們總是在變,所以需要消除這個隨機性,打開 ida,加載 dump_SCY.exe 文件,使用 Manual Load 加載 pe 頭區段,然後轉到這一区段。
在 header 頭中找到如下內容 Dll characteristics,需要將其值改為 0。
打開菜單 Edit-patch program-change word 將這個值改為 0。
點擊 ok,然後使用 apply patches to input file 將改動保存回可執行文件。
此刻,再次運行dump_SCY.exe
可成功運行,說明脫殼後的文件執行成功。