Masm64函数的可变参数实现方法

您所在的位置:网站首页 windows钩子程序 Masm64函数的可变参数实现方法

Masm64函数的可变参数实现方法

2022-12-11 04:10| 来源: 网络整理| 查看: 265

Masm64中函数可变参数VARARG的实现方法

在Masm32编程中,函数的可变参数使用VARARG类型定义,并指定函数"C"调用类型,如下:

FunName proc C a:DWORD,b:DWORD,num:DWORD,args:VARARG

但在Masm64编程中似乎并不能使用。为了能在Masm64编程中能使用可变参数,可以通过以下方法实现。

1. 可变参数的实现方法

(1)先要定义一个宏,如下:

QWORDS EQU QWORD,@2:QWORD,@3:QWORD,@4:QWORD,@5:QWORD,\ @6:QWORD,@7:QWORD,@8:QWORD,a9:QWORD,@10:QWORD,\ @11:QWORD,@12:QWORD,@13:QWORD,@14:QWORD,@15:QWORD

该宏定义了15个参数,因为编译器不能处理太长的定义串,所以只能定义15个参数,一般情况下是足够使用了。

(2) 使用可变参数的函数定义形式如下:

;================================================ ; 参数: ; a1=为固定参数,可以有多个,也可以没有。 ; num=可变参数的个数。下续参数必须为可变参数。 ; args=可变参数变量列表。必须放在最后。 ;================================================ vararg_fun1 proc a1:QWORD,num:QWORD,args:QWORDS LOCAL ss_rsi:QWORD mov ss_rsi,rsi ;保护 lea rsi,args ss_lp1: cmp num,0 jz ss_out lodsq ;取参数1、参数2... dec num jmp ss_lp1 ss_out: mov rsi,ss_rsi ;恢复 ret vararg_fun1 endp

说明:可变参数的函数,不需要(也不能)指定调用类型符"C"。也不能使用VARARG类型,须要使用自定义的QWORDS宏。

2. 可变参数的再次传递问题

与Masm32环境一样,可变参数函数的再次传递是需要进行特别处理的,直接地将本函数的可变参数传递给另一个可变参数函数是不可以的。如以下调用是不可以的:

;================================================ vararg_fun2 proc a1:QWORD,num:QWORD,args:QWORDS invoke vararg_fun1,a1,num,args ;这将引起程序的崩溃。 ret vararg_fun2 endp

为了实现可变参数函数的再次传递,必须使函数能够接收参数列表,并且也能接收参数列表地址。问题的关键是如何区别传入的参数是参数列表还是参数列表地址,我的方法是通过num参数来区别。因为num参数值不可能很大,通过在num参数的高位设置标识位,就可以区别参数的属性。

将vararg_fun1函数改进为如下:

;================================================ ; 参数: ; a1=为固定参数。 ; num: 低16位值=可变参数的个数。 ; 如果高16位值=0,则args为参数列表 ; 如果高16位值0,则args为参数列表地址 ; args=可变参数变量列表或参数列表地址 ;================================================ vararg_fun3 proc a1:QWORD,num:QWORD,args:QWORDS LOCAL ss_rsi:QWORD mov ss_rsi,rsi ;保护 lea rsi,args cmp num,10000h jc ss_lp1 mov rsi,[rsi] and num,0ffffh ss_lp1: cmp num,0 jz ss_out lodsq ;取参数1、参数2... dec num jmp ss_lp1 ss_out: mov rsi,ss_rsi ret vararg_fun3 endp

改进后的函数,可以接收原始可变参数,也可以接收再传递的可变参数。示例如下:

;================================================ ; 参数: ; a1=为固定参数。 ; num: 低16位值=可变参数的个数。 ; 如果高16位值=0,则args为参数列表 ; 如果高16位值0,则args为参数列表地址 ; args=可变参数变量列表或参数列表地址 ;================================================ vararg_fun4 proc a1:QWORD,num:QWORD,args:QWORDS mov rax,args cmp num,10000h jnc ss_1 lea rax,args or num,10000h ss_1: invoke vararg_fun3,a1,num,rax ;接受这样的调用 invoke vararg_fun3,0,3,101,102,103 ;也接受这样的调用 ret vararg_fun4 endp


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3