一、数组
输入如下程序
#include "stdafx.h"
void Function()
{
int x = 10;
int y = 20;
int z = 30;
int v = 40;
}
int main(int argc, char* argv[])
{
Function();
return 0;
}
查看汇编如图
而如果用数组,就会方便很多,数组的本质就是存一些相同类型的变量,之前说过long和short和int在计算机里的都是4位
#include "stdafx.h"
void Function()
{
int arr[10]={1,2,3,4,5,6,7,8,9,10};
}
int main(int argc, char* argv[])
{
Function();
return 0;
}
汇编如下
是倒着排的,这样排就是从低地址向高地址引用
如果这样写:
// test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
void Function()
{
int arr[10]={1,2,3,4,5};
}
int main(int argc, char* argv[])
{
Function();
return 0;
}
打印出来的是一个地址,打印出来Function里
反汇编
存到ebp+4了,这里的ebp+4就是返回地址,也就是说完事以后会直接跳到这个地址,因为会把这个当EIP弹出去,这就是之前我们说的pwn缓冲区溢出
输入这个:
如图,然后这个offset是VC6生成的一个标识
这个就可以把helloworld弹到这里,最后可以打印hello world
二、二维数组
这里可以形象点理解,有3个组,每组有4个人,最后一个不能加逗号
反汇编的角度理解
输入这个数组,查看反汇编
上面是提升了70个空间
换成2维数组
查看反汇编
没有区别哈,不管是1维数组,2维数组,都没有区别,至少对编译器来说,是没有区别的,编译器是这样弄:int arr[3*4]
如果里面有的写空的呢?
如图,先放1和2,然后异或,把eax清0,然后把0补足空间,补两个,然后后面补3个了
如果整成这种了,编译器直接报错,编译器编译不过去
如果写成这种:
和之前的一样,是可以编译的,就之前说的多维数组和一维是一样的
这个的话,也是直接补0
为什么用多维数组?写代码的人方便,因为编译器对待单维数组和多维数组是一样的
如果是这种
也可以编译,如果这样省了,可以的,一组四个
但是这样,就编译失败了,所以只能省略前面的数字
这样的话就直接补0
如果这样的话,就直接分两组
给了这一个数组,是这样找到的
所以这也解释了为什么从0开始的
总结
数组实际上就是一些数据类型相同的数据,存储的话和一个个存是相反的,这也是缓冲区溢出的利用
多维数组和单维数组本质上在汇编里是一样,但是多维数组方便编写者。数组的检索方式就是为什么我们以0为开头的原因