加密与解密(4.2 64位软件传参笔记)

X64寄存器:

  X64系统通用寄存器的名曾,第1个字母从“E”改为“R” (RAX)大小扩展到64位。数量增加了8个(R8~R15),使用WORD\BYTE\DWORD后缀。

 

调用约定:如果参数既有浮点类型,又有政署类型,例如“void fun(float,int,float,int)”,那么参数传递顺序为第1个参数(XMM0)、第二个参数(RDX)、第三个参数(XMM2)、第四个参数(R9)。

参数传递

 两个例子 参数小于4时

#include "stdafx.h"

int Add(int nNum1, int nNum2) {
	return nNum1 + nNum2;
}


int _tmain(int argc, _TCHAR* argv[]) {
	printf("%d\r\n", Add(1, 2));
	return 0;
}

用IDA Pro查看反汇编

.text:0000000140001040 main_0          proc near               ; CODE XREF: mainj
.text:0000000140001040                                         ; DATA XREF: .pdata:000000014000A00Co
.text:0000000140001040
.text:0000000140001040 arg_0           = dword ptr  8
.text:0000000140001040 arg_8           = qword ptr  10h
.text:0000000140001040
.text:0000000140001040                 mov     [rsp+arg_8], rdx ;参数2
.text:0000000140001045                 mov     [rsp+arg_0], ecx ;参数1
.text:0000000140001049                 push    rdi  ;保护环境
.text:000000014000104A                 sub     rsp, 20h ;申请预留
.text:000000014000104E                 mov     rdi, rsp ;初始化为0xcc
.text:0000000140001051                 mov     ecx, 8
.text:0000000140001056                 mov     eax, 0CCCCCCCCh
.text:000000014000105B                 rep stosd
.text:000000014000105D                 mov     ecx, [rsp+28h+arg_0]
.text:0000000140001061                 mov     edx, 2    ;参数2:nNUM2
.text:0000000140001066                 mov     ecx, 1    ;参数1:nNUM1
.text:000000014000106B                 call    sub_140001005    ;ADD函数
.text:0000000140001070                 mov     edx, eax
.text:0000000140001072                 lea     rcx, Format     ; "%d\r\n"
.text:0000000140001079                 call    cs:printf
.text:000000014000107F                 xor     eax, eax
.text:0000000140001081                 add     rsp, 20h
.text:0000000140001085                 pop     rdi
.text:0000000140001086                 retn
.text:0000000140001086 main_0          endp
.text:0000000140001086

 

参数大于4时

#include "stdafx.h"


int Add(int nNum1, int nNum2, int nNum3, int nNum4, int nNum5, int nNum6) {
    return nNum1 + nNum2 + nNum3 + nNum4 + nNum5 + nNum6;
}

int _tmain(int argc, _TCHAR* argv[]) {
    printf("%d\r\n", Add(1, 2, 3, 4, 5, 6));
    return 0;
}

.text:0000000140001060
.text:0000000140001060                 mov     [rsp+arg_8], rdx
.text:0000000140001065                 mov     [rsp+arg_0], ecx
.text:0000000140001069                 push    rdi
.text:000000014000106A                 sub     rsp, 30h
.text:000000014000106E                 mov     rdi, rsp
.text:0000000140001071                 mov     ecx, 0Ch
.text:0000000140001076                 mov     eax, 0CCCCCCCCh
.text:000000014000107B                 rep stosd
.text:000000014000107D                 mov     ecx, [rsp+38h+arg_0]
.text:0000000140001081                 mov     [rsp+38h+var_10], 6
.text:0000000140001089                 mov     [rsp+38h+var_18], 5
.text:0000000140001091                 mov     r9d, 4
.text:0000000140001097                 mov     r8d, 3
.text:000000014000109D                 mov     edx, 2
.text:00000001400010A2                 mov     ecx, 1
.text:00000001400010A7                 call    sub_140001005
.text:00000001400010AC                 mov     edx, eax
.text:00000001400010AE                 lea     rcx, Format     ; "%d\r\n"
.text:00000001400010B5                 call    cs:printf
.text:00000001400010BB                 xor     eax, eax
.text:00000001400010BD                 add     rsp, 30h
.text:00000001400010C1                 pop     rdi
.text:00000001400010C2                 retn

 ADD反汇编

.text:0000000140001020 arg_0           = dword ptr  8
.text:0000000140001020 arg_8           = dword ptr  10h
.text:0000000140001020 arg_10          = dword ptr  18h
.text:0000000140001020 arg_18          = dword ptr  20h
.text:0000000140001020 arg_20          = dword ptr  28h
.text:0000000140001020 arg_28          = dword ptr  30h
.text:0000000140001020
.text:0000000140001020                 mov     [rsp+arg_18], r9d
.text:0000000140001025                 mov     [rsp+arg_10], r8d
.text:000000014000102A                 mov     [rsp+arg_8], edx
.text:000000014000102E                 mov     [rsp+arg_0], ecx
.text:0000000140001032                 push    rdi
.text:0000000140001033                 mov     eax, [rsp+8+arg_8]
.text:0000000140001037                 mov     ecx, [rsp+8+arg_0]
.text:000000014000103B                 add     ecx, eax
.text:000000014000103D                 mov     eax, ecx
.text:000000014000103F                 add     eax, [rsp+8+arg_10]
.text:0000000140001043                 add     eax, [rsp+8+arg_18]
.text:0000000140001047                 add     eax, [rsp+8+arg_20]
.text:000000014000104B                 add     eax, [rsp+8+arg_28]
.text:000000014000104F                 pop     rdi
.text:0000000140001050                 retn

 如果参数多于4个,前4个参数同福哦寄存器传递,从第五个参数开始使用栈传递。

对于参数为结构体则是如果参数结构体小于8字节,在传递结构体参数是,应直接吧整个结构体的内容放在寄存器中。在函数里,通过访问寄存器的高32为和低32为来分别访问结构体的成员。

如果参数结构体大于8字节的,在传递参数时,会先把结构内容复制到栈空间中,再把结构体地址当成函数的参数来传递。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值