惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

阮一峰的网络日志
阮一峰的网络日志
C
Cyber Attacks, Cyber Crime and Cyber Security
P
Privacy & Cybersecurity Law Blog
Cloudbric
Cloudbric
GbyAI
GbyAI
T
Threatpost
Google DeepMind News
Google DeepMind News
Jina AI
Jina AI
The Hacker News
The Hacker News
Y
Y Combinator Blog
Blog — PlanetScale
Blog — PlanetScale
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
I
Intezer
美团技术团队
S
Schneier on Security
I
InfoQ
Project Zero
Project Zero
S
SegmentFault 最新的问题
IT之家
IT之家
C
CXSECURITY Database RSS Feed - CXSecurity.com
C
CERT Recently Published Vulnerability Notes
博客园 - 司徒正美
Security Latest
Security Latest
G
Google Developers Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Cisco Talos Blog
Cisco Talos Blog
L
LINUX DO - 最新话题
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
L
Lohrmann on Cybersecurity
G
GRAHAM CLULEY
Engineering at Meta
Engineering at Meta
L
LangChain Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
C
Cisco Blogs
大猫的无限游戏
大猫的无限游戏
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Apple Machine Learning Research
Apple Machine Learning Research
雷峰网
雷峰网
V
V2EX
The Register - Security
The Register - Security
A
Arctic Wolf
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Tor Project blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Microsoft Security Blog
Microsoft Security Blog
Stack Overflow Blog
Stack Overflow Blog
Vercel News
Vercel News
Spread Privacy
Spread Privacy
H
Help Net Security
H
Heimdal Security Blog

MoonLab

VSCode + OpenOCD 远程调试开发STM32 Clangd + VSCode使用方法 Keil5 编译错误 error: call to undeclared function '__enable_irq' BTSNOOP is FUN! 算法 - 前缀和 2025蓝桥杯赛后总结 三星ZFold 3改造 JavaScript 逆向 Steam 登录二维码 快速求解平方根倒数算法 Protobuf Android设备安装Debian成为BT下载服务器 [双系统] Windows 更新摧毁了我的Linux系统 Reading List Golang embed 使用问题 Hexo博客自动备份插件 云盘备份支持 Git push 出现 permisson denied error 403 坑:Litepal save方法返回true却没有保存 Android Shizuku源码分析 第二篇 Android Shizuku源码分析 Android 监听第三方Activity的一举一动 Android笔记#1 View的事件分发机制解析 知乎日报的问题 使用Hexo Hello World Ubnutu 无法启动网易云音乐 - 总结 Windows 好软推荐 | 这一定是良心软件 typecho - http转https 如何评价Android P MoonLab MoonLab MoonLab 关于 项目
通过汇编分析栈、函数调用 esp&ebp
LingC · 2023-12-15 · via MoonLab

📦 由AI生成的摘要
栈是一种遵循后进先出(LIFO)规则的数据结构,通常用于内存管理。重要寄存器包括栈指针(SP)和基指针(BP)。在函数调用中,使用`push`将参数压入栈中,`call`指令保存返回地址。ESP寄存器指向栈顶,函数执行后需平衡栈。C语言函数调用中,参数通过EBP寻址,编译器可能使用`mov`而非`push`,使得ESP不指向栈顶,简化栈平衡的处理。

栈 Stack

栈是一种数据结构,遵循Last in, First out (LIFO)规则,栈在中文语境中有时也被叫做堆栈。在实际中,是一片内存空间。

IMG

在栈中,有两个重要的寄存器

SP (Stack Pointer)

BP (Base Pointer)

在16位系统中是这样的,在32位系统中分别叫做esp ebp,在64位中

栈是从高地址向低地址搭起来的,因此栈顶位于低地址,栈底位于高地址。一般来说是这样,当然你的程序也可以不这样做,主打一个叛逆。

ESP 函数调用

要理解栈和那两个有关栈的寄存器,可以通过函数调用来理解。

以下是x86 32bit的汇编程序。

push 1
push 2
call 002110D
add esp,8
nop
; this func will add up a and b
mov eax,dword ptr [esp+4]
add eax,dword ptr [esp+8]
ret

其中push操作码不仅会将参数压入栈中,还会使esp寄存器的值减4,即sub esp,#4。以确保esp始终指向栈顶。

call首先会用push来把下一个操作码的地址压入栈中,这个地址叫做返回地址,然后跳转到函数所在的地址。

在进入到func后,此时esp指向之前call所压入栈内的地址。就可以直接通过exp+4向下拿到参数。

执行完函数后,就需要考虑栈平衡了。要让调用函数后的栈和调用函数前的保存一致。

ret 跳转到返回地址,执行add esp,8 清除栈内的函数参数。

EBP 函数调用

但分析C语言的函数调用,会发现与上文的esp寻址有些不同,一般是用ebp来进行参数的寻址。

int add(int a, int b) {
    return a + b;
}

int main() {
    add(1, 2);
    return 0;
}

这是一段简单的C代码,用gcc将其编译成32位可执行文件

gcc -m32 -o main main.c

对于Windows 64 bit要想编译32位程序,如果MinGW的exception model是SEH,那么可以用i686-w64-mingw32-gcc来编译32位程序

对main.exe进行反汇编

AEM1

在上图中可以看到,在调用call前,先处理两个参数,但这里因为编译器等等问题使用了mov而不是push,实现的效果也是一样的。这里没有用push的区别就是esp没有始终指向栈顶,,所以也不用考虑栈平衡了。

AEM2

这里就是通过ebp来使用两个形参,分别赋到了EDX, EAX。然后EAX储存函数返回值。


Refs

https://blog.csdn.net/song_lee/article/details/105297902