數據來源

  • 如果不知道彙編指令操縱的數據是什麼意義, 那麼你必定分析不出彙編指令在完成何種功能.
  • 想要知道被彙編指令操縱的數據是什麼意義, 那麼你必須找到這個數據的值的來源(任何一個數據,它的初始值的來源有兩種: 一. 隨機值, 二. 人為賦值).
  • 一個數據的來源一般有以下幾種:
  • 來自直接給出的常量(比如: mov [0x403000], 0x12345678)
  • 來自函數返回值:




call GetDlgItemTextInt
mov [0x12345678] , eax
  • 來自函數內部的賦值:
1 lea eax, [ebp-20h]
2 push eax
3 call sacnf
4 add esp , 4

數據來源未必就只有以上三種

總結: 要分析彙編指令, 必先分析其操縱的數據


代碼結構

需分析代碼結構的場景: 如果數據的來源是一個敏感函數的返回值,或輸出值. 或者數據的來源是一串常量字符串, 那麼數據的意義就很明顯. 但是大多數情況下, 即使你已經找到了數據的來源, 你仍然猜測不出數據的意義何在.

我們在使用高級語言編寫代碼時, 一般都會在函數中使用局部變量. 局部變量的使用場景無外乎以下幾種:

  • 保存函數的返回值
  • 保存函數的輸出內容
  • 用於計數的變量
  • 數據交換時用到的臨時變量
  • 僅僅用於保存另一個變量的值的臨時變量

只要能夠識別出局部變量的使用場景,那麼分析時就能夠知道局部變量所保存的值的意義.

大多數臨時變量都可以直接識別出來, 但仍然有一些變量不能輕易識別出. 好消息是這些不能輕易識別出來的變量一般都會在特定的代碼結構中出現.

一個循環的代碼結構:

1 mov [ebp-14h] , 0
 2 _loop:
 3     cmp [ebp-14h], 100h
 4     jge _exit
 5     mov eax, [ebp-14]
 6     inc eax
 7     mov eax, [ebp-14]
 8     jmp _loop
 9 _exit:
10     ret

 

在這種結構的代碼下, [ebo-14]它的初始值是0 , 在隨後的代碼中, 它的值不斷產生變化, 變動的值來自於它本身.

如果不瞭解循環結構 , 那麼你可能就意識不到, [ebo-14]是一個循環結構中的計數器.

除了循環結構, 還有一些其它的代碼結構:

  • if...else if...else 結構
  • switchcase結構

總結: 識別出代碼的結構有助於提升數據來源的分析效率.


數據交叉引用

程序結構有助於分析出局部變量的數據來源, 但對於一些全局變量, 就失靈了. 在碰到全局變量時, 你可能在整個函數中都找不到其初始來源, 這是因為全局變量一般情況下在任何函數都可以被賦值, 如果想要分析其數據來源, 就需要挨個挨個函數地去找被賦值的地方.

IDA中提供了數據交叉引用 , 能夠快速查看整個程序代碼中, 使用了全局變量的代碼. 使用這個功能, 我們就能夠快速找到全局變量被賦值的地方.

OD中提供了查找參考IDA的數據交叉引用類似, 也能夠快速查找到所有使用全局變量的代碼.

如果全局變量的值來自於一個局部變量, 那麼, 我們就可以用局部變量的分析方法分析出局部變量的數據來源.

總結:

  • 全局變量可以使用IDA的數據交叉引用,OD中的查找參考功能快速找到全局變量被賦值的地方
  • 全局變量的數據分析可以轉換成局部變量的數據分析.