全局變量
測試代碼
全局變量既可以是某對象函數創建,也可以是在本程序任何地方創建。全局變量是可以被本程序所有對象或函數引用。下面這段代碼中將int、float、char變量定義在main函數之外。
// 變量.cpp : 定義控制台應用程序的入口點。
//
#include "stdafx.h"
//全局變量
// 整型
int a_nNum = 22;
// 浮點型
float fNum = 2.5;
// 字符型
char ch = 'A';
int main()
{
// 整型
int nNum = 1;
printf("int %d ,int %d, float %f ,char %c", a_nNum, nNum, fNum, ch);
return 0;
}
VS反匯編結果
IDA反匯編結果
局部變量標識區只有ver_8一個變量,而全局變量則集中保存在.data區域。IDA幫我們識別出變量的類型,byte、dword,雙擊變量可以看到數據的定義。
雙擊全局變量可以進入全局變量存放區,根據右鍵顯示的數據可以修改名稱。
數組
測試代碼
#include "stdafx.h"
int main()
{
int nArr[5] = { 1,2,3,4,5 };
int n = 2;
nArr[n] = 20;
return 0;
}
VS反匯編結果
當在函數內定義數組時候,如果沒有其他聲明,該數組即為局部變量,擁有局部變量的所有特性,數組中的數據在內存中的存儲是線性連續的,其數據排列順序由低地址到高地址。數組名稱表示該數組的首地址。
這是數組在內存中的數據分布的樣子
IDA反匯編結果
數組中的各項元素均為同一類型的數據,而局部變量賦值時的類型都不相同。根據此特征即可判斷局部變量不是數組中的元素。在尋址的過程中,數組不同於局部變量,不會因為被賦予了常量值而使用常量傳播。
在IDA中反匯編代碼中,可以看出連續使用了5個4字節的內存地址,依次賦值整型數據1、2、3、4、5。雙擊標號“var_18”定位到標號定義處,在IDA下單擊此標號,按鍵盤上的“*”或者右鍵【Array】將連續的變量定義為數組。
新建一個數組定義,大小設置為5
回到反匯編視圖,選取"var_18“並使用快捷鍵"N”鍵將標號重新命名為“nAarray”,程序中所有用到該數組標號的地方將全部被修改。
IDA中F5后可看到的源代碼,這款靜態分析工具果真是牛逼。
結構體
測試代碼
#include "stdafx.h"
//定義結構體
struct MyStruct
{
int nNum;
float fNum;
char chA;
};
void Print(MyStruct stc)
{
printf("int %d , y %f , z %c",stc.nNum,stc.fNum,stc.chA);
}
int main()
{
//結構體初始化
MyStruct stc = { 1,2.2,'A' };
stc.fNum = 5.5;
Print(stc);
return 0;
}
VS反匯編結果
IDA反匯編結果
在反匯編結果中,初始化賦值整型變量、浮點型變量、字符型變量,而函數體內浮點型變量是賦值了第二次的。熟記結構體中所有變量都共享一片內存的特性,在反匯編中識別出結構體則在於三個變量一起傳入了堆棧。逆向過程中更主要是靠猜,不對的話我們再改回來。而且改之前一定要有想法,知道自己要做什么。
為了使反匯編更利於逆向中的閱讀,我們首先在結構體窗口點擊【insert】鍵插入一個結構體
選擇結構體的ends部分,點擊快捷鍵【d】,增加結構體變量
00000001 struc_1 ends
增加三個變量,使用快捷鍵【n】將三個變量改名。這里要注意基礎數據類型都為DD,否則有可能導致數據類型不匹配出現兩個結構體問題。
00000000 struc_5 struc ; (sizeof=0x4, mappedto_25)
00000000 nNum dd?
00000001 fNum dd?
00000003 chA dd?
00000004 struc_5 ends
回到反匯編窗口,雙擊變量。到 stack of sub_xxx(局部堆棧) 窗口下將變量轉換成結構體類型
可以使用快捷鍵【alt+Q】,轉換成指定結構體。
使用結構體解析變量后,可以看到反匯編窗口中變量以結構體形式顯示。F5大法后還原高度仿真的偽C代碼