C语言反汇编之数组-未完待续

1、代码示例

#include "stdafx.h"

int main(int argc, char* argv[])
{
	int i=0, a[4]={1,2,3,4},j=5;
	for(i=4; i>=0; i--)
		printf("%d",a[i]);
	printf("\n end!");

	return 0;
}

2、反汇编

我们反汇编赋值语句时,首先可以发现在定义时元素是按照先后顺序入栈的(即自左向右入栈),在这里我们先将 i 压入栈中,然后将数组 a[4] 压入栈中,最后将 j=5 压入栈中;然后观察 数组 a[4] 元素的入栈,发现 【ebp-14h】数组的首地址,且入栈顺序是 4,3,2,1;因此我么可以判断,数组入栈顺序是从右至左。
在这里插入图片描述
上面我们反汇编的是int数组,发现这个每个元素占 4个字节。下图,我们反汇编的是字符数组的,通过堆栈我们可以知道字符数组每个元素占 1个字节。
在这里插入图片描述

3、数组示例

参考链接:常见指针和数组的反汇编(x86)

一维数组的定义和赋值
8:        int i=0, a[4]={1,2,3,4},temp;
0040D778 C7 45 FC 00 00 00 00 mov         dword ptr [ebp-4],0
0040D77F C7 45 EC 01 00 00 00 mov         dword ptr [ebp-14h],1//a[1]
0040D786 C7 45 F0 02 00 00 00 mov         dword ptr [ebp-10h],2//a[2]
0040D78D C7 45 F4 03 00 00 00 mov         dword ptr [ebp-0Ch],3//a[3]
0040D794 C7 45 F8 04 00 00 00 mov         dword ptr [ebp-8],4  //a[4]

二维数组:

8:        int i, a[2][3]={1,2,3,4},temp;
0040D778 C7 45 E4 01 00 00 00 mov         dword ptr [ebp-1Ch],1
0040D77F C7 45 E8 02 00 00 00 mov         dword ptr [ebp-18h],2
0040D786 C7 45 EC 03 00 00 00 mov         dword ptr [ebp-14h],3
0040D78D C7 45 F0 04 00 00 00 mov         dword ptr [ebp-10h],4
0040D794 33 C0                xor         eax,eax
0040D796 89 45 F4             mov         dword ptr [ebp-0Ch],eax	//a[1][1]
0040D799 89 45 F8             mov         dword ptr [ebp-8],eax		//a[1][2]
一维数组的元的赋值、取值、自增
10:       a[0] = 6; 	//数组元素的赋值
0040D79B C7 45 EC 06 00 00 00 mov         dword ptr [ebp-14h],6
11:       temp = a[1];	//数组元素的取值
0040D7A2 8B 45 F0             mov         eax,dword ptr [ebp-10h]
0040D7A5 89 45 E8             mov         dword ptr [ebp-18h],eax
12:       a[2]++;		//自增
0040D7A8 8B 4D F4             mov         ecx,dword ptr [ebp-0Ch]
0040D7AB 83 C1 01             add         ecx,1
0040D7AE 89 4D F4             mov         dword ptr [ebp-0Ch],ecx

二维数组:可以发现表示二维数组的元素和一维数组相差不大,都是直接定位内存单元地址寻找元素的,和下标无关。

10:       a[0][0] = 6;
0040D79C C7 45 E4 06 00 00 00 mov         dword ptr [ebp-1Ch],6
11:       temp = a[0][1];
0040D7A3 8B 4D E8             mov         ecx,dword ptr [ebp-18h]
0040D7A6 89 4D E0             mov         dword ptr [ebp-20h],ecx
12:       a[0][2]++;
0040D7A9 8B 55 EC             mov         edx,dword ptr [ebp-14h]
0040D7AC 83 C2 01             add         edx,1
0040D7AF 89 55 EC             mov         dword ptr [ebp-14h],edx

一维数组中元素的动态赋值与被赋值
//eax = i
14:           a[i] = i+2;	//被变量动态赋值
0040D7C9 8B 45 FC             mov         eax,dword ptr [ebp-4]
0040D7CC 83 C0 02             add         eax,2
0040D7CF 8B 4D FC             mov         ecx,dword ptr [ebp-4]
0040D7D2 89 44 8D EC          mov         dword ptr [ebp+ecx*4-14h],eax

16:           a[i] = 10;	//被常量动态赋值
0040D7F0 8B 45 FC             mov         eax,dword ptr [ebp-4]
0040D7F3 C7 44 85 EC 0A 00 00 mov         dword ptr [ebp+eax*4-14h],0Ah

14:           temp = a[i];	//赋值给变量
0040D7C9 8B 45 FC             mov         eax,dword ptr [ebp-4]
0040D7CC 8B 4C 85 EC          mov         ecx,dword ptr [ebp+eax*4-14h]

二维数组:

11:           a[0][i] = i+2;	//被变量动态赋值
0040D7BB 8B 55 FC             mov         edx,dword ptr [ebp-4]
0040D7BE 83 C2 02             add         edx,2
0040D7C1 8B 45 FC             mov         eax,dword ptr [ebp-4]
0040D7C4 89 54 85 E4          mov         dword ptr [ebp+eax*4-1Ch],edx

16:           a[0][i] = 10;		//被常量动态赋值
0040D7EE 8B 4D FC             mov         ecx,dword ptr [ebp-4]
0040D7F1 C7 44 8D E4 0A 00 00 mov         dword ptr [ebp+ecx*4-1Ch],0Ah

14:           temp = a[0][i];	//动态赋值给变量
0040D7CA 8B 4D FC             mov         ecx,dword ptr [ebp-4]
0040D7CD 8B 54 8D E4          mov         edx,dword ptr [ebp+ecx*4-1Ch]
0040D7D1 89 55 E0             mov         dword ptr [ebp-20h],edx

4、溢出函数

关于溢出的函数,之前详细的讲解过了 strcpy 和 memcpy 两个函数,所以这里就不细讲了,详情请移步:哦!

1、连接函数 strcat(str1, str2)

如下图,为此函数的溢出原理:str2长度 > str1 的长度,然后导致溢出,当 str2 足够长时,溢出的字符串把 函数执行结束后 ret 的返回地址覆盖了,然后就可以实现地址跳转了。
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值