美文网首页
数组_多维数组_分析

数组_多维数组_分析

作者: Jessica_nasa | 来源:发表于2020-12-18 22:10 被阅读0次

VC++6.0编译器生成的数组越界

由于VC++6.0编译器,在栈中给变量和数组分配缓存区内存时,不预留保护区(0xCCCCCCCC),并且数组的寻址方式为

DWORD PTR DS:[EBP+EAX*4 - 28h]或DWORD PTR DS:[EBP-4]或DWORD PTR DS:[EBP+4]

[EBP+4] 在函数销毁执行ret命令时,会修改EIP,所以CPU会运行被修改后的函数 “返回地址”。

下面是代码测试:

//数组越界后,越界的值是ebp+4(即EIP返回地址)

void Helloword() {

    printf("==========helloword");

    getchar();

}

void arrYuJie() {

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

    arr[6] = (int)Helloword;

}

int main(int argc, char* argv[]){

    arrYuJie();

    printf("Hello World!\n");

    return 0;

}

arrYuJie:

004010D0  push        ebp

004010D1  mov        ebp,esp

004010D3  sub        esp,54h

004010D6  push        ebx

004010D7  push        esi

004010D8  push        edi

004010D9  lea        edi,[ebp-54h]

004010DC  mov        ecx,15h

004010E1  mov        eax,0CCCCCCCCh

004010E6  rep stos    dword ptr [edi]

004010E8  mov        dword ptr [ebp-14h],1

004010EF  mov        dword ptr [ebp-10h],2

004010F6  mov        dword ptr [ebp-0Ch],3

004010FD  mov        dword ptr [ebp-8],4

00401104  mov        dword ptr [ebp-4],5

0040110B  mov        dword ptr [ebp+4],offset @ILT+0(Helloword) (00401005)

00401112  pop        edi

00401113  pop        esi

00401114  pop        ebx

00401115  mov        esp,ebp

00401117  pop        ebp    

00401119   ret    ----------------------------------------->ret后会修改EIP的值,CPU会执行这个地址,就是Helloword这个函数的地址,如下:

@ILT+0(?Helloword@@YAXXZ):

00401005  jmp        Helloword (00401030)

Helloword:

00401030  push        ebp

00401031  mov        ebp,esp

00401033  sub        esp,44h

00401036  push        ebx

00401037  push        esi

00401038  push        edi

00401039  lea        edi,[ebp-44h]

0040103C  mov        ecx,11h

00401041  mov        eax,0CCCCCCCCh

00401046  rep stos    dword ptr [edi]

00401048  push        offset string "==========helloword" (0042301c)

0040104D  call        printf (004014b0)

00401052  add        esp,4

00401055  mov        eax,[__iob+4 (00425a34)]

0040105A  sub        eax,1

0040105D  mov        [__iob+4 (00425a34)],eax

00401062  cmp        dword ptr [__iob+4 (00425a34)],0

00401069  jl          Helloword+5Ch (0040108c)

0040106B  mov        ecx,dword ptr [__iob (00425a30)]

00401071  movsx      edx,byte ptr [ecx]

00401074  and        edx,0FFh

0040107A  mov        dword ptr [ebp-4],edx

0040107D  mov        eax,[__iob (00425a30)]

00401082  add        eax,1

00401085  mov        [__iob (00425a30)],eax

0040108A  jmp        Helloword+6Ch (0040109c)

0040108C  push        offset __iob (00425a30)

00401091  call        _filbuf (00401180)

00401096  add        esp,4

00401099  mov        dword ptr [ebp-4],eax

pop edi

0040109D  pop        esi

0040109E  pop        ebx

0040109F  add        esp,44h

004010A2  cmp        ebp,esp

004010A4  call        __chkesp (00401530)

004010A9  mov        esp,ebp

004010AB  pop        ebp

004010AC  ret


//桶排序 

visual studio 2019版本的编译器,在对变量或数组分配内存时,会预留int3(0xCCCCCCCC)缓存区,防止CPU执行越界后,导致程序飞

visual studio 2019版本的编译器,显然做了保护在分配栈缓冲内存时。并且寻址方式也做了变形保护。

例如:

//桶排序

void tongSort() {

    int index = 0;

    int arrS[8] = {2,4,6,5,3,8,2,1};

    int arrK[9] = { 0 };

    //把要排序的数组的数,放到空桶中,重复的数,桶里加1;

    for (int i = 0; i < 8;i++) {

        int t = arrS[i];

        arrK[t]++;

    }

    //将空桶里每个数值所对应的个数,依次放回源桶中排序列;

    for (int j = 0; j < 9;j++) {

        int t = arrK[j];

        if (t) {

            for (int n = 0; n < t;n++) {

            arrS[index] = j;

            index++;

            }

        }

    }

}


(三)多维数组

本质:多维数组就是一维数组,以二维数组举例(visual studio 2019版本的编译器);

1)编译器分内存空间:转为一位数组    int arr_one[ 3*4] = {  --- ---   };

2)//编译不过去,初始化太多。

int  arr[3][4] = {

                        {1,2,3,4,5},

                        {5},

                        {9}

                     }        

3)可编译就是乱,分配空间[3*4],正常分配,第二段不够补0

        int  arr[ 3 ] [4 ] = {1,2,3,4,5,6,7,8,9,11};

4)省略长度,编译可通过,4个一组。后面 [ 4 ] 的位置不可省略,前面的[  ]可以省略。总个数模上4来整数组分空间,还可补            0,能分几组就分几组。

        int  arr[  ][ 4 ] = {1,2,3,4,5,6,7,8,9,11};

5)寻址找到这个值    arr[ 1 ][ 2 ]  =  arr [ 1*4+2 ] 

        int  arr[3][4] = {

                               {2,3,4,9},

                                {5,4,1,8},

                                {2,7,5,4}

                             }     

6)三维数组:假设一共有5个班,每个班4个组,给个组3人。

        int  arr[ 5 ][ 4 ] [ 3 ]= {

                  {{4,1,4},{2,5,9},{5,4,3},{9,1,3}},

                  {{1,2,3},{12,52,1},{5,44,3},{9,12,31}},

                  {{4,1,8},{2,35,9},{5,4,6},{9,41,36}},

                  {{44,1,24},{2,51,3},{5,42,34},{9,1,3}},

                  {{4,16,47},{72,6,9},{7,64,5},{9,14,3}},

         }     

        寻址:第二个班,第三组的第二人,今年多大  

                    arr[ 1 ][ 2 ][ 1 ]   =  [ 1*4*3 + 2*3 + 1]  =  44

7)五维数组 int arr[ m ][ n ][ g ][ f ][ k ]

        寻址:arr[ 2 ][ 3 ][ 5 ][ 1 ][ 4 ]   = arr[ 2*n*g*f*k + 3*g*f*k + 5*f*k + 1*k + 4e ]

8)练习,归并排序,前提是两个数组都是有序的。

      j = 0  数组一:arr_1 [ 8 ] = { 3,5,7,11,13,15,21,25 };

     k = 0  数组二:arr_2 [ 6 ] = { 4,8,9,17,22,35 };

                             arr_new [ 14 ]={                                  };           


相关文章

  • 数组_多维数组_分析

    VC++6.0编译器生成的数组越界由于VC++6.0编译器,在栈中给变量和数组分配缓存区内存时,不预留保护区(0x...

  • 多维数组

    创建多维数组 多维数组可以看成是数组的数组,二维数组是最基本的多维数组。 要创建多维数组,请将每个数组放在其自己的...

  • 4.3~1多维数组

    多维数组可以看作是数组的数组,如果将多维数组看作是比较特殊的一维数组,那数组的元素本身就是数组。在学习多维数组之前...

  • 学习Java第五天

    数组是多个数据的集合 数组的语法 数组元素类型【】 数组名; 多维数组: 数组元素类型【】【】 数组名; 多维数组...

  • TS学习笔记(5)-多维数组

    多维数组的使用 ========= 知识点 多维数组的定义方法 多维数组的使用方法 代码

  • Scala多维数组、Java数组与Scala数组的隐式转换

    多维数组:数组的元素,还是数组,数组套数组,就是多维数组 构造指定行与列的二维数组:Array.ofDim方法 构...

  • Java学习day-13:多维数组和冒泡排序

    一、多维数组: 多维数组可以看成以数组为元素的数组。可以有二维、三维、甚至更多维数组。 1.二维数组: (1)二维...

  • PHP Day4:基础回顾与加强

    多维数组 多维数组指的是包含一个或多个数组的数组。 PHP 能理解两、三、四或五级甚至更多级的多维数组。不过,超过...

  • 10.31学习总结

    今天代课老师讲了c#中的数组。 一维数组:声明数组,分配空间,元素赋值,引用数组元素。 多维数组(声明多维数组时,...

  • 数组

    Array: 多维数组: 多维数组又称为矩形数组 每行的列是相同的,和交错数组不一样 交错数组: 交错数组是数组的...

网友评论

      本文标题:数组_多维数组_分析

      本文链接:https://www.haomeiwen.com/subject/oeefnktx.html