C语言反汇编入门小知识
文章目录
0 . 说明
看滴水逆向视频总结笔记
编译器VC++6.0
主要总结一些C语言的反汇编常见的点。
1 . 子函数常识
参数传入堆栈
push eax
call “子函数地址”
add esp,0x4
进入函数后,堆栈的作用大概是这样,
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dI0AxKr6-1583928872439)(E:/Typora/image/1583924345759.png)]](https://i-blog.csdnimg.cn/blog_migrate/1812b839a7baba9cf301a4941aeaa9fa.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)]](https://i-blog.csdnimg.cn/blog_migrate/34457b897d32ddd66eb3c1835c9aa103.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)]](https://i-blog.csdnimg.cn/blog_migrate/a2baaecadfd6397f16dc06d86d1a79e9.png)
所以,不管你参数的数据类型怎样,都会讲按照4个字节的本机宽度处理参数。
2).局部变量:int型/char型
在调用函数时,会有初始化问题,会先开辟空间,如果是一个空函数,那么一般
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jhtka9Ce-1583928872442)(E:/Typora/image/1583926012652.png)]](https://i-blog.csdnimg.cn/blog_migrate/ba4394328b9e5da4d24a4616843e67f1.png)
00401020 push ebp
00401021 mov ebp,esp
00401023 sub esp,40h//开辟堆栈空间
而是会随着局部变量的变化而变化的,这样一来,开辟的空间就不会因为局部变量过多而内存不够。
每多一个int型局部变量,开辟空间会变大。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MpaXkIFN-1583928872443)(E:/Typora/image/1583925768224.png)]](https://i-blog.csdnimg.cn/blog_migrate/17414a74f1618564188e15cd20433b2b.png)
但是,当局部变量为char型呢?
![**[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UDPsjS6C-1583928872443)(E:/Typora/image/1583926188144.png)]**](https://i-blog.csdnimg.cn/blog_migrate/1ae79f38eee7b80a64e361a793cfc6b7.png)
所以,对于单个局部变量,不管是char还是int,每多一个,就多分配4个堆栈空间。
3).局部变量:int型数组/char型数组
上面说到,单个int型或char型变量分配的堆栈内存空间是一样的,但是对应的数组呢?
![ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6kQlEiq1-1583928872443)(E:/Typora/image/1583926624145.png)]](https://i-blog.csdnimg.cn/blog_migrate/f52fb40af71812f7d395d21e7499a273.png)
多分配了0x10个空间,注意是十六进制,所以对应4*4;
而char型数组呢?
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QT9K9DuV-1583928872444)(E:/Typora/image/1583926772291.png)]](https://i-blog.csdnimg.cn/blog_migrate/8f468069bf8b0bb9fa8de155846d7133.png)
这里数组就只是多分配了4个堆栈空间(1*4);
但是,这里也存在本机宽度问题,如果我们只是定义一个char arr[3]的数组,编译器会怎样分配呢?
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FADqZR5s-1583928872444)(E:/Typora/image/1583926982149.png)]](https://i-blog.csdnimg.cn/blog_migrate/a02e3ba1add22d40bd5cd1fa27b004c8.png)
所以,如果char数组大小不足4的倍数,那编译器会自动补充,从而分配4的倍数的堆栈空间。
3 . 64位的数据存储
一般,我们对堆栈最大是4个字节为一组,那如果遇到64位的数据,如何存储呢?可以从函数返回值来分析这个问题。
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rRl0dz2M-1583928872445)(E:/Typora/image/1583928067658.png)]](https://i-blog.csdnimg.cn/blog_migrate/0f560c51424de58b7d6f8bff459edfbb.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]
519

被折叠的 条评论
为什么被折叠?



