C语言反汇编入门小知识
文章目录
0 . 说明
看滴水逆向视频总结笔记
编译器VC++6.0
主要总结一些C语言的反汇编常见的点。
1 . 子函数常识
参数传入堆栈
push eax
call “子函数地址”
add esp,0x4
进入函数后,堆栈的作用大概是这样,
然后,当函数结束后,会有一个返回值,俗称函数返回值,一般在子函数执行ret汇编语句前,会将函数返回值传入eax。所以在一个函数结束后,如果有返回值,那么我们只需查看寄存器eax。
2 . 本机宽度:32位
一般程序会有32位和64位之分,所谓32位,就是4个字节,而本机宽度指的就是编译器在编译程序时考虑到cup,在一些特定的情况下,为不满4个字节的数据强行分配4个字节的堆栈空间。
1).函数传参
一般在C语言中,大家都知道,int代表四个字节,short代表两个字节,char代表一个字节。但是,在函数传参的过程中,并不会考虑你的类型,也就是说,就算是char类型的参数,函数还是把它按照4个字节来传入参数。
编译器现将局部变量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]
所以,不管你参数的数据类型怎样,都会讲按照4个字节的本机宽度处理参数。
2).局部变量:int型/char型
在调用函数时,会有初始化问题,会先开辟空间,如果是一个空函数,那么一般
00401020 push ebp
00401021 mov ebp,esp
00401023 sub esp,40h//开辟堆栈空间
而是会随着局部变量的变化而变化的,这样一来,开辟的空间就不会因为局部变量过多而内存不够。
每多一个int型局部变量,开辟空间会变大。
但是,当局部变量为char型呢?
所以,对于单个局部变量,不管是char还是int,每多一个,就多分配4个堆栈空间。
3).局部变量:int型数组/char型数组
上面说到,单个int型或char型变量分配的堆栈内存空间是一样的,但是对应的数组呢?
多分配了0x10个空间,注意是十六进制,所以对应4*4;
而char型数组呢?
这里数组就只是多分配了4个堆栈空间(1*4);
但是,这里也存在本机宽度问题,如果我们只是定义一个char arr[3]
的数组,编译器会怎样分配呢?
所以,如果char数组大小不足4的倍数,那编译器会自动补充,从而分配4的倍数的堆栈空间。
3 . 64位的数据存储
一般,我们对堆栈最大是4个字节为一组,那如果遇到64位的数据,如何存储呢?可以从函数返回值来分析这个问题。
首先,每个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]