C/C++逆向:函数逆向分析-调用约定分析

news2024/11/25 18:27:24

在进行函数逆向分析时,分析其函数调用约定具有非常重要的作用,因为调用约定直接影响了函数的参数传递、返回值、栈管理、寄存器使用等多个方面,不同的编译器和平台可能有不同的默认调用约定,识别调用约定可以帮助判断代码是由哪种编译器生成的。例如:

①Windows API 函数通常使用 stdcall 调用约定。
②在 x64 平台,Windows 使用的调用约定与 Linux 的 System V 调用约定有所不同。
③通过调用约定,可以更好地识别代码的上下文,甚至推断出目标程序使用的编译器和编译选项。

调用约定描述了函数调用和参数传递的方式,掌握这些约定是正确分析函数的基础,常见的调用约定如下:

cdecl:参数通过栈从右向左传递,调用者负责清理栈。
stdcall:参数通过栈从右向左传递,函数本身负责清理栈。
fastcall:部分参数通过寄存器传递,通常第一个和第二个参数通过 ecx 和 edx 寄存器传递(在windows x86 平台上),剩余参数从右到左压入栈中。 (在 Windows x64 平台上,前四个参数使用 rcx, rdx, r8, r9 寄存器传递。)函数可能负责栈的清理,具体情况与实现相关。

下面是一个 C 代码的示例,通过使用 cdeclstdcallfastcall 三种调用约定来演示它们的区别。在代码中,我们使用 Microsoft 编译器提供的关键字来指定不同的调用约定:

#include <stdio.h>
​
// 使用 cdecl 调用约定
int __cdecl add_cdecl(int a, int b) {
    return a + b;
}
​
// 使用 stdcall 调用约定
int __stdcall add_stdcall(int a, int b) {
    return a + b;
}
​
// 使用 fastcall 调用约定
int __fastcall add_fastcall(int a, int b) {
    return a + b;
}
​
int main() {
    int x = 3;
    int y = 4;
​
    // 调用 cdecl 函数
    int result_cdecl = add_cdecl(x, y);
    printf("cdecl result: %d\n", result_cdecl);
​
    // 调用 stdcall 函数
    int result_stdcall = add_stdcall(x, y);
    printf("stdcall result: %d\n", result_stdcall);
​
    // 调用 fastcall 函数
    int result_fastcall = add_fastcall(x, y);
    printf("fastcall result: %d\n", result_fastcall);
​
    return 0;
}

接下去我们将代码进行编译,生成exe文件后放入x32dbg中进行动态调试,去具体分析这三种调用约定的区别。

在文件载入完毕后,我们需要先进行main函数的定位(定位main函数的方法请看笔者前面C/C++逆向:定位main函数文章);此时我们需要重点关注的是红线以下代码。

mov dword ptr ss:[ebp-8],3
mov dword ptr ss:[ebp-14],4

代码中首先初始化了两个四字节(dword ptr)的局部变量ebp-8ebp-14;这两个局部变量就对应上述C代码中的两个int型变量x(ebp-8)y(ebp-14)

①cdecl调用约定

相关代码如下:

mov eax,dword ptr ss:[ebp-14]
push eax
mov ecx,dword ptr ss:[ebp-8]
push ecx
call function_x86.281050
add esp,8

这串代码首先将局部变量ebp-14(y)的值加载到eax中,接着将 eax 寄存器中的值压入栈中,这是即将调用函数的第一个参数。然后将另一个局部变量ebp-8(x)的值加载到 ecx 寄存器中;将 ecx 寄存器中的值压入栈中,作为调用函数的第二个参数,接着通过call指令调用名为 function_x86.281050 的函数。通过对比上述的函数调用C代码;

int result_cdecl = add_cdecl(x, y);

cdecl调用约定在进行参数传递时,调用函数所使用的参数是从右到左推入栈中,正如这个例子所展现的,我们调用函数add_cdecl(x, y)时,反汇编代码中先压入栈中的参数是ebp-14(y),接着才是x。并且在调用函数完毕后需要由调用者来恢复栈指针;add esp,8调用函数后,恢复栈指针。因为调用之前压入了两个参数,每个 4 字节,共计 8 字节,所以通过 add esp, 8 来调整栈指针,清理掉这些参数。

②stdcall调用约定

相关代码:

mov eax,dword ptr ss:[ebp-14]
push eax
mov ecx,dword ptr ss:[ebp-8]
push ecx
call function_x86.281235

可以看到stdcallcdecl调用约定一样,都是从右往左依次将参数压入栈中,但是与cdecl不一样的是,stdcall的平栈操作是在函数内完成的。这个时候我们进入函数function_x86.281235进行查看:

我们可以看到在函数结尾有一个ret 8指令;该指令在 x86 汇编中表示返回到调用函数的地址,并在返回之前从栈中移除 8 个字节,这是一种同时进行函数返回和栈清理的指令。

③fastcall调用约定

相关代码:

mov edx,dword ptr ss:[ebp-14]
mov ecx,dword ptr ss:[ebp-8]
call function_x86.2810F5

fastcall 调用约定中,部分参数通过寄存器传递,而不是全部通过栈来传递。在该程序的函数调用中,第一个ebp-8(x)和第二个参数ebp-14(y)分别通过 ecxedx 寄存器传递,接着使用call指令调用函数即可。若有更多参数,超出寄存器能够处理的范围,这些额外的参数会被压入栈中;对于通过栈传递的额外参数,栈的清理方式可以与 stdcall 类似,即由被调用者来负责清理栈上的参数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2190522.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTB:Mongod[WriteUP]

连接至HTB服务器并启动靶机 靶机IP&#xff1a;10.129.99.33 分配IP&#xff1a;10.10.16.12 1.How many TCP ports are open on the machine? 使用nmap对靶机进行全端口TCP脚本、服务扫描&#xff1a; nmap -sC -sV -T4 -p- {TARGET_IP} 可以看到靶机共开放TCP端口2个&…

LC108-将有序数组转化为二叉搜索树(二叉平衡树)

文章目录 1 题目2 思路3 ACM完整代码参考 1 题目 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 平衡二叉搜索树 示例&#xff1a; 输入&#xff1a;nums [-10,-3,0,5,9] 输出&#xff1a;[0,-3,9,-10,null,5] 解释&#xff1…

最佳语音识别 Whisper-large-v3-turbo 上线,速度更快(本地安装 )

Openai 上线语音模型whisper-large-v3-turbo 在本文中&#xff0c;我们将介绍 whisper-large-v3-turbo 以及 whisper-web&#xff08;一个直接在浏览器中进行ML语音识别的开源项目&#xff09;。 尽管近年来出现了许多音频和多模态模型&#xff0c;但Whisper 仍是生产级自动语音…

类型模板参数与非类型模板参数

在C中&#xff0c;模板参数分为两种类型&#xff1a;类型参数和非类型参数。类型参数是指定模板类型名称的参数&#xff0c;而非类型参数是指定模板整型常量的参数。 模板参数不限定于类型&#xff0c;普通值也可作为模板参数&#xff0c;但这里值的类型只能是整形家族&#x…

Qt教程(001):Qt概述与安装

文章目录 一、Qt概述1.1 什么是Qt1.2 Qt优点1.3 Qt发展史1.4 支持的平台1.5 成功案例1.6 下载安装1.7 QtCreator介绍 一、Qt概述 1.1 什么是Qt Qt是一个跨平台的C图形用户界面应用程序框架。它为应用程序开发者提供建立艺术级图形界面所需的所有功能。它是完全面向对象的&…

快乐数(c语言)

1.「快乐数」 定义为&#xff1a;对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变不到 1。如果这个过程 结果为 1&#xff0c;那么这个数就是快乐数。如果 n 是 快乐数 就返…

打卡第三天 P5729 【深基5.例7】工艺品制作

今天是我打卡第三天&#xff0c;做个入门题吧(#^.^#) 题目描述 输入格式 输出格式 输出一个整数表示答案。 输入输出样例 输入 #1 4 4 4 1 1 1 1 2 2 2 输出 #1 56 说明/提示 C&#xff1a; #include<bits/stdc.h> using namespace std; long long a[100][100][1…

【ubuntu】修改用户名、主机名、主文件夹名、登录名、密码

目录 1.他们是什么 2.修改方法 2.1 修改用户密码 2.2 修改主机名 2.2.1 切换到root用户 2.2.2 修改名称 2.3 修改用户名 主文件夹名 登录名 2.2.1 sudoers 2.2.2 passwd 2.2.3 shadow 2.2.4 group 2.2.5 修改主文件夹名 3.重启 1.他们是什么 &#xff08;1&#xf…

初识 C 语言(2)

目录 一、sigined 和 unsigned1. unsigned 二、数据类型的取值范围三、变量的分类1. 局部变量2. 全局变量3. 全局变量和局部变量名称冲突 四、算数操作符1. 加法操作符&#xff08;&#xff09;2. 减法操作符&#xff08;-&#xff09;3. 乘法操作符&#xff08;\*&#xff09;…

认知杂谈96《反人性与顺人性》

内容摘要&#xff1a; 成长常被视为反人性的&#xff0c;因为它意味着要离开舒适区&#xff0c;面对挑战。然而&#xff0c;在与人共事时&#xff0c;顺应人性同样重要&#xff0c;它要求我们理解他人的需求和动机。为了平衡成长与顺应人性&#xff0c;我们应设定清晰目标&…

封装el-upload组件,用于上传图片和视频

使用环境 vue3element-ui plus 需要根据后端返回结构修改的函数&#xff1a;onPreview onRemove onSuccess 组件使用 基本使用 源代码&#xff1a; <script setup> import AutoUploadFile from /components/auto-upload-file/index.vue function change(urls){console.…

hdfs伪分布式集群搭建

1 准备 vmware 虚拟三台centos系统的节点三台机器安装好jdk环境关闭防火墙&#xff08;端口太多&#xff0c;需要的自行去开关端口&#xff09;hadoop压缩包解压至三台服务器 可在一台节点上配置完成后克隆为三台节点 2 host修改 vi /etc/hosts在每个节点上添加三台机器的i…

Linux环境搭建git服务器和代码自动化部署

在开发过程中&#xff0c;我们经常遇到的问题就是提交代码到测试地址&#xff0c;然后进行线上测试。 要实现Git代码的自动化部署&#xff0c;考虑以下几种方法 FTP提交&#xff1a;可以使用FTP将代码上传到服务器自动化部署工具&#xff1a;如Jenkins、当代码被推送到仓库时…

【JavaWeb实战项目】在线蛋糕商城的设计与实现(附完整源代码)

一、系统介绍 本项目分为前后台&#xff0c;分为管理员与普通用户两种角色&#xff0c;管理员登录后台&#xff0c;普通用户登录前台&#xff1b; 管理员角色包含以下功能&#xff1a; 管理员登录 商品管理 订单管理 客户管理 类目管理等功能。 用户角色包含以下功能&a…

MySQL 表的操作

温馨提示&#xff1a;非特殊情况不要修改和删除表 创建表 第一种方式 第二种方式 第三种方式 简单查看 查看表 查询当前数据库&#xff1a;select database(); 查询当前数据库中具有的表&#xff1a;show tables; 查看表的简略信息&#xff1a;desc 表名1&#xff1b; 查看表的…

22.第二阶段x86游戏实战2-背包遍历REP指令详解

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要…

双十一狂欢派对 五款市面上获得好评的好物

一年一度的双十一购物狂欢派对即将到来&#xff0c;这一天不仅是广大消费者的福利日&#xff0c;也是各大品牌展示实力的战场。随着市场的不断发展与消费者需求的多样化&#xff0c;双十一已经不仅仅是降价促销的代名词&#xff0c;更是品质与创新的竞技场。在琳琅满目的商品中…

【C++】--类与对象(1)

&#x1f9c7;个人主页: 起名字真南 &#x1f32d;个人专栏:【数据结构初阶】 【C语言】 【C】 目录 1 类的定义1.1 类定义格式1.1.1 Stack类1.1.2 Date类1.1.3 Struct格式 1.2 访问限定符1.3 类域 2 实例化2.2 对象大小 3 this指针 1 类的定义 1.1 类定义格式 1 class为定义…

软件设计之SSM(5)

软件设计之SSM(5) 路线图推荐&#xff1a; 【Java学习路线-极速版】【Java架构师技术图谱】 尚硅谷新版SSM框架全套视频教程&#xff0c;Spring6SpringBoot3最新SSM企业级开发 资料可以去尚硅谷官网免费领取 学习内容&#xff1a; AOP面向切面编程 代理AOP面向切面编程获取…

好用的股票预测八大算法的Python实现

股票预测算法通常涉及时间序列分析、统计学、机器学习和深度学习等多种方法。以下是经典的、常见的十大股票预测算法及其Python实现。这些算法各有优势&#xff0c;可以用于不同的市场预测场景。以下代码实现中&#xff0c;我们将使用yfinance下载数据&#xff0c;并展示各算法…