C语言反汇编入门小知识

C语言反汇编入门小知识


0 . 说明

​ 看滴水逆向视频总结笔记

​ 编译器VC++6.0

​ 主要总结一些C语言的反汇编常见的点。

1 . 子函数常识

​ 参数传入堆栈

push eax
call “子函数地址”
add esp,0x4

​ 进入函数后,堆栈的作用大概是这样,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dI0AxKr6-1583928872439)(E:/Typora/image/1583924345759.png)]

​ 然后,当函数结束后,会有一个返回值,俗称函数返回值,一般在子函数执行ret汇编语句前,会将函数返回值传入eax。所以在一个函数结束后,如果有返回值,那么我们只需查看寄存器eax。

2 . 本机宽度:32位

​ 一般程序会有32位和64位之分,所谓32位,就是4个字节,而本机宽度指的就是编译器在编译程序时考虑到cup,在一些特定的情况下,为不满4个字节的数据强行分配4个字节的堆栈空间。

1).函数传参

​ 一般在C语言中,大家都知道,int代表四个字节,short代表两个字节,char代表一个字节。但是,在函数传参的过程中,并不会考虑你的类型,也就是说,就算是char类型的参数,函数还是把它按照4个字节来传入参数。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-STqvPv9Q-1583928872441)(E:/Typora/image/1583924376928.png)]

编译器现将局部变量a = ‘x’;放入堆栈

00401068   mov         byte ptr [ebp-4],78h

而下面传参数时,虽然也是取出来放入al中,但是push压栈时对象却是eax。

00401070   mov         al,byte ptr [ebp-8]
00401073   push        eax

​ 而把参数改为int时,传参的过程只是这一句不一样,直接放入eax中。

00401070   mov         eax,byte ptr [ebp-8]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dPmyj646-1583928872442)(E:/Typora/image/1583924717293.png)]

​ 所以,不管你参数的数据类型怎样,都会讲按照4个字节的本机宽度处理参数。

2).局部变量:int型/char型

​ 在调用函数时,会有初始化问题,会先开辟空间,如果是一个空函数,那么一般

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jhtka9Ce-1583928872442)(E:/Typora/image/1583926012652.png)]

00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,40h//开辟堆栈空间

​ 而是会随着局部变量的变化而变化的,这样一来,开辟的空间就不会因为局部变量过多而内存不够。

​ 每多一个int型局部变量,开辟空间会变大。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MpaXkIFN-1583928872443)(E:/Typora/image/1583925768224.png)]

​ 但是,当局部变量为char型呢?

**[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UDPsjS6C-1583928872443)(E:/Typora/image/1583926188144.png)]**

​ 所以,对于单个局部变量,不管是char还是int,每多一个,就多分配4个堆栈空间。

3).局部变量:int型数组/char型数组

​ 上面说到,单个int型或char型变量分配的堆栈内存空间是一样的,但是对应的数组呢?

​	[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6kQlEiq1-1583928872443)(E:/Typora/image/1583926624145.png)]

​ 多分配了0x10个空间,注意是十六进制,所以对应4*4;

​ 而char型数组呢?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QT9K9DuV-1583928872444)(E:/Typora/image/1583926772291.png)]

​ 这里数组就只是多分配了4个堆栈空间(1*4);

但是,这里也存在本机宽度问题,如果我们只是定义一个char arr[3]的数组,编译器会怎样分配呢?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FADqZR5s-1583928872444)(E:/Typora/image/1583926982149.png)]

​ 所以,如果char数组大小不足4的倍数,那编译器会自动补充,从而分配4的倍数的堆栈空间。

3 . 64位的数据存储

​ 一般,我们对堆栈最大是4个字节为一组,那如果遇到64位的数据,如何存储呢?可以从函数返回值来分析这个问题。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rRl0dz2M-1583928872445)(E:/Typora/image/1583928067658.png)]

​ 首先,每个64位的int型数据占8位。

​ 在堆栈存储是,堆栈从低到高依次存储数据高位[ebp-4],到数据低位[ebp-8]。(小端存储)

0040D4B8   mov         dword ptr [ebp-8],89ABCDEFh
0040D4BF   mov         dword ptr [ebp-4],1234567h

/*与数组的存储正好相反,数组是arr[0]到arr[n]依次从堆栈高位向低位存储。*/

而在函数返回值,返回64位int型数据时,eax存储数据低位,edx存储数据高位。

0040D4C6   mov         eax,dword ptr [ebp-8]
0040D4C9   mov         edx,dword ptr [ebp-4]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值