Windows 逆向-多维数组

Oyst3r 于 2023-12-23 发布

前言

不要被名字吓到了,不管是几维的数组,在计算机里面都是按照一维的线性排列的,定义成多维的只是方便程序员处理数据更加的直观

课堂

二维数组分配空间

这里首先给出一个代码示例

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

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

其实上面的和下面的意思是一样的,不过上面那么写的话,对数据的操作更加的灵活了,咱们先看一下一维数组咋分的,这个其实上篇文章也说过,就是地址从低到高依次分配

而对于二维数组来说,

编译器同样也是先计算数组的长度,会将两个[]中的长度相乘得到数组的长度–3 * 4 = 12,且是 int 类型的数据,所以 12 * 4 = 48 = 0x30,所以 VC6 编译器会开辟缓冲区大小也同样为 0x40 + 0x30 = 0x70 字节,而且虽然定义时是四个四个一组,一共三组,但是对编译器来说一维还是多维是无差别的,还是按照将数组中的数据正着从低地址向高地址存到缓冲区中

所以二维数组还可以省略当中的{},编译器也会根据定义数组时后面的[][]中的数值自动分组计算大小,没给初值的时候默认补 0

int arr[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int arr[3][4] = {1,2,3,4,5,6,7,8,9,10};  //补0

编译器获取元素的办法

定义一个二维数组

int arr[5][12] = {
	{1,2,1,4,5,6,7,8,99,1,2,3}, //0
	{1,2,1,4,5,6,7,88,9,1,2,3},  //1
	{1,2,1,4,5,6,7,8,9,1,2,3},  //2
	{1,2,1,4,5,6,7,8,9,1,2,3},  //3
	{1,2,1,4,5,6,7,8,9,1,2,3},  //4
  // 0 1 2 3 4 5 6 7 8 9 10 11
};
int i = arr[0][8];
int j = arr[1][7];

如果现在我要得到arr[0][8]中的值,那么可以理解为找第 1 行第 9 个值,所以就是 99;但编译器可不是这么想的,

编译器是不分行和列的概念的,它只管正着从低地址向高地址存,所以编译器其实是根据[ebp - 0xF0 + (0 * 0xC + 0x8) * 0x4] = [ebp - 0xD0]得到的 arr[0][8]中的值,即先找到数组中第一个元素的存储地址[ebp - 0xF0],然后根据下标做运算得到结果[ebp - 0xD0]

三维数组

这就和二维数组一个道理,我就不阐述了,这里放海东老师的一张讲义图片

作业

1.这里把前面的 5 个练习写一块了

void Class_age(){

	int student_age[5][10] = {

		{21,22,23,25,17,27,18,16,15,19},

		{20,21,19,25,17,27,19,16,15,18},

		{21,19,22,16,17,27,18,16,15,19},

		{21,22,20,25,17,27,18,16,15,19},

		{21,22,23,24,17,21,17,16,15,19},
	};

	printf("%d\n",student_age[1][5]);

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

		int j;

		if(i == 1){

			for(j = 0;j < 10;j++){

				if(student_age[i][j] >= 20){

					student_age[i][j] = 21;
				}
			}
		}
		for(j = 0;j < 10;j++){
			printf("%d ",student_age[i][j]);

		}
		printf("\n");
	}

	printf("------------------------------------\n");
	for(i = 0;i < 5;i++){

		int sum_age_class = 0;
		int k;
		for(k = 0;k < 10;k++){
			sum_age_class += student_age[i][k];
		}
		printf("%d\n",sum_age_class);
	}

}

2.第六个练习就是一个归并排序,但注意事项挺多的,我写的这个是适用于任何场景的,前提就是两个数组已经是排好序的,然后我是举了个特殊的例子,大家改一下里面具体的数值,就能封装成一个函数去使用了

void sort_arry_guibing(){

	int arry_1[7] = {1,2,3,4,5,6,101};
	int arry_2[6] = {7,7,7,9,49,100};
	int i = 0;
	int j = 0;
	int arry_results[13] = {0};
	int count = 0;

	for(i;i < 7;i++){

		for(j;j < 6;j++){

			if(arry_1[i] >= arry_2[j]){

				arry_results[count++] = arry_2[j];
			}else{
				arry_results[count++] = arry_1[i];
				break;
			}
		}
	}
	printf("%d",count);
	if(arry_2[5] == arry_results[count - 1]){

		int temp = 7-(13-count);
		for(temp;temp < 7;temp++)
		{
			arry_results[count++] = arry_1[temp];

		}

	}else{
		int temp = 6-(13-count);
		for(temp;temp < 6;temp++)
		{
			arry_results[count++] = arry_2[temp];

		}
	}
	for(count = 0;count < 13;count++){

		printf("%d ",arry_results[count]);
	}


}

OKK 就到这里