热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C语言获得把64位数的后32位,32位程序调用64位函数

#pragmawarning(push)#pragmawarning(disable:4409)DWORD64__cdeclX64Call(DWORD64func,intargC,

#pragma warning(push)

#pragma warning(disable : 4409)

DWORD64 __cdecl X64Call(DWORD64 func, int argC, ...)

{

if (!g_isWow64)

return 0;

va_list args;//VA_LIST 是在C语言中解决变参问题的一组宏,所在头文件:#include ,用于获取不确定个数的参数。

va_start(args, argC);//VA_START宏,获取可变参数列表的第一个参数的地址(ap是类型为va_list的指针,v是可变参数最左边的参数):

reg64 _rcx = { (argC > 0) ? argC--, va_arg(args, DWORD64) : 0 };

reg64 _rdx = { (argC > 0) ? argC--, va_arg(args, DWORD64) : 0 };//VA_ARG宏,获取可变参数的当前参数,返回指定类型并将指针指向下一参数(t参数描述了当前参数的类型):

reg64 _r8 = { (argC > 0) ? argC--, va_arg(args, DWORD64) : 0 };

reg64 _r9 = { (argC > 0) ? argC--, va_arg(args, DWORD64) : 0 };

reg64 _rax = { 0 };

reg64 restArgs = { (DWORD64)&va_arg(args, DWORD64) };//剩余成员用堆栈传递//conversion to QWORD for easier use in inline assembly

reg64 _argC = { (DWORD64)argC };

DWORD back_esp = 0;

WORD back_fs = 0;

__asm

{

;//reset FS segment, to properly handle RFG

mov back_fs, fs

mov eax, 0x2B

mov fs, ax

;//keep original esp in back_esp variable

mov back_esp, esp

;//align esp to 0x10, without aligned stack some syscalls may return errors !

;//(actually, for syscalls it is sufficient to align to 8, but SSE opcodes

;//requires 0x10 alignment), it will be further adjusted according to the

;//number of arguments above 4

;//对齐

and esp, 0xFFFFFFF0

X64_Start();

;//below code is compiled as x86 inline asm, but it is executed as x64 code

;//that's why it need sometimes REX_W() macro, right column contains detailed

;//transcription how it will be interpreted by CPU

;//fill first four arguments

REX_W mov ecx, _rcx.dw[0] ;//mov rcx, qword ptr [_rcx]

REX_W mov edx, _rdx.dw[0] ;//mov rdx, qword ptr [_rdx]

push _r8.v ;//push qword ptr [_r8]

X64_Pop(_R8); ;//pop r8

push _r9.v ;//push qword ptr [_r9]

X64_Pop(_R9); ;//pop r9

;// REX_W mov eax, _argC.dw[0] ;//mov rax, qword ptr [_argC]

;// ;//final stack adjustment, according to the ;// ;//number of arguments above 4 ;// test al, 1 ;//test al, 1

jnz _no_adjust ;//jnz _no_adjust

sub esp, 8 ;//sub rsp, 8 对齐对齐对齐!假如有单个参数 需要对齐!!!

_no_adjust: ;// ;// push edi ;//push rdi

REX_W mov edi, restArgs.dw[0] ;//mov rdi, qword ptr [restArgs]

;// ;//put rest of arguments on the stack ;// REX_W test eax, eax ;//test rax, rax

jz _ls_e ;//je _ls_e

REX_W ea edi, dword ptr [edi + 8*eax - 8] ;//lea rdi, [rdi + rax*8 - 8]取最后一个的地址

;//_ls: ;// REX_W test eax, eax ;//test rax, rax 判断是否为0

jz _ls_e ;//je _ls_e

push dword ptr [edi] ;//push qword ptr [rdi]

REX_W sub edi, 8 ;//sub rdi, 8

REX_W sub eax, 1 ;//sub rax, 1

jmp _ls ;//jmp _ls

_ls_e: ;// ;// ;//create stack space for spilling registers ;// REX_W sub esp, 0x20 ;//sub rsp, 20h

;// call func ;//call qword ptr [func]

;// ;//cleanup stack ;// REX_W mov ecx, _argC.dw[0] ;//mov rcx, qword ptr [_argC]

REX_W lea esp, dword ptr [esp + 8*ecx + 0x20] ;//lea rsp, [rsp + rcx*8 + 20h]

;// pop edi ;//pop rdi

;//

//set return value ;// REX_W mov _rax.dw[0], eax ;//mov qword ptr [_rax], rax

X64_End();

mov ax, ds

mov ss, ax

mov esp, back_esp

;//restore FS segment

mov ax, back_fs

mov fs, ax

}

return _rax.v;

}



推荐阅读
author-avatar
1012720691_905e1e
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有