逆向-beginners之栈

#if 0

栈是最基础的数据结构之一。

从技术上说,栈就是CPU寄存器里的某个指针所指向的一片内存区域。这里所说的"某个指针"通常位于x86/x64平台的ESP/RSP,ARM的SP。

操作栈的最常见的指令是push/pop。

push 会对ESP/RSP/SP的值进行减法运算,使之减去 4(32 bit)或 8(64 bit),然后将操作数写到上述寄存器里的指针所指向的内存中。

pop 先从栈指针(stack pointer)指向的内存中读取数据,用以备用(通常是写到其他寄存器里),然后再将栈指针的数值加上 4 或 8 。

在分配栈的空间之后,栈指针,即stack pointer所指向的地址是栈的底部。push 将减少栈指针的数值,而 pop 会增加它的数值。

栈的"底"实际上使用的是整个栈的最低地址,即是整个栈的启动内存地址。

/*

* 栈的用途

*/

1.保存函数结束时的返回地址

/* x86 */

当程序使用call调用其他函数时,call指令结束后的返回地址将被保存在栈里;

在call所调用的函数结束之后,程序将执行无条件跳转指令,跳转到这个返回地址。

call 等价于 "PUSH 返回地址" 和 "JMP 函数地址" 的指令对。

被调用函数里的RET指令,会从栈中读取返回地址,然后跳转到这个地址,就相当于"POP 返回地址" + "JMP 返回地址"指令。

栈是有限的,溢出它很容易。直接使用无限递归,本就会满。

/* arm */

ARM程序也使用栈保存返回地址,只是略有不同。程序的返回地址保存在LR里。但是,如果程序还会继续调用其他函数,就需要在调用函数

之前保存LR的值。通常,函数会在启动过程中(序言处)保存LR的值。通常在函数序言处看到"push R4-R7,LR", 并在尾声处看到

"pop R4-R7, PC"。这些指令会对函数自身将要用到的寄存器进行保护,把它们的值放在栈中---也包括LR。

如果一个函数不调用其他函数,它就像对上的枝杈末端的叶子那样。这种函数就叫作"叶函数(leaf function)"。叶函数的特点是,它不必

保存LR的值。如果叶函数的代码短到用不到几个寄存器,那么它可能根本不会使用数据栈。所以,调用叶函数的时候确实可能不会涉及栈

操作。这种情况下,因为这种代码不在外部内存RAM进行与栈有关的操作,所以它的运行速度有可能超过X86系统。在没有分配栈或者不可能用栈的时候,这类函数就会显现出优势。

2.参数传递

esp + 4 : 返回地址

esp + 8 : 参数一

ese + c : 参数二

ese + 10 : 参数三

3.存储局部变量

4.alloca

alloca函数直接使用栈来分配内存,除此之外,它与malloc没有显著区别。用完退出,自动释放。

/*

* 栈的噪音

*/

原有栈空间里的局部变量不会被自动清除,就成为了噪音或脏数据了。

#endif

void main()

{}

相关推荐
ThornArmor5 小时前
重铸1996|肉体渲染:关节的裂缝:分段模型积木拼装与未成熟的 RSP 矩阵骨骼动画形变
c语言·汇编·c++·python·硬件架构·游戏机
星栖与芯8 小时前
LiteOS-M 切换汇编逐行图解(1):汇编是什么·寄存器与栈
汇编·stm32·嵌入式硬件·harmonyos·鸿蒙系统
yume_sibai11 小时前
11-Rust 不安全编程(unsafe 关键字 + 裸指针 + FFI + 内联汇编 + 内存安全保证)
汇编·安全·rust
小杨不想秃头3 天前
信息安全工程师 历年真题原题汇编(2016–2025)
汇编
2601_9622965112 天前
C/C++:编译全过程——预处理、编译、汇编、链接(包含预处理指令:宏定义,文件包括、条件编译)
汇编·预处理·链接·c/c++·编译过程
Freak嵌入式12 天前
Pico PIO 汇编语法深度详解:标识符、指令、伪指令全解析
汇编·stm32·单片机·嵌入式硬件·fpga开发·硬件架构
kyle~18 天前
x86 汇编LOCK前缀 --- 硬件架构向软件提供的核心同步原语
汇编·c++·性能优化·硬件架构·实时系统
典典分享指南18 天前
飞书 + 企业微信 + 微信文档多端协同实践指南
汇编·flask·intellij-idea·fastapi
极客互动API23 天前
企业微信 iPad 协议服务搭建与 AI 回调实战
网络·汇编·人工智能·微信·企业微信·ipad
wechatbot8881 个月前
极客互动企业微信 SCRM 私域运营实战效果全景
大数据·汇编·微信·自动化·企业微信·rpa