网站首页 全球最实用的IT互联网站!

人工智能P2P分享Wind搜索发布信息网站地图标签大全

当前位置:诺佳网 > 软件工程 > 其他技术区 > 网络安全 >

逆向:x86,x64从汇编分析函数调用约定详解

时间:2025-08-07 00:01

人气:

作者:admin

标签:

导读:前言 网上大多教程都是对x86汇编进行分析,少有x64的,因此,本次对x86和x64的函数调用的参数传递以及函数的调用约定进行详细的分析对比和总结。 (cdecl,fastcall,stdcall,vectorcall,thiscal...

网上大多教程都是对x86汇编进行分析,少有x64的,因此,本次对x86和x64的函数调用的参数传递以及函数的调用约定进行详细的分析对比和总结。
(cdecl,fastcall,stdcall,vectorcall,thiscall)
注意本次实验中(环境):x86的cdecl, fastcall, stdcall代码以debug模式编译,x86的thiscall,以及x64代码均以relase模式下编译并关闭性能优化

分析汇编的源码:

#include <iostream>

int __cdecl cdecl_test(int a, int b, int c, int d, int e, int f, int g) {
	char p[] = "Hello, World!";
	int result = 0;
	result += a + b + c + d + e + f + g;
	return result;
}

int __fastcall fastcall_test(int a, int b, int c, int d, int e, int f, int g) {
	char p[] = "Hello, World!";
	int result = 0;
	result += a + b + c + d + e + f + g;
	return result;
}

int __stdcall stdcall_test(int a, int b, int c, int d, int e, int f, int g) {
	char p[] = "Hello, World!";
	int result = 0;
	result += a + b + c + d + e + f + g;
	return result;
}

int main(){
	int a = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7;
	int result = 0;
	result = cdecl_test(a, b, c, d, e, f, g);
	printf("cdecl_test result: %d\n", result);
	result = fastcall_test(a, b, c, d, e, f, g);
	printf("fastcall_test result: %d\n", result);
	result = stdcall_test(a, b, c, d, e, f, g);
	printf("stdcall_test result: %d\n", result);
	return 0;
}
#include <iostream>

class Test {
public:
	int func(int a, int b, int c, int d, int e, int f, int g) {
		int result = 0;
		result += a + b + c + d + e + f + g;
		printf("Result: %d\n", result);
		return result;
	}
};

int main() {
	int a = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7;
	int result = 0;
	Test test;
	result = test.func(a, b, c, d, e, f, g);
	printf("Result: %d\n", result);
	return 0;
}

cdecl


传递参数
PixPin_2025-08-05_21-46-26

开辟栈空间,保存栈环境
PixPin_2025-08-05_22-14-58

恢复环境,恢复栈空间,返回
PixPin_2025-08-05_22-22-04

平栈,保存返回值
PixPin_2025-08-05_22-20-12

fastcall


传递参数
PixPin_2025-08-05_22-30-09

开辟栈空间,保存环境
PixPin_2025-08-05_22-37-30

恢复环境,恢复栈空间,平栈
PixPin_2025-08-05_22-41-04

stdcall


传递参数
PixPin_2025-08-05_22-45-41

开辟栈空间,保存环境
PixPin_2025-08-05_22-48-34

恢复环境,恢复栈空间,平栈
PixPin_2025-08-05_22-50-15

thiscall


传递参数
PixPin_2025-08-06_23-37-52

开辟栈空间,保存环境
PixPin_2025-08-06_23-38-03

恢复环境,恢复栈空间,平栈
PixPin_2025-08-06_23-38-09

总结

函数调用约定 参数传递方式 平栈方式
cdecl(默认) push(从右到左) 函数外平栈
fastcall ecx(参数1),edx(参数2),push(从右到左) 函数内平栈
stdcall push(从右到左) 函数内平栈
thiscall ecx(this指针),push(从右到左) 函数内平栈

值得注意的是:在winapi中大多是用stdcall

分析汇编的源码

#include <iostream>

int __vectorcall test(int a, int b, int c, int d, int e, int f, int g) {
	int result = 0;
	result += a + b + c + d + e + f + g;
	printf("Result: %d\n", result);
	return result;
}

int main() {
	int a = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7;
	int result = 0;
	result = test(a, b, c, d, e, f, g);
	printf("Result: %d\n", result);
	return 0;
}

vectorcall


传递参数
PixPin_2025-08-06_23-06-12

保存参数,开辟栈空间,(保存环境)
PixPin_2025-08-06_23-06-43

恢复栈空间
PixPin_2025-08-06_23-06-53

总结

函数调用约定 参数1 参数2 参数3 参数4 参数5以上 平栈方式
vectorcall rcx rdx r8 r9 堆栈传递 函数内平栈
vectorcall(浮点参数) xmm0 xmm1 xmm2 xmm3 堆栈传递 函数内平栈
thiscall rcx(this) rdx r8 r9 堆栈传递 函数内平栈

我这里给出thiscall,vectorcall的浮点表现形式,thiscall,因为在底层默认函数第一个参数传递this指针,这两种函数调用约定在x64中本质是一样的

本文来自博客园,作者:ClownLMe,转载请注明原文链接:https://www.cnblogs.com/ClownLMe/p/19026101

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信