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

[复制链接]
发表于 2025-8-7 03:22:51 | 显示全部楼层 |阅读模式
前言

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

分析汇编的源码:
  1. #include <iostream>
  2. int __cdecl cdecl_test(int a, int b, int c, int d, int e, int f, int g) {
  3.         char p[] = "Hello, World!";
  4.         int result = 0;
  5.         result += a + b + c + d + e + f + g;
  6.         return result;
  7. }
  8. int __fastcall fastcall_test(int a, int b, int c, int d, int e, int f, int g) {
  9.         char p[] = "Hello, World!";
  10.         int result = 0;
  11.         result += a + b + c + d + e + f + g;
  12.         return result;
  13. }
  14. int __stdcall stdcall_test(int a, int b, int c, int d, int e, int f, int g) {
  15.         char p[] = "Hello, World!";
  16.         int result = 0;
  17.         result += a + b + c + d + e + f + g;
  18.         return result;
  19. }
  20. int main(){
  21.         int a = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7;
  22.         int result = 0;
  23.         result = cdecl_test(a, b, c, d, e, f, g);
  24.         printf("cdecl_test result: %d\n", result);
  25.         result = fastcall_test(a, b, c, d, e, f, g);
  26.         printf("fastcall_test result: %d\n", result);
  27.         result = stdcall_test(a, b, c, d, e, f, g);
  28.         printf("stdcall_test result: %d\n", result);
  29.         return 0;
  30. }
复制代码
  1. #include <iostream>
  2. class Test {
  3. public:
  4.         int func(int a, int b, int c, int d, int e, int f, int g) {
  5.                 int result = 0;
  6.                 result += a + b + c + d + e + f + g;
  7.                 printf("Result: %d\n", result);
  8.                 return result;
  9.         }
  10. };
  11. int main() {
  12.         int a = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7;
  13.         int result = 0;
  14.         Test test;
  15.         result = test.func(a, b, c, d, e, f, g);
  16.         printf("Result: %d\n", result);
  17.         return 0;
  18. }
复制代码
cdecl

传递参数

开辟栈空间,保存栈环境

恢复环境,恢复栈空间,返回

平栈,保存返回值

fastcall

传递参数

开辟栈空间,保存环境

恢复环境,恢复栈空间,平栈

stdcall

传递参数

开辟栈空间,保存环境

恢复环境,恢复栈空间,平栈

thiscall

传递参数

开辟栈空间,保存环境

恢复环境,恢复栈空间,平栈

总结

函数调用约定参数传递方式平栈方式cdecl(默认)push(从右到左)函数外平栈fastcallecx(参数1),edx(参数2),push(从右到左)函数内平栈stdcallpush(从右到左)函数内平栈thiscallecx(this指针),push(从右到左)函数内平栈值得留意的是:在winapi中大多是用stdcall
x64 汇编分析(vectorcall, thiscall)

分析汇编的源码
  1. #include <iostream>
  2. int __vectorcall test(int a, int b, int c, int d, int e, int f, int g) {
  3.         int result = 0;
  4.         result += a + b + c + d + e + f + g;
  5.         printf("Result: %d\n", result);
  6.         return result;
  7. }
  8. int main() {
  9.         int a = 1, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7;
  10.         int result = 0;
  11.         result = test(a, b, c, d, e, f, g);
  12.         printf("Result: %d\n", result);
  13.         return 0;
  14. }
复制代码
vectorcall

传递参数

保存参数,开辟栈空间,(保存环境)

恢复栈空间

总结

函数调用约定参数1参数2参数3参数4参数5以上平栈方式vectorcallrcxrdxr8r9堆栈传递函数内平栈vectorcall(浮点参数)xmm0xmm1xmm2xmm3堆栈传递函数内平栈thiscallrcx(this)rdxr8r9堆栈传递函数内平栈我这里给出thiscall,vectorcall的浮点表现情势,thiscall,因为在底层默认函数第一个参数传递this指针,这两种函数调用约定在x64中本质是一样的
以上出现错误可品评区提示!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

×
登录参与点评抽奖,加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表