1 熟悉工作環境和相關工具
1.1 調試工具Microsoft Visual C++6.0和OllyDBG
1.2 反匯編靜態分析工具IDA
1.3 反匯編引擎的工作原理
2 基本數據類型的表現形式
2.1 整數類型
2.2 浮點數類型
2.3 字符和字符串
2.4 布爾類型
2.5 地址、指針和引用
2.6 常量
3 認識啟動函數,找到用戶入口
3.1 程序的真正入口
3.2 了解VC++6.0的啟動函數
3.3 main函數的識別
4 觀察各種表達式的求值過程
4.1 算術運算和賦值
4.2 關系運算和邏輯運算
4.3 位運算
4.4 編譯器使用的優化技巧
4.5 一次算法逆向之旅
5 流程控制語句的識別
5.1 if語句
-
if語句只能判斷兩種情況,0和非0
-
5-1 if語句構成
#include<stdio.h>
int main()
{
int a=2;
if (a==2)//注意與匯編位置對比
{
printf("%d",a);
}
return 0;
}
-
使用相反的條件跳轉指令
-
表達式短路和if語句的反匯編一樣,不容易區分
總結: ;先執行各類影響標志位的指令 ;其后各種條件跳轉指令 JCC xxxx
-
循環結構中也會出現類似代碼,分析過程還需要結合上下文
5.2 if...else...語句
- 取相反的條件跳轉指令
- if語句條件成立執行后有個jmp指令,跳過else的代碼塊
- 條件表達式與if-else的判斷比較難
- 5-3 if-else組合
#include<stdio.h>
int main()
{
int a=2;
if (a==2)
{
printf("a等於2");
}
else{
printf("a不等於2");
}
return 0;
}
- 利用兩個跳轉(jne,jmp)來區別if塊和else塊的邊界
總結:
;先執行影響標志位的指令
jcc ELSE_BEGIN ;重點
IF_BEGIN:
...
IF_END:
jmp ELSE_END ;重點
ELSE_BEGIN:
...
ELSE_END:
- 在沒有高級源碼的情況下,分析者需要先定位語句塊的邊界,然后根據跳轉目標和邏輯依賴慢慢推出高級代碼
5.3 用if構成的多分支流程
#include<stdio.h>
int main()
{
int a=2;
if (a<0)
{
printf("a小於2");
}
else if(a==2)
{
printf("a等於2");
}
else
{
printf("a為其他");
}
return 0;
}
- 每一個if語句由cmp與jcc組成,而else代碼之前沒有cmp判斷,直接跳到最后
總結:
;會影響標志位的指令
JCC ELSE_IF_BEGIN //if條件不成立,跳轉到下一條if_else首地址
IF_BEGIN:
... //if條件成立執行代碼塊
IF_END:
jmp END //執行if后跳出到結束地址
ELSE_IF_BEGIN: //else_if條件不成立,跳轉到else首地址
;會影響標志位的指令
JCC ELSE_BEGIN
... //else_if條件成立,執行代碼塊
ELSE_IF_END:
jmp END //執行else_if后跳出到結束地址
ELSE_BEGIN: //if和else_if條件都不成立,執行else代碼
...
ELSE_END //執行完就結束了,不用再跳轉了
...
END:
...
- 編譯器自動優化問題,空間與效率的問題
5.4 switch的真相
- switch是常用的多分支結構,效率上高於if else_if語句
#include<stdio.h>
int main()
{
int nIndex = 1;
scanf_s("%d", &nIndex);
switch (nIndex)
{
case 1:
printf("nIndex==1");
case 2:
printf("nIndex==2");
case 100:
printf("nIndex==100");
}
return 0;
}
int main()
{
000C18B0 push ebp
000C18B1 mov ebp,esp
000C18B3 sub esp,0D4h
000C18B9 push ebx
000C18BA push esi
000C18BB push edi
000C18BC lea edi,[ebp-14h]
000C18BF mov ecx,5
000C18C4 mov eax,0CCCCCCCCh
000C18C9 rep stos dword ptr es:[edi]
000C18CB mov eax,dword ptr [__security_cookie (0CA024h)]
000C18D0 xor eax,ebp
000C18D2 mov dword ptr [ebp-4],eax
000C18D5 mov ecx,offset _A43DB3BE_源@cpp (0CC003h)
000C18DA call @__CheckForDebuggerJustMyCode@4 (0C1316h)
int nIndex = 1;
000C18DF mov dword ptr [nIndex],1
scanf_s("%d", &nIndex);
000C18E6 lea eax,[nIndex]
000C18E9 push eax
000C18EA push offset string "%s" (0C7B30h)
000C18EF call _scanf_s (0C13C0h)
000C18F4 add esp,8
switch (nIndex)
000C18F7 mov eax,dword ptr [nIndex]
000C18FA mov dword ptr [ebp-0D4h],eax
000C1900 cmp dword ptr [ebp-0D4h],1
000C1907 je __$EncStackInitStart+61h (0C191Dh)
000C1909 cmp dword ptr [ebp-0D4h],2
000C1910 je _printf+0Ah (0C192Ah)
000C1912 cmp dword ptr [ebp-0D4h],64h
000C1919 je _printf+17h (0C1937h)
000C191B jmp _printf+24h (0C1944h)
{
case 1:
printf("nIndex==1");
000C191D push offset string "two" (0C7B34h)
000C1922 call _printf (0C10CDh)
000C1927 add esp,4
case 2:
printf("nIndex==2");
000C192A push offset string "nIndex==2" (0C7BE4h)
000C192F call _printf (0C10CDh)
000C1934 add esp,4
case 100:
printf("nIndex==100");
000C1937 push offset string "nIndex==100" (0C7BF0h)
000C193C call _printf (0C10CDh)
000C1941 add esp,4
}
return 0;
000C1944 xor eax,eax
}
- if...else_if會在條件跳轉后緊跟語句塊,switch case則將所有的條件跳轉放到一起,把case語句塊也放到了一起
5.5 難以構成跳轉表的switch
5.6 降低判定樹的高度
5.7 do/while/for的比較
5.8 編譯器對循環結構的優化
6 函數的工作原理
6.1 棧幀的形參和關閉
6.2 各種調用方式的考察
6.3 使用ebp或esp尋址
6.4 函數的參數
6.5 函數的返回值
6.6 回顧
7 變量在內存中的位置和訪問方式
7.1 全局變量和局部變量的區別
7.2 局部靜態變量的工作方式
7.3 堆變量
8 數組和指針的尋址
8.1 數組在函數內
8.2 數組作為參數
8.3 數組作為返回值
8.4 下標尋址和指針尋址
8.5 多維數組
8.6 存放指針類型數據的數組
8.7 指向數組的指針變量
8.8 函數指針
9 結構體和類
9.1 對象的內存布局
9.2 this指針
9.3 靜態數據成員
9.4 對象作為函數參數
9.5 對象作為返回值
10 關於構造函數和析構函數
10.1 構造函數的出現時機
10.2 每個對象都有默認的構造函數嗎
10.3 析構函數的出現時機
11 關於虛函數
11.1 虛函數的機制
11.2 虛函數的識別
12 從內存角度看繼承和多重繼承
- 父類指針指向子類對象
12.1 識別類和類之間的關系
-
子類具備父類所有成員數據,成員函數
-
父類聲明為私有的成員,子類對象無法直接訪問,但在子類對象的內存結構中,父類私有的成員數據依然存在
-
C++訪問權限僅限於編譯層面,不會影響對象的內存結構
-
12-1 定義派生類和繼承類
12.2 多重繼承
12.3 抽象類
12.4 菱形繼承
13 異常處理
13.1 異常處理的相關知識
13.2 異常類型為基本數據類型的處理流程
13.3 異常類型為對象的處理流程
13.4 識別異常處理
14 PEiD的工作原理分析
14.1 開發環境的識別
14.2 開發環境的偽造
15 “熊貓燒香”病毒逆向分析
15.1 調試環境配置
15.2 病毒程序初步分析
15.3 “熊貓燒香”啟動過程分析
15.4 “熊貓燒香”的自我保護分析
15.5 “熊貓燒香”的感染過程分析
16 調試器OllyDBG的工作原理分析
16.1 INT3斷點
16.2內存斷點
16.3 硬件斷點
16.4 異常處理機制
16.5 加載調試程序
17 反匯編代碼的重建與編譯
17.1 重建反匯編代碼
17.2 編譯重建后的反匯編代碼