内容简介:汇编语言是学习逆向的基础,本文通过从汇编的层面分析知识有限,如果有错误或则不清楚的地方还请您指出。您的鼓励是我写文章的动力。
前言
汇编语言是学习逆向的基础,本文通过从汇编的层面分析 函数调用 来了解 压栈、跳转、执行、返回 的具体实现流程以及对 堆栈 的应用。
知识有限,如果有错误或则不清楚的地方还请您指出。
您的鼓励是我写文章的动力。
1. 函数调用的说明
在介绍函数调用的具体流程前,我们先来了解一下几个知识点。
-
1.1 程序的执行流程
程序是顺序执行的,cpu是怎么进行实现的呢?
程序的执行离不开一个关键的寄存器。
我们首先来了解一下关于 程序计数器 的概念。
百度百科:
由此可见,程序计数器的功能就是存放下一条要执行指令的地址。
在X86汇编中,执行程序计数功能的寄存器叫做 EIP ,指令指针寄存器。
我们可以写个简单的程序,查看反汇编了解一下。
EIP寄存器里面存放的就是即将要执行指令的地址。
-
1.2 程序的栈结构
在经典的操作系统里,栈总是 向下增长 的。栈顶由 esp寄存器 定位。压栈操作使栈顶的地址减小,弹出操作使栈顶地址增大。
函数的调用离不开栈,栈中保存了函数调用当中的所有信息。
-
函数的返回地址和参数;
-
函数的非静态的局部变量;
-
保存上下文:保存一些不需要改变的寄存器。
为了能够正确的处理函数调用的堆栈平衡,我们需要更正两个寄存器ebp,esp的位置:
1. 把ebp提升到esp的位置。
2. esp的值是动态变化的,随着申请更多的临时变量,e's'p会不断减小。
3. 调用函数后栈中的结构图。
-
1.3 调用约定及堆栈平衡
在函数调用过程中,参数需要提前压栈,而在函数调用结束后,之前压栈的参数也需要退栈。
这样就有一个问题,退栈的工作是交给 调用者 完成还是交给 被调用函数 完成?
这就需要有个约定。
常见调用约定的堆栈平衡方式:
调用约定 | 堆栈平衡方式 |
__stdcall | 函数自己平衡 |
__cdecl | 调用者负责平衡 |
__thiscall | 调用者负责平衡 |
__fastcall | 调用者负责平衡 |
__naked | 有编写者负责 |
2. 函数调用的流程
了解了基本的概念之后,回到主题: 函数调用
-
压栈:函数参数压栈 返回地址压栈
-
跳转:跳转到函数所在代码处执行
-
执行:执行函数代码
-
返回:平衡堆栈 找出返回地址并跳回
-
2.1 call指令
0x210000 call swap; 0x210005 mov ecx,eax;
call指令可以分解成两个指令:
push 0x210005; jmp swap;
首先push当前指令下一条指令的地址,目的是调用完函数后可以跳回来;
然后修改 eip, 跳到函数的地址。
-
2.2 ret指令
ret指令表示取出当前栈顶值作为返回地址,将 eip 修改为该地址。
执行完这一步一个基本的函数调用就完成了。
3. 函数调用汇编实验
测试程序
在main函数中调用一个交换两个数的函数。
#include <stdio.h> void _stdcall swap(int& a,int& b); //交换两个数 void _stdcall swap(int& a, int& b) { int c = a; a = b; b = c; } void main() { int a = 1; int b = 2; printf("交换前:a =%d,b=%d\n",a,b); swap(a,b); printf("交换后:a= %d,b=%d\n",a,b); getchar(); }
程序的运行结果:
-
3.1 压栈
-
3.1.1 函数参数压栈
真正调用函数前先将参数进行压栈。
我们通过观察寄存器和内存来查看变化过程:
发现参数已经被压入栈中。
-
3.1.2 返回地址压入栈中
F11进入swap函数后,可以发现内存当中凭空出现一段数,它是什么?
其实它就是call指令的下一条指令的地址:
-
3.2 跳转
跳转到swap函数内部,下面是详细注解
-
3.3 返回
执行ret前。
执行ret后, 帖前先滑动左侧填充拼图:
由于使用的是 __stdcall 的调用约定,在被调用函数内部进行堆栈平衡。
4. 结语
这样,一个函数调用的实现就分析完成了。有好多细节的问题没有进行阐述。这样一篇文章用来总结汇编的知识点,希望遇到同道中人。
成为逆向大牛的过程是艰辛的,你已经迈出了第一步,加油。
- End -
看雪ID:Jabez
https://bbs.pediy.com/user-825190.htm
本文由看雪论坛 Jabez 原创
转载请注明来自看雪社区
书籍推荐:
-
《加密与解密》
是一本逆向必读书籍。本书以软件逆向为切入点,讲述了软件安全领域相关的基础知识和技能,可以说是安全人士必读书籍之一了。
看雪推荐“解密”前的过渡书籍:
-
基普·欧文的《汇编语言:基于x86处理器》
-
王爽的《汇编语言》
-
Charles Petzold著的《Windows程序设计》(以VC来讲解)
长按识别二维码,即可购买以上书籍
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- iOS高级调试&逆向技术-汇编寄存器调用约定教程
- 从汇编角度看fmt.Println是如何系统调用的
- iOS汇编入门教程(一)ARM64汇编基础
- iOS 汇编入门教程(一):ARM64 汇编基础
- iOS汇编入门教程(三)汇编中的 Section 与数据存取
- iOS汇编入门教程(二)在Xcode工程中嵌入汇编代码
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。