逆向-数组

对于数组而言,我们需要理解其数组的寻址公式,而其公式又与其内存的分布息息相关,所以当你了解了其内存分布,那么这个公式自然而然也能推出来。

首先数组有如下两点性质

连续性-排列连续
一致性-类型一致

因为有其连续的特点,所以其内存模型也就比较好理解,下面我们来看一下如下代码

int arr[5] = {0,1,2,3,4}

上面就是其内存模型,对于一致性的特点,可以推定其每个元素占用的空间大小一致,上面的话就是每个元素占4字节(int)

所以我们假设数组开始的首地址为0x10000,那么其各个元素在内存中占的地址是多少呢

arr[0] 0x10000
arr[1] 0x10004
arr[2] 0x10008
arr[3] 0x1000c
arr[4] 0x10010

其实很明显,上面就是一个等差数列,所以其一维数组的寻址公式为

ary+sizeof(type)*n

ary[3] ->  0x10000 + 4 * 3 = 0x1000C

此时就可以很方便的定位到每一个元素了。下面来看一下对应的一维数组的反汇编

int main(int argc, char* argv[])
{
    int arr[5] = {1,2,3,4,5};
    printf("%d",arr[2]);
    printf("%d",arr[argc]);
    printf("%d",arr[argc%7]);
    for(int i=0;i < 5;++i)
    {
        printf("%d\r\n",arr[i]);
    }
    return 0;
}

对应的反汇编代码

21:       int arr[5] = {1,2,3,4,5};
0040D7A8 C7 45 EC 01 00 00 00 mov         dword ptr [ebp-14h],1  //说明数组首地址为ebp-0x14
0040D7AF C7 45 F0 02 00 00 00 mov         dword ptr [ebp-10h],2
0040D7B6 C7 45 F4 03 00 00 00 mov         dword ptr [ebp-0Ch],3
0040D7BD C7 45 F8 04 00 00 00 mov         dword ptr [ebp-8],4
0040D7C4 C7 45 FC 05 00 00 00 mov         dword ptr [ebp-4],5
22:       printf("%d",arr[2]); //arr[2] -> ebp-14 + 4 * 2 = ebp-0c
0040D7CB 8B 45 F4             mov         eax,dword ptr [ebp-0Ch]
0040D7CE 50                   push        eax
0040D7CF 68 1C 20 42 00       push        offset string "%d" (0042201c)
0040D7D4 E8 27 39 FF FF       call        printf (00401100)
0040D7D9 83 C4 08             add         esp,8
23:       printf("%d",arr[argc]);  // arr[argc]  ->  ebp-14h+argc*4
0040D7DC 8B 4D 08             mov         ecx,dword ptr [ebp+8]
0040D7DF 8B 54 8D EC          mov         edx,dword ptr [ebp+ecx*4-14h]  //换个写法 [ebp-14h+ecx*4]
0040D7E3 52                   push        edx
0040D7E4 68 1C 20 42 00       push        offset string "%d" (0042201c)
0040D7E9 E8 12 39 FF FF       call        printf (00401100)
0040D7EE 83 C4 08             add         esp,8
24:       printf("%d",arr[argc%7]);
0040D7F1 8B 45 08             mov         eax,dword ptr [ebp+8]
0040D7F4 99                   cdq
0040D7F5 B9 07 00 00 00       mov         ecx,7
0040D7FA F7 F9                idiv        eax,ecx  //先计算结果此时,结果在edx
0040D7FC 8B 54 95 EC          mov         edx,dword ptr [ebp+edx*4-14h]  //寻址公式和上面相同
0040D800 52                   push        edx
0040D801 68 1C 20 42 00       push        offset string "%d" (0042201c)
0040D806 E8 F5 38 FF FF       call        printf (00401100)
0040D80B 83 C4 08             add         esp,8
25:       for(int i=0;i < 5;++i)
0040D80E C7 45 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值