深入理解Ghidra反汇编中的栈帧结构
1. 函数调用约定与系统调用
在程序开发中,函数调用约定至关重要。若函数仅用于程序内部,优化编译器可能会选择替代调用约定以生成更快的代码。例如,在Microsoft C/C++中使用 /GL 选项可执行“全程序优化”,实现跨函数边界的寄存器优化使用;在GNU gcc/g++中使用 regparm 关键字,程序员可指定最多三个参数通过寄存器传递。
当使用汇编语言编写代码时,程序员能完全控制参数传递方式。除非希望函数供其他程序员使用,否则汇编语言程序员可自由选择合适的参数传递方式。因此,分析自定义汇编代码(如混淆例程和shellcode)时需格外小心。
系统调用是一种特殊的函数调用,用于请求操作系统服务。通常会引发从用户模式到内核模式的状态转换,以让操作系统内核处理用户请求。不同操作系统和处理器启动系统调用的方式有所不同。例如,32位Linux x86系统调用可使用 INT 0x80 指令或 sysenter 指令,其他x86操作系统可能仅使用 sysenter 指令或其他中断号,64位x86代码则使用 syscall 指令。在许多x86系统(Linux除外)中,系统调用的参数放在运行时栈上,系统调用号在启动系统调用前放入 EAX 寄存器。Linux系统调用的参数则放在特定寄存器中,参数过多时会使用内存。
2. 栈帧相关考虑
在任何处理器中,寄存器是有限资源,程序中的所有函数需共享。当一个函数(
超级会员免费看
订阅专栏 解锁全文
21

被折叠的 条评论
为什么被折叠?



