IDA PRO 07 - 反汇编基础01

本文聚焦反汇编里的函数调用与栈帧。介绍了栈帧对函数参数和局部变量的分配释放机制,阐述了C、标准、x86 fastcall、C++等调用约定,说明了局部变量布局情况,还讲解了IDA栈视图的摘要和详细视图,帮助理解函数调用过程。

本文主要讨论一下反汇编里面的函数调用与栈帧。内容将会比较偏理论,但是你看过《CSAPP》的话,也不难理解。有兴趣的可以去B站搜一下该内容,有个up讲的不错,图文并茂,总共百来个小时,花几个月时间看完还是很划得来的。

栈帧

当函数被调用时,函数的调用方可能希望以参数(实参)的方式向该函数传递信息,这些参数需要存储到函数能够找到它们的位置。其二,函数的编写过程中,程序员通常会使用到局部变量,这些变量将在函数内部使用,完成函数调用以后,就无法再访问它们。

编译器通过栈帧对函数参数和局部变量进行分配和释放,这个过程对程序员是透明的。在将控制权转交给函数之前,编译器会插入代码,将函数参数放入栈帧内,并分配足够的内存,以保存函数的局部 变量。鉴于栈帧的结构,该函数的返回地址也存储在新的栈帧内。这样就可以进行函数的递归,因为每个递归函数调用都有它自己的栈帧。

下面是调用一个函数时的详细操作步骤:

  1. 调用方将被调用函数所需的任何参数放入到该函数所采用的调用约定指定的位置。如果参数被放到运行时栈上,该操作可能导致程序的栈指针发生改变。

  2. 调用方将控制权转交给被调用的函数,这个过程常由x86 CALL 指令执行。然后,返回地址被保存到程序栈或CPU 寄存器中。

  3. 如有必要,被调用的函数会配置一个栈指针 ,并保存调用方希望保持不变的任何寄存器值。

    1. 帧指针 是一个指向栈帧位置的寄存器。通常,栈帧内的变量根据它们与帧指针所指向的位置的相对距离来引用。

  4. 被调用的函数为它可能需要的任何局部变量分配空间。一般,通过调整程序栈指针在运行时栈上保留空间来完成这一任务。

  5. 被调用的函数执行其操作,可能生成一个结果。在执行操作的过程中,被调用的函数可能会访问调用函数传递给它的参数。如果函数返回一个结果,此结果通常被放置到一个特定的寄存器中,或者放置到函数返回后调用方可立即访问的寄存器中。

  6. 函数完成其操作后,任何为局部变量保留的栈空间将被释放。通常,逆向执行第4步中的操作,即可完成这个任务。

  7. 如果某个寄存器的值还为调用方保存(第3步)着,那么将其恢复到原始值。这包括恢复调用方的帧指针寄存器。

  8. 被调用的函数将控制权返还给调用方。实现这一操作的主要指令包括 x86 RET 。根据所使用的调用约定,这一操作可能还会从程序栈中清除一个或多个参数。

  9. 调用方一旦重新获得控制权,它可能需要删除程序栈中的参数。这时可能需要对栈进行调整,以将程序栈指针恢复到第(1)步以前的值。

调用约定

上面对栈帧的介绍提到了一个东西:调用约定。

创建栈帧时最重要的步骤是,通过调用函数将函数参数存入栈中。调用函数必须存储被调用函数所需的参数,否则可能导致严重的问题。各个函数会选择并遵照某一特定的调用约定,以表明它们希望以何种方式接收参数

调用约定指定调用方放置函数所需参数的具体位置。调用约定可能要求将参数放置在特定的寄存器、程序栈、或者寄存器和栈中。同样重要的是,在传递参数时,程序栈还要决定:被调用函数完成其操作后,由谁负责从栈中删除这些参数。一些调用约定规定,由调用方负责删除它放置在栈中的参数,而另一些调用约定则要求被调用函数负责删除栈中的参数。遵照指定的调用约定对于维护程序栈指针的完整性尤为重要。

C调用约定

x86体系结构的许多C编译器使用的默认调用约定叫做C调用约定 。一般,我们把这种调用约定叫做cdecl 调用约定。

cdecl 调用约定规定:调用方按从右到左的顺序将函数参数放入栈中,在被调用的函数完成其操作时,调用方(而不是被调用方)负责从栈中清除参数

举个例子:

void demo_cdecl(int w, int x, int y, int z);

默认情况下,这个函数将使用cdecl 调用约定,并希望你按从右到左的顺序压入4个参数,同时要求调用方清除栈中的参数。编译器可能会为这个函数的调用生成以下代码:

; demo_cdecl(1, 2, 3, 4); //programmer calls demo_cdecl
➊ push 4 ; push parameter z
push 3 ; push parameter y
push 2 ; push parameter x
push 1 ; push parameter w
call demo_cdecl ;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二手的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值