逆向分析技術

1.啓動函數

功能:檢索新進程命令指針,環境指針,全局變量初始化,內存堆棧初始化

比如:
GetCommandLineA 命令指針
GetStartupInfoA 啓動信息
GetModuleHandleA 執行文件基地址

編譯器自動加入的代碼:

00401020 >/$  55            push    ebp
00401021  |.  8BEC          mov     ebp, esp
00401023  |.  6A FF         push    -1
00401025  |.  68 A0504000   push    004050A0
0040102A  |.  68 7C1C4000   push    00401C7C                         ;  SE 處理程序安裝
0040102F  |.  64:A1 0000000>mov     eax, dword ptr fs:[0]
00401035  |.  50            push    eax
00401036  |.  64:8925 00000>mov     dword ptr fs:[0], esp
0040103D  |.  83EC 10       sub     esp, 10
00401040  |.  53            push    ebx
00401041  |.  56            push    esi

2.函數及其參數

反編譯分析時,將注意力集中在函數的識別以及參數的傳遞上
函數多以call(保存函數返回信息)地址爲跳轉 也有動態計算或者寄存器傳地址

函數的參數傳遞方式有三種:

堆棧方式

寄存器方式

全局變量

3.函數的返回值

1. return操作符返回值

逆向分析技術
od遇到了一個bug 就是不是每個指令都會下到int3斷點 從而debug時F8單步有一些代碼是一起執行的。(這讓想起了原子操作)

一般的返回值時存放在eax寄存器中,如果超過了容量則會放到edx寄存器中。

2.通過參數按照傳引用的方式返回

注意ds和ss的區別 然後一般通過引用來傳值需要使用變量的地址,在調用某個函數時再把變量的地址傳給函數。
逆向分析技術

3.通過全局變量返回

4.數據結構

逆向算法和數據結構

1.局部變量

1.堆棧分配局部變量
在堆棧中進行分配,分配完在釋放。或者直接存放在寄存器中。
分配[ebp-xxx]
訪問[ebp+xxx]

初始化局部變量的兩種方法:
mov [ebp-xxx],5

push 5

2.利用寄存器存放局部變量

堆棧佔用兩個寄存器,編譯器會利用剩下的6個通用寄存器儘可能的有效存放局部變量。寄存器不夠時纔會使用堆棧,且局部變量的生命週期比較短,需要確定時那個寄存器存放的那個變量。

2.全局變量

全局變量存放在內存區,靜態pe的.data的可讀寫區域的固定地址上。訪問時即訪問硬編碼的特定地址即可。
(靜態變量 static 作用範圍有限)
如果是常量 則在只可讀區域內。

3.數組

數組保存在.data段中 使用基地址+偏移來尋址

4.虛函數

虛函數實在運行時刻定義的函數,地址無法在編譯時確定(在即將調用時確定)
對所有虛函數的引用常放在一個專用的數組虛函數表VTBL裏,

逆向分析技術
這裏使用4050A0存放着虛表(虛表裏有兩個方法的地址 利用兩次間接尋址找到虛函數的正確地址)
逆向分析技術

每太搞懂右邊的流程,爲什麼有個失敗的流程 xor esi,esi

還有爲什麼每次任然需要新建一個this指針( mov ecx,esi )ecx來傳遞參數給成員函數

(更好奇的是如何復原ida裏面的函數流程)

5.控制語句

1.if-then-else的循環控制語句

整數比較實用cmp 浮點數使用fcom fcomp

逆向分析技術
不太懂這個初始化的時候的值。書上說是指向局部變量空間

這裏使用test替換cmp指令 如果爲0則zf=1 不跳轉繼續執行
逆向分析技術

2.Switch-case語句

未優化前的代碼都含有printf函數
逆向分析技術

編譯優化後使用dec eax 來代替cmp指令 指令更短執行更快速

使用調轉表

cmp 和ja 無符號大於則跳轉 jmp table
逆向分析技術

3.轉移指令的機器碼的計算

短轉:無條件和條件轉移的機器碼都是兩個字節

長轉:無條件轉移是5個字節 條件轉移是6個字節

子程序調用:call

6.循環語句

受用Maximize Speed優化後的代碼使用寄存器來傳值
逆向分析技術

7.數學運算符

1.一般使用add和sub指令,優化後比較喜歡使用lea指令來代替add和sub指令

逆向分析技術

這兩個變量是什麼時候初始化的

004007030 是%d

004701020 是printf函數

2.整數的乘法

mul和imul指令。
如果一個數是2的冪,會使用指令shl來實現乘法。

逆向分析技術

3.除法

div或者idiv指令
逆向分析技術

符號拓展指令cdq,作用是把eax寄存器中的數視爲有符號的數字。

編譯優化後爲:
逆向分析技術

用於將除法轉化爲乘法

8.文本字符串

1.字符串存儲格式
C \0 也成爲ASCII字符串 廣泛用於windows和unix中

DOS $

Pascal Y

Delphi Y

2.字符尋址指令

80x86支持直接和間接尋址等模式

mov eax,[40010h]
mov eax,[ecx]

load effective address

lea eax,[40040h]== mov eax,40040h

lea eax,[eax+8]== add eax,8

3.字符大小寫轉換

大寫41~5A 小寫 61~7A 大小寫轉換爲減去20h

或者將第五位置0

4.計算字符串的長度

strlen()的實現

repne scasb指令獲取字符串長度 strlen.c文件中的內聯彙編代碼如下:

#include <string.h>

size_t
strlen (const char *str)
{
  int cnt;

  asm("cld\n"           /* Search forward.  */
      /* Some old versions of gas need `repne' instead of `repnz'.  */
      "repnz\n"         /* Look for a zero byte.  */
      "scasb" /* %0, %1, %3 */ :
      "=c" (cnt) : "D" (str), "0" (-1), "a" (0));

  return -2 - cnt;
}

並沒有使用scasb指令,而是直接比對字節內容。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章