首页
社区
课程
招聘
[旧帖] [原创]C语言——数组和简单栈 0.00雪花
发表于: 2011-5-27 21:46 2939

[旧帖] [原创]C语言——数组和简单栈 0.00雪花

2011-5-27 21:46
2939

数组
        具有相同属性的,在内存中顺序排列的一组数据。
int nAge1,nAge2,nAge3…nAge49;
int nAge[50] = {0};
上述两实质是相同的,只是数组提供了跟好的管理,将相同的类型的数据组织起来使用。

    int nAge1 = 0x19880808;
00324335  mov         dword ptr [nAge1],19880808h 
    int nAget2 = 0x19870707;
0032433C  mov         dword ptr [nAget2],19870707h 
    //.............
    int nAge50 = 0x19890909;
00324343  mov         dword ptr [nAge50],19890909h 

    int nAge[50] = {1,2,3,4,5};
0032434A  mov         dword ptr [nAge],1 
00324354  mov         dword ptr [ebp-0ECh],2 
0032435E  mov         dword ptr [ebp-0E8h],3 
00324368  mov         dword ptr [ebp-0E4h],4 
00324372  mov         dword ptr [ebp-0E0h],5 

    int nHight[50] ;
    for (int i = 0; i < sizeof(nAge)/sizeof(nAge[0]); ++i)
    {
        nHight[i] = i;
        *(int*)(nAge+i) = i;
    }

   for (int i = 0; i < sizeof(nAge)/sizeof(nAge[0]); ++i)
01144363  mov         dword ptr [i],0 
0114436D  jmp         wmain+6Eh (114437Eh) 
0114436F  mov         eax,dword ptr [i] 
01144375  add         eax,1 
01144378  mov         dword ptr [i],eax 
0114437E  cmp         dword ptr [i],32h 
01144385  jae         wmain+9Fh (11443AFh) 
    {
        nHight[i] = i;
01144387  mov         eax,dword ptr [i] 
0114438D  mov         ecx,dword ptr [i] 
01144393  mov         dword ptr nHight[eax*4],ecx 
        *(int*)(nAge+i) = i;
0114439A  mov         eax,dword ptr [i] 
011443A0  mov         ecx,dword ptr [i] 
011443A6  mov         dword ptr nAge[eax*4],ecx 
}
    int nTemp1 = nHight[20];
    int nTemp2 = *(nHight + 20);
    int nTemp3 = *((char*)nHight +sizeof(nHight[0]/*sizeof(int)*/)*20);

    int nTemp1 = nHight[20];
003343AF  mov         eax,dword ptr [ebp-170h] 
003343B5  mov         dword ptr [nTemp1],eax 
    int nTemp2 = *(nHight + 20);
003343BB  mov         eax,dword ptr [ebp-170h] 
003343C1  mov         dword ptr [nTemp2],eax 
    int nTemp3 = *((char*)nHight + sizeof(nHight[0]/*sizeof(int)*/)*20);
003343C7  movsx       eax,byte ptr [ebp-170h] 
003343CE  mov         dword ptr [nTemp3],eax 


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 7
支持
分享
最新回复 (1)
雪    币: 191
活跃值: (130)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
2
关于数组这里简单说下:
数组就是相同数类型的一个数据块,通过下标来区分不同的数据,重点了解数组的寻址公式,这里引用下论坛里的资料,这个帖子的作者evilkis 将数组涉及到的概念都讲的比较清楚。
原帖地址为  http://bbs.pediy.com/showthread.php?t=120897   【分享】C数组与指针学习笔记,作者:evilkis
一维数组的寻址公式
如int a[6];
则a[n]的地址为(int)a+sizeof(int)*n(当然n<=6),其原理即:首地址+偏移地址其中a一定要做强制类型转换因为a是有类型的,必须把其转换成整数,sizeof(int)即是一个元素的大小
推而广之
对于TYPE array[m];
则array[n]的地址为:(int)array+sizeof(TYPE)*n(n<=m)//做逆向的时候很有用
二维数组的寻址公式
如:int a[4][5]
则a[2][3]的地址为:(int)a+sizeof(int[5])*2+sizeof(int)*3
                  |           |            |
                  |           |            | 
             数组首地址    行偏移      列偏移
即:先算确定在第几行,在确定在第几列最后加上首地址
或者第二种方式:
a[2][3]的地址为:(int)a+sizeof(int)*(2*5+3)    
                          |
                          | 
       直接定位元素看跨越了多少个元素然后乘以他们的数据类型大小
因为数组a每一行有5个元素故2*5,3是目标行的元素偏移
故推而光之
对于TYPE array[x][y]二维数组
则array[m][n]的地址为:(int)a+sizeof(int[y])*m+sizeof(TYPE)*n
或array[m][n]的地址为:(int)a+sizeof(TYPE)*(m*y+n)
这些寻址公式在逆向过程中很有用,至少看到这样的寻址方式我们应该能想到是个数组,其实把数组在内存中的存放想成线性的就很好理解这些寻址方法。

另外上述帖子对指针涉及到的概念也讲述的很清楚,用奶牛和牛奶来讲述各种类型的指针区别非常好,我现在都没有十足把握搞清楚这些指针该叫什么。
这里只对讲述指针加法补充一点点:
指针类型做加法时实际就是移动指针到下一个类型的内存位置:
比如:
    char* lpBuf = "Test";
00D4457E  mov         dword ptr [lpBuf],offset string "Test" (0D4783Ch) 
    ++lpBuf;
00D44585  mov         eax,dword ptr [lpBuf] 
00D44588  add         eax,[B][COLOR="Red"]1[/COLOR][/B]  //char型指针所以下一地址就是类型大小
00D4458B  mov         dword ptr [lpBuf],eax 
    int nNum = 0x12;
00D4458E  mov         dword ptr [nNum],12h 
    int* lpNum = &nNum;
00D44595  lea         eax,[nNum] 
00D44598  mov         dword ptr [lpNum],eax 
    ++lpNum;
00D4459B  mov         eax,dword ptr [lpNum] 
00D4459E  add         eax,[COLOR="red"][B]4[/B][/COLOR] //同上
00D445A1  mov         dword ptr [lpNum],eax 
    int nAry[3][4] = {0};
00D445A4  mov         dword ptr [nAry],0 
00D445AB  push        2Ch  
00D445AD  push        0    
00D445AF  lea         eax,[ebp-54h] 
00D445B2  push        eax  
00D445B3  call        @ILT+160(_memset) (0D410A5h) 
00D445B8  add         esp,0Ch 
    int (*lpAry)[4] = nAry;
00D445BB  lea         eax,[nAry] 
00D445BE  mov         dword ptr [lpAry],eax 
    ++ lpAry;
00D445C1  mov         eax,dword ptr [lpAry] 
//指针数组,类型是个数组,4个元素*sizeof(int)
00D445C4  add         eax,[COLOR="red"][B]10h [/B][/COLOR] 00D445C7  mov         dword ptr [lpAry],eax 

指针的大小是固定的,32位为4字节也就是32位。

C语言不好理解的应该就这几部分了,其他内容多联系下也应该可以较容易搞定,况且其他内容论坛都有相关精彩文章,大家参考并吸取就好了

基本数据类型和局部变量: http://bbs.pediy.com/showthread.php?t=134570
常量:  http://bbs.pediy.com/showthread.php?t=134555
简单的函数调用过程: http://bbs.pediy.com/showthread.php?t=135551

声明 : 水平比较菜,表述不清和错误难免,只是将个人的一点心得拿出来检讨下,也希望有过来人能多多提点,求进步求提高!

                     五边形
2011-6-16 19:27
0
游客
登录 | 注册 方可回帖
返回
//