跳转到主要内容

神秘的汇编代码

神秘的汇编代码

下面是一段神秘汇编代码,编译后可以给LISP调用,至于方法,以后再说。

 	.data
pStack  qword 0     ;栈位置
dReal8  real8 0.0

	.code
;extern "C" _INT CallAPI64_( _UINT lpFunction, DYNAPARM Param[],size_t nArgs,_INT Flags,LPVOID pRet, size_t nRetSiz);
;参数说明: 函数地址-RCX, 参数-RDX, 参数数目-R8, 调参方式-R9, 返回结果-[rsp+40], 返回大小-[rsp+48]
CallAPI64_ proc pFunc:qword,Param:qword,nArgs:qword,Flags:qword,pRet:qword,nRet:qword
SaveStack:
	mov     pStack,rsp		;保存栈

SaveArgs:
	mov     pFunc,rcx       ;函数地址
	mov     r11,r8          ;参数个数 
    
AdjustStack:               
    sub     rsp,20h         ;留给代码运行空间
	test    r11,1			;测试参数个数是否奇数
	jz      ZeroArg         ;偶数跳转
	sub     rsp,8			;奇数的话要平栈

ZeroArg:
	cmp     r11,0           ;无参数
	jz      CallAPI         ;直接call

SaveData:
	cmp		r11,5           ;是否5个参数
	jb		FourArgs        ;小于则跳转到4个参数段

FromLast:					 
    imul	rax,r8,16		;每个参数16个字节,16*参数个数 
    sub     rax,8           ;每个参数的第8个字节存储参数的值
	add     rax,rdx         ;参数偏移值=Param[n-1]
	mov     rcx,r8          ;参数个数  
	sub		rcx,4           ;大于4则只循环读取4个以上的

GetArgs: 
	push    [rax]           ;参数入栈
	sub		rax,16          ;每个参数16个字节
    loop	GetArgs

FourArgs:
	mov 	rax,rdx         ;rax=参数组  
	cmp     r11,4			;4个参数
	jb      ThreeArgs
	mov     r10b,[rax+30h]
	cmp     r10b,2
    jnz     @F
	movsd   xmm3,mmword ptr [rax+38h]
@@:
    mov     r9,[rax+38h]
	push    r9

ThreeArgs:
	cmp     r11,3			;3个参数
	jb      TwoArgs
	mov     r10b,[rax+20h]
	cmp     r10b,2
    jnz     @F
	movsd   xmm2,mmword ptr [rax+28h]
@@:
	mov     r8,[rax+28h]
	push    r8

TwoArgs:
	cmp     r11,2			;2个参数
	jb      OneArg
	mov     r10b,[rax+10h]
	cmp     r10b,2
    jnz     @F
	movsd   xmm1,mmword ptr [rax+18h]
@@:
	mov     rdx,[rax+18h]
	push    rdx

OneArg:						;1个参数			
	mov     r10b, [rax]
	cmp     r10b, 2
	jnz     @F
	movsd   xmm0,mmword ptr [rax+8]
@@:
	mov     rcx,[rax+8]		
	push    rcx

CallAPI:
    call	pFunc
	cmp     pRet,0
	jz      RestoreStack
	mov     rax,pRet 
	movsd   mmword ptr [rax],xmm0  
	  
RestoreStack:
	mov     rsp,pStack
	ret

CallAPI64_ endp

分类