我們已經學會了 IDA Pro 的基本操作與如何使用交叉參照,今天要對函式進行更深入的分析並學習如何用圖像功能等工具幫助分析!
IDA Pro 其中一個最強大的功能就是他可以對函式進行分辨、標籤、並且將區域變數與參數進行解析

上圖是被 IDA Pro 成功辨識出來的函式範例,在 ❶ 處顯示這個函式使用的是以 ebp 為基準的 Stack Frame,這代表在整個函式執行期間,區域變數和參數都會透過 ebp Register 來進行參照。
IDA Pro 也找出了這個函式中的所有區域變數與參數,它會使用 var_ 作為區域變數名稱的前綴,使用 arg_ 作為參數名稱的前綴,並且根據這些區域變數與參數相對於 ebp 的 offset,在名稱後面加上對應的後綴。IDA Pro 只會替實際在程式碼中被使用到的區域變數與參數加上標籤,而且沒有辦法自動知道 IDA Pro 是否已經找出了原始 Source Code 中的所有變數與參數。且第 4 章我們已經學到:區域變數位於相對於 ebp 的負 offset,而函式參數則位於相對於 ebp 的正 offset。
在 ❷ 處可以看到,IDA Pro 顯示了一段 Stack View 的摘要,第一行
var_C
對應的值是
-0xCh
這是 IDA Pro 告訴我們,它已經在 ❸ 處使用 var_C 取代了 -0xC,也就是說,IDA Pro 對原本的 Instruction 做了一層抽象化,以下
mov [ebp-0Ch], 3
就可以直接理解成將 var_C 設定為 3
PMA 教材裡面寫的是舊版 IDA Pro 提供的選項,現在新版本 toolbar 的 graphs 裡面只剩兩種圖,而流程圖平常只要直接按空白鍵就可以直接切換

這種圖會顯示是哪些函式呼叫了你所選定的函式,並且整個路徑都會顯示出來,以下圖為例

選定 DllMain 就可以看到有誰呼叫它

這種圖會顯示你所選定的函式呼叫了哪些函式,而且會一直遞迴下去,所以不一定是直接呼叫的,以下圖為例

IDA Pro 除了以上方法方便分析以外,還提供了更多功能讓我們可以看得更輕鬆
在我們對函式進行分析的時候,雖然 IDA Pro 會自動對某些他辨識出的函式進行命名,但是還是會有很多函式只有編號名稱,像是
sub_401000
這樣的名稱在閱讀時很容易找不到,因此如果我們了解了他的功能以後就可以對他進行重新命名,例如我們可以按右鍵選 Rename 改成
ReverseBackdoorThread
在 IDA 裡面就會全部都改好,然後變數跟參數也都可以改
IDA Pro 可以讓我們在整個反組譯程式碼中加入註解,而且 IDA Pro 本身也會自動加入許多註解,如果要加入自己的註解,先將游標移到某一行反組譯程式碼上,然後按下鍵盤上的冒號 :,IDA Pro 就會開啟一個註解視窗,讓你輸入註解。如果你要插入一個可重複註解,可以按下分號 ;。這種可重複註解的特色是:只要反組譯視窗中的某個地方存在對「你加入註解的那個 Address」的 Cross-reference,這個註解就可以在那些參照位置中一併顯示。
像是如果有一個函式
sub_401200
被很多地方呼叫
sub_A ──────┐
│
sub_B ──────┼──→ sub_401200
│
sub_C ──────┘
而且我們已經分析出他負責 DNS hostname resolution,那在他身上加上重複性註解就可以在呼叫他的函式也看到
sub_A:
call sub_401200 ; Resolves hostname using gethostbyname
sub_B:
call sub_401200 ; Resolves hostname using gethostbyname
sub_C:
call sub_401200 ; Resolves hostname using gethostbyname
在進行反組譯時,IDA Pro 會自行判斷每一條反組譯指令中的 Operand 應該以什麼格式顯示,如果沒有足夠的上下文資訊,這些資料通常會以十六進位數值的形式顯示,有需要的時候可以自行修改,例如
十六進位:62h
十進位: 98
八進位: 142o
二進位: 1100010b
ASCII: 'b'
可以根據需求以及當下的分析情境,選擇最適合的表示方式。如果 IDA 不小心把某個數值當成地址,例如
0x410000
也可以按 O 鍵,把這個 Address Operand 改回單純的數值
410000h
惡意程式作者,以及一般的程式設計師,在原始碼中經常會使用像 GENERIC_READ 這樣的具名常數,它可以讓程式設計師使用容易記憶、容易理解的名稱來表示某個數值,但在編譯成 Binary 之後,這些具名常數實際上只會以整數的形式存在。
不幸的是,一旦編譯器完成原始碼的編譯之後,我們就無法再判斷原始碼使用的究竟是 符號常數,還是直接寫入的字面值。
幸運的是,IDA Pro 提供了一個很大的具名常數資料庫,其中包含許多 Windows API 以及 C Standard Library 的具名常數。
因此,在分析反組譯程式碼中的 Operand 時,可以使用 Use Standard Symbolic Constant 功能,如下圖

而下圖是對數值 0x80000000 選擇 Use Standard Symbolic Constant 之後所出現的視窗

下表的程式碼片段則展示了對 Windows API CreateFileA 的參數套用 Standard Symbolic Constant 之後會產生什麼效果

右邊的程式碼比左邊的程式碼更具有意義,也更容易理解。
當 IDA Pro 第一次對一個程式進行反組譯時,偶爾會把某些 Bytes 分類錯,例如:
在 Disassembly Window 中,最常見的重新定義方式,是按下 U 鍵,將 Function、Code 或 Data 設定為 Undefined,當我們將 Code 設為 Undefined 時,底層真正存在的 Bytes 就會被重新顯示成一串 Raw Bytes,如果要把這些 Raw Bytes 定義成 Code,可以按下 C 鍵,例如下圖

上圖這個文件
paycuts.pdf
在檔案 offset
0x8387
的位置,我們發現了一段 Shellcode,這段 Shellcode 一開始被定義成 Raw Bytes,如 ❶ 所示,因此我們在該位置按下 C,這樣 IDA Pro 就會把這些 Raw Bytes 當成 Code 進行反組譯。
經過反組譯之後,我們發現這段 Shellcode 中包含一個使用:
0x97
作為 XOR Key 的 XOR Decoding Loop(XOR 解碼迴圈),如 ❷ 所示。
並且根據不同的分析目的,也可以使用類似的方法,將 Raw Bytes 定義成 Data 或 ASCII String:
D → 定義成 Data
A → 定義成 ASCII String
我們昨天透過基本的操作和使用交叉參照回答了 1~4 題,今天要用學到的方法來繼續分析後面的題目!
0x10001656 的 subroutine 辨識出多少區域變數首先找到 0x10001656 的 subroutine

可以看到上面總共有 24 個項目,其中我們還記得
所以區域變數總共有上面的 23 個
0x10001656 的 subroutine 辨識出多少函數參數
在剛剛同個地方可以看到最後的一個是參數,其 offset 為正,而且 IDA Pro 還有幫忙把名稱標出來
\cmd.exe /c 的位址先選
View → Open subviews → Strings
接著搜尋
\cmd.exe /c
就會看到

地址是 0x10095B34
\cmd.exe /c 的程式碼區域發生了甚麼在剛剛看到 \cmd.exe /c 的頁面對他點兩下

從圖中可以看到他寫說 remote shell session,接著去看 cross-reference

點兩下去看對應的函式

可以看到他呼叫了一系列的 memcmp 函式

而且也有看到 recv 及 send,種種都顯示這個程式碼區域是在幫攻擊者創建一個 remote shell session
0x100101C8,看起來 dword_1008E5C4 是個幫助決定路徑的全域變數,這個惡意程式如何設定他首先在同樣區域的 0x100101C8 找到 dword_1008E5C4

接著對 dword_1008E5C4 去看 cross-reference

看到第一個函式有複製值進去

mov dword_1008E5C4, eax
可以看到 eax 被複製進 dword_1008E5C4,而且 eax 是上個函式的回傳值,所以去看上個函式的內容

這個函式有一個 GetVersionEx 會存取 OS 的資訊,而最終會存回 dword_1008E5C4,所以它的內容就是儲存 OS 的版本資訊
今天完成了 IDA Pro 對於惡意程式靜態分析的基本介紹,現在我們已經學會了如何載入、查看、分析一個惡意程式,接下來就要繼續動態分析的介紹啦!
