做數據逆向分析最先應該區分數據是常量、變量,還是指針。可是作爲二進制數據本身不會標記自己是什麼,然而編譯器將不同的的類別儲存在不同的區域。
變量數據應分爲這兩類:
1. 局部非靜態變量:對於1KB以下的該種變量,一般都要放在棧區,那麼它的尋址必然用到ebp寄存器來間接變址進行尋址。另外,有些編譯器(比如gcc)出於優化考慮,也會用到esp寄存器。
舉例:
void fun()
{
int i=0;
char a[5]="AAAA";
}
//vc2005Debug版反彙編
void fun()
{
-------------------------------------------------保護寄存器數據
00411390 push ebp
00411391 mov ebp,esp
00411393 sub esp,0E0h
00411399 push ebx
0041139A push esi
0041139B push edi
---------------------爲局部變量在棧區預留內存,以及vc編譯器的添加防溢出措施
0041139C lea edi,[ebp-0E0h]
004113A2 mov ecx,38h
004113A7 mov eax,0CCCCCCCCh
004113AC rep stos dword ptr es:[edi]
004113AE mov eax,dword ptr [___security_cookie (417000h)] //研究溢出漏洞的人,
//可以看一下藍色代碼,
//通過在回調地址前,
//添加安全碼
//使shellcode不可以覆蓋
//這裏,否則異常
004113B3 xor eax,ebp
004113B5 mov dword ptr [ebp-4],eax
//這是vs2005的新特性,
//你想能出破解方案嗎?
-------------------------------------------------
int i=0
004113B8 mov dword ptr [ebp-0Ch],0
char a[5]="AAAA";
004113BF mov eax,dword ptr [string "AAAA" (41563Ch)]
004113C4 mov dword ptr [ebp-1Ch],eax
004113C7 mov cl,byte ptr ds:[415640h]
004113CD mov byte ptr [ebp-18h],cl
}
004113D0 push edx
004113D1 mov ecx,ebp
004113D3 push eax
004113D4 lea edx,[ (4113F4h)]
004113DA call @ILT+140(@_RTC_CheckStackVars@8) (411091h)
004113DF pop eax
004113E0 pop edx
004113E1 pop edi
004113E2 pop esi
004113E3 pop ebx
004113E4 mov ecx,dword ptr [ebp-4]
004113E7 xor ecx,ebp
004113E9 call @ILT+25(@__security_check_cookie@4) (41101Eh)
004113EE mov esp,ebp
004113F0 pop ebp
004113F1 ret
2. 全局變量、局部靜態變量:它們統一儲存在數據節,因爲它們的實現方式是一樣的,都是直接尋址方式來尋址,只是全局變量,在所有區域均可訪問,而局部靜態變量只能在函數內部訪問。
char a[5]="AAAA";
void fun()
{
static int i;
i=0;
a[0]='b';
}
void fun()
{
00411390 push ebp
00411391 mov ebp,esp
00411393 sub esp,0C0h
00411399 push ebx
0041139A push esi
0041139B push edi
0041139C lea edi,[ebp-0C0h]
004113A2 mov ecx,30h
004113A7 mov eax,0CCCCCCCCh
004113AC rep stos dword ptr es:[edi] //由於沒有使用堆棧,編譯器沒有添加防溢出措施
static int i;
i=0;
004113AE mov dword ptr [41719Ch],0
a[0]='b';
004113B8 mov byte ptr [417034h],62h
}
004113BF pop edi
004113C0 pop esi
004113C1 pop ebx
004113C2 mov esp,ebp
004113C4 pop ebp
004113C5 ret
常量
常量和全局變量、靜態變量實現方法使一樣的,使用直接尋址,但區別是:只能讀、不可寫。
比如:1. mov eax, [417034h]
2. cmp eax, [417034h]
指針
指針可以當做是存儲地址的變量,它即可以是全局變量,也可以是局部非靜態變量,但與普通變量的區別是:"初始化時使用offset或lea,使用指向內容時二次尋址"。
舉例:初始化:
1.mov [417034h],offset “AAAA”//全局指針
2.lea eax,ARRAY
mov [esp-4ch],eax//局部指針
使用:
1.mov eax, [417034h]
mov edx, [eax]
2.mov eax, [esp-4ch]
mov edx, [eax+i]//指針可能指向的是數組
//vc2005Debug版反彙編