逆向:x,x从汇编分析函数调用约定详解
逆向x86/x64从汇编分析函数调用约定详解引言函数调用约定是程序运行时函数间传递参数、控制权和返回值的一套规则。在逆向工程中理解调用约定是分析二进制代码的基础。x86和x64架构的调用约定存在显著差异本文将深入剖析从汇编层面分析这些约定的原理并提供可运行的代码示例。## 1. 调用约定的核心要素调用约定主要解决三个问题- 参数如何传递寄存器/栈- 栈的清理责任调用者/被调用者- 返回值的存放位置常见的调用约定包括cdecl、stdcall、fastcallx86以及Microsoft x64和System V AMD64x64。## 2. x86架构调用约定分析### 2.1 cdecl约定C语言默认在cdecl中参数从右向左压入栈调用者负责清理栈。让我们通过汇编分析c// 示例代码cdecl_test.c#include stdio.hint __attribute__((cdecl)) add(int a, int b, int c) { return a b c;}int main() { int result add(1, 2, 3); printf(Result: %d\n, result); return 0;}编译并查看汇编使用gcc -S或objdump反汇编assembly; add函数的汇编ATT语法add: pushl %ebp movl %esp, %ebp movl 12(%ebp), %eax ; 加载b参数2 movl 8(%ebp), %edx ; 加载a参数1 addl %edx, %eax ; a b addl 16(%ebp), %eax ; c popl %ebp ret; main函数的汇编main: pushl $3 ; 参数c最后压栈 pushl $2 ; 参数b pushl $1 ; 参数a先压栈 call add addl $12, %esp ; 调用者清理栈3个int 12字节关键点- 参数从右向左压栈pushl $3-pushl $2-pushl $1- 调用者清理栈addl $12, %esp恢复栈指针- 返回值通过eax传递### 2.2 stdcall约定Windows API常见stdcall与cdecl类似但被调用者负责清理栈assembly; stdcall约定下的add函数add_std: pushl %ebp movl %esp, %ebp movl 12(%ebp), %eax addl 8(%ebp), %eax addl 16(%ebp), %eax popl %ebp ret $12 ; 被调用者清理ret指令后加12字节; 调用方式 pushl $3 pushl $2 pushl $1 call add_std ; 无需清理栈因为add内部已经ret $12区别ret $12指令在返回前自动弹出12字节3个参数调用者无需addl。### 2.3 fastcall约定寄存器传参fastcall使用ecx和edx传递前两个参数其余通过栈传递c// fastcall_test.c#include stdio.hint __attribute__((fastcall)) fast_add(int a, int b, int c) { return a b c;}int main() { int result fast_add(10, 20, 30); printf(Result: %d\n, result); return 0;}汇编分析assemblyfast_add: pushl %ebp movl %esp, %ebp pushl %ebx movl %ecx, %ebx ; 参数a在ecx movl %edx, %eax ; 参数b在edx addl %ebx, %eax ; a b addl 8(%ebp), %eax ; 参数c在栈上 popl %ebx popl %ebp retmain: pushl $30 ; 第三个参数压栈 movl $20, %edx ; 第二个参数在edx movl $10, %ecx ; 第一个参数在ecx call fast_add addl $4, %esp ; 只清理栈上的一个参数## 3. x64架构调用约定### 3.1 Microsoft x64约定Windowsx64下参数通过寄存器传递rcx, rdx, r8, r9前4个整数剩余通过栈传递。调用者负责预留影子空间shadow space。c// x64_test.c#include stdio.hint add_x64(int a, int b, int c, int d, int e) { return a b c d e;}int main() { int result add_x64(1, 2, 3, 4, 5); printf(Result: %d\n, result); return 0;}x64汇编Windows环境assemblyadd_x64: push rbp mov rbp, rsp ; rcx a, rdx b, r8 c, r9 d ; 第五个参数e在栈上rbp0x30因为影子空间占用32字节 mov eax, ecx add eax, edx add eax, r8d add eax, r9d add eax, [rbp0x30] ; 从栈加载e pop rbp retmain: sub rsp, 40 ; 预留影子空间32字节 对齐 mov dword [rsp32], 5 ; 第五个参数在栈上 mov r9d, 4 ; 第四个参数 mov r8d, 3 ; 第三个参数 mov edx, 2 ; 第二个参数 mov ecx, 1 ; 第一个参数 call add_x64 add rsp, 40 ; 返回值在eax### 3.2 System V AMD64约定Linux/macOS前6个整数参数通过rdi, rsi, rdx, rcx, r8, r9传递无需影子空间assembly; Linux x64汇编add_linux: ; rdi a, rsi b, rdx c, rcx d ; 第五个参数e在栈上 mov eax, edi add eax, esi add eax, edx add eax, ecx mov rcx, [rsp8] ; 第五个参数在rsp8返回地址上方 add eax, ecx retmain: push 5 ; 第五个参数 mov ecx, 4 ; 第四个参数 mov edx, 3 ; 第三个参数 mov esi, 2 ; 第二个参数 mov edi, 1 ; 第一个参数 call add_linux add rsp, 8 ; 清理栈上的参数## 4. 逆向分析实战识别调用约定在逆向二进制代码时可以通过以下特征识别调用约定### 4.1 分析栈清理方式python# 模拟逆向分析脚本def analyze_calling_convention(assembly_lines): 分析调用约定 insns [line.strip() for line in assembly_lines] # 检查call指令后是否有add esp, X has_caller_cleanup False for line in insns: if call in line and ret in line.split(,)[-1]: # 被调用者清理stdcall return stdcall if add in line and esp in line and call in insns[insns.index(line)-1]: has_caller_cleanup True if has_caller_cleanup: return cdecl return unknown# 测试cdecl_code [ push 3, push 2, push 1, call add, add esp, 12 # 调用者清理]print(analyze_calling_convention(cdecl_code)) # 输出: cdecl### 4.2 识别寄存器传参pythondef detect_fastcall(assembly): 检测fastcall检查ecx/edx是否用于传参 ecx_used False edx_used False for line in assembly: if mov in line and ecx in line and push not in line: ecx_used True if mov in line and edx in line and push not in line: edx_used True return ecx_used and edx_used# x86 fastcall示例fastcall_code [ push 30, # 第三个参数 mov edx, 20, # 第二个参数 mov ecx, 10, # 第一个参数 call fast_add]print(detect_fastcall(fastcall_code)) # 输出: True## 5. 调用约定对比总结| 特性 | cdecl (x86) | stdcall (x86) | fastcall (x86) | MS x64 | SysV x64 ||------|-------------|---------------|----------------|--------|----------|| 参数传递 | 栈右→左 | 栈右→左 | ecx/edx 栈 | rcx,rdx,r8,r9 栈 | rdi,rsi,rdx,rcx,r8,r9 栈 || 栈清理 | 调用者 | 被调用者 | 调用者栈部分 | 调用者 | 调用者 || 返回值 | eax | eax | eax | rax | rax || 影子空间 | 无 | 无 | 无 | 32字节 | 无 |## 总结函数调用约定是逆向工程中必须掌握的基础知识。通过分析汇编代码我们可以从三个维度识别调用约定参数传递方式寄存器vs栈、栈清理责任方调用者vs被调用者、以及影子空间的使用仅x64 Windows。在实际逆向中cdecl和stdcall通过ret指令后是否带立即数区分fastcall通过检查ecx/edx的初始赋值识别x64下则需观察寄存器的使用顺序和栈布局。掌握这些技术能够帮助我们准确理解二进制代码的函数交互逻辑为后续的逆向分析打下坚实基础。

相关新闻

Matplotlib子图实战:从基础布局到复杂仪表板构建

Matplotlib子图实战:从基础布局到复杂仪表板构建

1. 项目背景与核心价值:为什么子图是数据可视化的“骨架”如果你用过Matplotlib画过几张图,大概率会遇到一个非常现实的问题:当你想把几个相关的图表放在一起对比分析时,一张图一张图地单独生成,再手动拼接到PPT或报告…

2026/10/13 19:32:04 阅读更多 →
计算机毕业设计之表务管理系统

计算机毕业设计之表务管理系统

随着新经济的需求和新技术的发展,特别是网络技术的发展,如果可以建立起表务管理系统,可以改变传统线下管理方式,在过去的时代里都使用传统的方式实行,既花费了时间,又浪费了精力。在信息如此发达的今天&…

2026/10/13 0:52:29 阅读更多 →
计算机毕业设计之便捷线上办公系统

计算机毕业设计之便捷线上办公系统

网络技术的快速发展给各行各业带来了很大的突破,也给各行各业提供了一种新的管理模块,对于便捷线上办公将是又一个传统管理到智能化信息管理的改革,设计便捷线上办公系统的目的就是借助计算机让复杂的部门信息操作变简单,变高效。…

2026/10/13 1:30:08 阅读更多 →

最新新闻

办公设备管理系统OAMS源码实战:从台账混乱到扫码即用

办公设备管理系统OAMS源码实战:从台账混乱到扫码即用

简介:办公设备管理系统OAMS是一套面向企事业单位设备管理员与信息化开发者的全生命周期管理解决方案,覆盖采购、入库、领用、维修、报废等核心环节,适合需要落地资产台账、审批流程与统计报表的Java Web项目学习与二次开发。资源包共451个文件…

2026/10/14 4:00:41 阅读更多 →
SpringBoot2+Vue3流浪宠物管理系统:前后端分离架构实战解析

SpringBoot2+Vue3流浪宠物管理系统:前后端分离架构实战解析

1. 这个系统解决的是什么问题:流浪宠物救助的数字化盲区说实话,市面上打着"宠物管理系统"旗号的项目源码并不少,但真正能落地到流浪动物救助场景的却不多。大部分所谓管理系统要么是单纯的前端页面堆砌,要么后端只做了简…

2026/10/14 4:00:41 阅读更多 →
Matlab实现CNN-GRU多特征分类预测:从数据准备到模型落地

Matlab实现CNN-GRU多特征分类预测:从数据准备到模型落地

涉及到用Matlab做时序或者多维特征数据的分类预测时,CNN-GRU这个组合近年来出镜率非常高。一方面卷积结构擅长局部特征提取,另一方面GRU门控循环单元对序列依赖关系的建模能力又比普通前馈网络强很多,两个搭在一起后,既能处理多维…

2026/10/14 4:00:41 阅读更多 →
Claude Code + git worktree 多分支并行开发实战指南

Claude Code + git worktree 多分支并行开发实战指南

最近半年我一直在重度使用 Claude Code 做日常开发,手头同时维护好几个功能分支是常有的事。一开始我还是老一套:开一个终端窗口,在一个工作目录里反复git checkout切换分支,切来切去不仅脑子乱,更麻烦的是 Claude Cod…

2026/10/14 4:00:41 阅读更多 →
中小团队 CI/CD 工具选哪个:2026 年主流平台对比与 Gitee 方案解析

中小团队 CI/CD 工具选哪个:2026 年主流平台对比与 Gitee 方案解析

中小团队选择 CI/CD 工具的核心结论是:没有"最好"的工具,只有匹配团队规模、技术栈与合规要求的方案;据 JetBrains 2025 年开发者生态系统报告,GitHub Actions 以 33% 采用率领跑,Jenkins 以 28% 紧随其后&a…

2026/10/14 4:00:41 阅读更多 →
从零构建每日晨报:信息过滤系统的设计与实现

从零构建每日晨报:信息过滤系统的设计与实现

1. 一份“每日晨报”到底在解决什么问题每天早上七点半,我习惯性打开自己维护的一个小工具,屏幕上会弹出一份排版干净的简报:昨天圈子里发生了什么、有哪些值得点进去看的链接、今天有什么值得留意的节点。这份东西我管它叫“每日晨报”&…

2026/10/14 3:59:41 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →