iT邦幫忙

2022 iThome 鐵人賽

DAY 6
0
Security

我逆向你逆向我的逆向工程膩系列 第 6

Dx06 - 執行檔的誕生

  • 分享至 

  • xImage
  •  

PE文件是在 windows系統下的可執行文件,他是微軟在 UNIX 的 COFF 格式為基礎製作而成的。而PE文件是指32位元的可執行文件,也稱為 PE32。但是64位元則稱為 PE+PE32+不可稱為 PE64

執行檔的生成

在介紹 PE 格式前,我們要知道一份程式是甚麼由程式碼變成 PE 文件。我們都學過程序語言分成高階語言組合語言指令碼等等的,當一份高階語言要執行時,就會透過一系列步驟變成指令碼,再經過指令週期後就能達成我們的任務。

https://ithelp.ithome.com.tw/upload/images/20220920/20135675geXMBSVBos.png

( 會作梗圖了 \OwO/ )

這是一個會寫 hello world 的視窗。

int main()
{
    MessageBoxA(0,"hello world","This is title",0);
    return 0;
}

這個程序會生出一個寫 hello world 的視窗。
然後 IDE 會根據 calling convention (呼叫慣例) 來生成一段組合語言 :

push 0
push "This is title" //push 到 stack
push "hello world"
push 0

call MassageBoxA

xor eax,eax
ret

太好了,我們把他轉成機器碼前做幾件事來封裝他 :

  1. 把字串存起來,放到 .rdata ( 用來只能讀取的空間 )

title -> 6 byte 放到 .rdata + 0

hello world -> 12 byte 放到 .rdata + 6

https://ithelp.ithome.com.tw/upload/images/20220920/20135675Ktw5mXu9hg.png

  1. MassageBoxA 這東西處理器看不懂在哪裡,所以把它使用的資料位置放入 .idata ( Import Address Table)

有些 IDE 會把這放到 .rdata,沒有唯一標準 ( 像是 Visual Studio )

  1. 把程式碼放入 .text

然後幾點要注意的 :

  • 程式不只包含一個 PE model ,所以掛載的 process 都依 PE 格式封裝
  • 裝上的 model 會有一個 image base ( 跟 virtual address 很像 ),指向該 model 內容
  • x32 的 image base 通常是 0x400000

然後把這些轉換成機器碼,有興趣可以看白算盤跟MIPS指令集來算算看。

https://inst.eecs.berkeley.edu/~cs61c/resources/MIPS_Green_Sheet.pdf

注意 Little / Big endian :

https://ithelp.ithome.com.tw/upload/images/20220920/20135675NR0rJEzIKm.png

然後把它組譯成 COFF 格式,就是組譯器生產的封裝檔案。

執行 g++ -c main.cpp 生成 main.o ( 他就是COFF格式 )

用 PEview 看它的結構

https://ithelp.ithome.com.tw/upload/images/20220920/20135675qH0yYvNqdI.png

然後透過 linker 為這個 COFF 進行連結,就變成 EXE程式

我們來看看 linking loader 中會用到的步驟 :

  • Binding ( 決定 Process 起始位置 )。若是在 linker loader 時做 Binding 產生出 obj 的稱為 "relocatable object file"

  • linker 把必要資料依 PE格式 寫入 OptionalHeader

詳細可以閱讀文件 : https://docs.microsoft.com/zh-tw/windows/win32/debug/pe-format

  • OS 要求起始位置

  • Complier 交辦 linking 修正資訊做出 linking 修正

  • Relocation 修正

等等步驟。


太棒了,你現在有了一份 EXE 檔案了 \OwO/

當你運行這個 EXE 時,就會由靜態檔案變成 process

那運行時發生了甚麼呢?

比如說我在 cmd.exe 輸入 msgbox.exe,會發生以下步驟 :

  1. 父程序 cmd.exe 發出 system call 請求子程序

  2. kernel modeOS 生成 Thread 給子程序,並在 userland 紀錄 PEB ( Process environment block ) 跟 TEB ( Thread environment block )。

  3. user mode 。然後對 Thread 初始化,把 PE 裝到 memory 還有 PE model 修正。

  4. application loader 修正完後把 EIP 送到 Entry point ,開始程序。

這邊看起來很麻煩,不過好像其實平常用不太到,希望未來多看幾次就可以能熟能生巧。


上一篇
Dx05 - 密碼藏在記憶體 !
下一篇
Dx07 - PE格式映射解析
系列文
我逆向你逆向我的逆向工程膩31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
HoiDam
iT邦新手 5 級 ‧ 2022-12-29 16:35:18

好油喔peko

我要留言

立即登入留言