当前位置:网站首页>X86 function call model analysis
X86 function call model analysis
2022-08-03 19:03:00 【mingjie】
相关: 《Postgresql中的pg_memory_barrier_impl和C的volatile》《X86Function call model analysis》
函数A调用函数B,BContinue to execute the function after executionA,How to implement such a call?
Direct thinking may involve the following steps:
- AThe local variables if in registers,需要保存起来.
- These variables are kept on the stack,The position on the stack needs to be recorded.
- If there are multiple layers of calls, there will be multiple sets of information to record the stack location,Records are also required.
- A调用完BNeed to continue after that,The position to continue execution needs to be saved.
下面分析x86的具体实现. (资料汇编)
速查:
- For stack frames:Used at the top of the stack framebp指针(高地址),栈帧底部(低地址)用sp指针.
- 对于堆栈来说:The top of the overall stack is sp指针(The lowest address to which the stack grows).
一、内存结构
The memory structure of the binary program execution time:
- code section:The machine code that holds the program execution instructions.
- static section:Constants and static variables that do not change during program execution.
- heap:使用malloc申请的堆内存,向Memory addresses grow in ascending order:grows up.
- stack:Holds control information for function local variables and function calls,向Memory addresses grow in descending order:grows down.
二、寄存器
- The program's virtual memory space is provided
space to save data,地址从0x00000000到0xFFFFFFFF(A hexadecimal for the corresponding4个二进制位,所以是2的32次方).
- Registers provide additional storage space,Each register can hold one word(4字节).
Registers associated with function calls(emeans to expand):
- eip:指令指针,Stores the address of the currently executing machine instruction.也叫PC(程序计数器).
- ebp:帧指针,Save the top address of the current stack frame(高地址).
- esp:堆栈指针,Save the current stack bottom address(低地址).
The diagram below is easy to understand:
|----------------------| high address
| ... |
|-------frame----------|
| ... |
| ... |
| ... |
|-------frame----------| # current frame <----- ebp
| ... |
| ... |
| ... | <----- esp
|----------------------| low address
三、x86函数调用
- when another function needs to be called,Stack space needs to grow,Used to save some local variables 或者 寄存器信息.
- when calling a function happens,callerThe execution logic will jump tocallee,拿到结果后,In the jump willcaller.This requires changing the values of the following registers:
- eip指令指针,Need to be changed to point tocallee的指令.
- ebp 和 esp currently point to respectivelycallerThe top and bottom of the stack frame.Both registers need to be updated as 指向calleeThe top and bottom of the new stack frame.
- 当函数返回时,The old value in the register needs to be restored,才可以返回caller.So update the value of the register,It needs to save its old value on the stack,in order to restore the old value after the function returns.
下面是main调用foo的执行过程:
step0
step1:参数入栈
将参数压入堆栈. x86Pass parameters by pushing them on the stack.请注意,When we push parameters onto the stack,esp 会递减.Arguments are pushed onto the stack in reverse order.(上面是高地址)
step2:旧的eip入栈
旧的eip(rip)压入堆栈.Jump to subfunction executioneipNeed to point to subfunction,So save it here.
step3:修改eip指向
已经保存了 eip 的旧值,可以安全地将 eip Change to point to becallee的指令.
step4:将旧的ebp入栈
step5:ebpMove down to point to the top of the new stack frame
这就是mov %esp %ebp
的含义:
step6:esp向下移动
通过sub esp
(esp地址–) to allocate new space for the new stack frame.The compiler determines based on the complexity of the function esp How much should be reduced.
- 例如,A function with only a few local variables doesn't need much stack space,因此 esp It will only reduce a few bytes.
- 例如,If a function declares a large array as a local variable,那么 esp would reduce a lot to fit the array on the stack.
step7:执行callee
The function's local variables and jump control information are now stored on the stack;由于ebp指向栈帧的顶部,所以可以用ebp+8Find where the first parameter is saved.
step8:返回espback to the top of the stack
step9:恢复旧的ebp
使用esp从堆栈中pop出一个值(old ebp),把old ebp的值赋给ebp.
step10:弹出eip
继续使用esp弹出old eip的值赋给eip.
step11:Remove the parameter from the stack
Continue talking about popping parameters on the stack into registers,然后删除espThe element below the top of the stack.Elements below the top of the stack are no longer on the stack,没有意义.
四、实例分析
int main(void) {
foo(1, 2);
}
void foo(int a, int b) {
int bar[4];
}
gcc -O0 t.c -o t -g
main执行过程
(gdb) disassemble /rm
Dump of assembler code for function main:
3 int main(void) {
# 由_start调入main函数
0x0000000000401122 <+0>: 55 push %rbp # The top of the stack frame is pushed onto the stack
0x0000000000401123 <+1>: 48 89 e5 mov %rsp,%rbp # Pointer to the top of the stack framerbpPoints to the top of the new stack frame
4 foo(1, 2);
=> 0x0000000000401126 <+4>: be 02 00 00 00 mov $0x2,%esi # 参数1passed into the register
0x000000000040112b <+9>: bf 01 00 00 00 mov $0x1,%edi # 参数2passed into the register
0x0000000000401130 <+14>: e8 07 00 00 00 callq 0x40113c <foo> # push %rip 然后 jmpq
# push %rip 等价与 sub $0x8, %rsp
# mov $rip, %rsp
0x0000000000401135 <+19>: b8 00 00 00 00 mov $0x0,%eax
5 }
0x000000000040113a <+24>: 5d pop %rbp # 先恢复rbp的值
0x000000000040113b <+25>: c3 retq # 在恢复rip的值 popq %rip
End of assembler dump.
foo函数
(gdb) disassemble /rm
Dump of assembler code for function foo:
7 void foo(int a, int b) {
0x000000000040113c <+0>: 55 push %rbp # Frame top position 入栈
0x000000000040113d <+1>: 48 89 e5 mov %rsp,%rbp # rbpframe top pointer,Point to the top of the new frame
0x0000000000401140 <+4>: 89 7d ec mov %edi,-0x14(%rbp) # 参数2入栈(Push the last parameter onto the stack first)
0x0000000000401143 <+7>: 89 75 e8 mov %esi,-0x18(%rbp) # 参数1入栈
8 int bar[4];
9 }
=> 0x0000000000401146 <+10>: 90 nop
0x0000000000401147 <+11>: 5d pop %rbp # 先恢复rbp的值
0x0000000000401148 <+12>: c3 retq # 在恢复rip的值 popq %rip
End of assembler dump.
边栏推荐
- 2022/08/02------Ugly number
- Compose原理-compose中是如何实现事件分法的
- YAML中多行字符串的配置方法:|+、 |、 |-、 >+、 >、 >-的区别
- Shell:循环语句
- 使用安全浏览器将网页保存为pdf的方法步骤
- Cobalt Strike (CS) 逆向初探
- Big guy, who is free to help me to see what the problem is, I just read MySQL source print, and I just came into contact with flink.
- 货比四家 version tb1.63
- Unity获取canvas 下ui 在屏幕中的实际坐标
- OneNote 教程,如何在 OneNote 中设置页面格式?
猜你喜欢
随机推荐
梅科尔工作室-14天华为培训七
BinaryIndexedTrees树状数组
OSError: [WinError 123] 文件名、目录名或卷标语法不正确
MYSQL误删数据恢复
深度学习常用公式与命令总结(更新中)
阿里巴巴政委体系-第六章、阿里政委体系运作
【微信小程序】NFC 标签打开小程序
dd命令:用于读取、转换并输出数据
阿里巴巴政委体系-第七章、阿里政委培育
Unity获取canvas 下ui 在屏幕中的实际坐标
X86函数调用模型分析
Word另存为PDF后无导航栏解决办法
不要小看 WebSocket!长连接、有状态、双向、全双工都是王炸技能
POJ 2377 Bad Cowtractors(最大生成树)
ctfshow php features
G6尝试 学习
2022/08/02------Ugly number
ScrollView嵌套RV,滑动有阻力不顺滑怎么办?
Compose原理-compose中是如何实现事件分法的
docker mysql 容器中执行mysql脚本文件并解决乱码