IDA逆向:数组的逆向

阅读《IDA Pro权威指南》第八章,整理的一些笔记,作为逆向的基础,可能有很多认识不足。

//全局分配数组

**********************************************************************

源程序:

int global_arrary[3];
int main()
{
int idx = 2;
global_arrary[0] = 10;
global_arrary[1] = 20;
global_arrary[2] = 30;
global_arrary[idx] = 40;

return 0;
}

逆向分析:

.text:0041136E                 mov     [ebp+var_8], 2         ; var_8为idx
.text:00411375                 mov     dword_417138, 0Ah      ;global_arrary[0] = 10
.text:0041137F                 mov     dword_41713C, 14h      ;global_arrary[1] = 20
.text:00411389                 mov     dword_417140, 1Eh      ;global_arrary[2] = 30
.text:00411393                 mov     eax, [ebp+var_8]       ;eax=idx
.text:00411396                 mov     dword_417138[eax*4], 28h   ;global_arrary[idx] = 10 由此可见当索引为变量时,易分析出元素大小 这里为4

.text:004113A1                 xor     eax, eax
.text:004113A3                 pop     edi
.text:004113A4                 pop     esi
.text:004113A5                 pop     ebx
.text:004113A6                 mov     esp, ebp
.text:004113A8                 pop     ebp
.text:004113A9                 retn
.text:004113A9 sub_411350      endp

//栈分配数组

**********************************************************************

源程序:

int _tmain(int argc, _TCHAR* argv[])
{
    int a[5];
    //int aa,bb,cc,dd,ee;
    int idx = 0;
    //int* p =a;
    a[0] = 10;
    a[1] = 20;
    a[2] = 30;
    a[3] = 40;
    a[4] = 50;

    a[idx]=100;

    print(a);


    return 0;
}

逆向分析:

var_EC= byte ptr -0ECh
idx= dword ptr -28h
a= dword ptr -1Ch
var_4= dword ptr -4
argc= dword ptr  8
argv= dword ptr  0Ch
mov     [ebp+var_4], eax
mov     [ebp+idx], 0     ;idx = 0
mov     [ebp+a], 0Ah     ;a[0] =10
mov     [ebp+a+4], 14h
mov     [ebp+a+8], 1Eh
mov     [ebp+a+0Ch], 28h
mov     [ebp+a+10h], 32h
mov     eax, [ebp+idx]      ;eax = idx
mov     [ebp+eax*4+a], 64h  ;a[idx] = 100

可以从idx的在栈中的位置 大致判断出数组的大小,可以操纵数组溢出之类的
数组大小 = a+10h - idx = -1ch + 10h - -28h = 28(十进制) = (5*4 + 8(vs2010保护))



//char数组

*************************************************************************

int _tmain(int argc, _TCHAR* argv[])
{
char* p = {"asdfgeg"};
char* q = "qwqre";
char b[3]= {"qw"};
printf("%s
",p);
printf("%s
",q);
printf("%s
",b);

return 0;
}
mov     [ebp+p], offset aAsdfgeg ; "asdfgeg"    ;将字符串常量地址赋值给 [ebp+p]
mov     [ebp+q], offset aQwqre ; "qwqre"
mov     ax, word ptr ds:aQw ; "qw"           ds是段寄存器,是用来存储段地址的,程序是通过段地址:偏移地址寻找数据地址的。
mov     word ptr [ebp+b], ax    //b[0]
mov     cl, ds:byte_415742
mov     [ebp+b+2], cl  //b[2]

vs2010反汇编:

    char* p = {"asdfgeg"};
00E5139E  mov         dword ptr [p],offset string "asdfgeg" (0E55750h)  
    char* q = "qwqre";
00E513A5  mov         dword ptr [q],offset string "qwqre" (0E55748h)  
    char b[3]= {"qw"};
00E513AC  mov         ax,word ptr [string "qw" (0E55744h)]  
00E513B2  mov         word ptr [b],ax  
00E513B6  mov         cl,byte ptr ds:[0E55746h]  
00E513BC  mov         byte ptr [ebp-1Eh],cl  


//堆分配数组
*****************************************************************************************

int main()
{
    int* heapArray = (int*)malloc(3 * sizeof(int));
    int idx = 2;
    heapArray[0] = 10;
    heapArray[1] = 20;
    heapArray[2] = 30;
    heapArray[idx] =40;


    return 0;
}
mov esi, esp
push 0Ch ; Size //malloc的参数 即数组大小
call ds:__imp__malloc
add esp, 4
cmp esi, esp
call j___RTC_CheckEsp
mov [ebp+heapArray], eax
mov [ebp+idx], 2
mov eax, [ebp+heapArray] //数组起始位置储存在heaparray中 每次要先获得基址再加偏移
mov dword ptr [eax], 0Ah
mov eax, [ebp+heapArray]
mov dword ptr [eax+4], 14h
mov eax, [ebp+heapArray]
mov dword ptr [eax+8], 1Eh
mov eax, [ebp+idx]
mov ecx, [ebp+heapArray]
mov dword ptr [ecx+eax*4], 28h


*************************************************************************************


总结:
只有当变量作为数组的索引时才最容易确定数组的存在

原文地址:https://www.cnblogs.com/HsinTsao/p/6439347.html