首页
社区
课程
招聘
[讨论]关于x64汇编调用api的问题
发表于: 2014-1-10 10:52 8582

[讨论]关于x64汇编调用api的问题

2014-1-10 10:52
8582
以RadASM为例子
win32汇编调用api比较简单
invoke api名字,参数

64位的就不会了
用ida看了一下生成的汇编代码,下面是个例子

call    cs:GetCurrentProcess
mov     r9d, 0Ch        ; nSize
mov     r8, rdi         ; lpBuffer
mov     rdx, rsi        ; lpBaseAddress
mov     rcx, rax        ; hProcess
mov     [rsp+38h+var_18], 0
call    cs:WriteProcessMemory
mov     rbx, [rsp+38h+arg_0]
mov     rsi, [rsp+38h+arg_8]
mov     eax, 1
add     rsp, 30h
pop     rdi
retn

32位的就比较好理解,直接push
push    0               ; lpNumberOfBytesWritten
push    5               ; nSize
push    offset unk_10003018 ; lpBuffer
push    lpAddress       ; lpBaseAddress
push    hProcess        ; hProcess
call    WriteProcessMemory

有没有相关资料介绍下调用的规则?

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 608
活跃值: (648)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
x64下函数调用约定都是fastcall 前4个参数为寄存器 rcx rdx r8 r9 多于4个的参数部分使用堆栈传参
2014-1-10 11:12
0
雪    币: 517
活跃值: (84)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
3
http://msdn.microsoft.com/zh-cn/library/ms235286(v=vs.90).aspx
2014-1-10 11:15
0
雪    币: 6566
活跃值: (4526)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
4
x64 调用约定概述
从 x86 到 x64 的两个重要修改是:64 位寻址功能和一组平面的用于常规使用的 16 个 64 位寄存器。对于展开的寄存器集,x64 仅使用 __fastcall 调用约定和基于 RISC 的异常处理模型。__fastcall 模型使用寄存器(对前四个变量)和堆栈帧传递其他参数。

以下编译器选项帮助您优化 x64 应用程序:

    /favor(针对 x64 进行优化)

调用约定

x64 应用程序二进制接口 (ABI) 是一个 4 寄存器快速调用调用约定,具有用于这些寄存器的堆栈后备功能。函数中的参数与这些参数的寄存器之间有一对一的对应关系。任何大于 8 个字节或不是 1、2、4 或 8 个字节的参数必须由引用传递。不尝试将单个参数在多个寄存器间传播。没有使用 x87 寄存器堆栈。可以使用它,但是必须认为它在函数调用之间是易失性的。所有浮点操作都是使用 16 个 XMM 寄存器完成的。参数在寄存器 RCX、RDX、R8 和 R9 中传递。如果参数是浮点/双精度型,则它们在 XMM0L、XMM1L、XMM2L 和 XMM3L 中传递。16 字节的参数由引用传递。参数传递中详细描述了参数传递。除这些寄存器外,RAX、R10、R11、XMM4 和 XMM5 也是易失性的。其他所有寄存器都是非易失性的。寄存器使用和由调用方或被调用方保存的寄存器中详细记录了寄存器用法。

调用方负责为被调用方的参数分配空间,并且必须始终为 4 个寄存器参数分配足够的空间,即使被调用方没有这么多参数。这有助于简化对 C 非原型函数和 vararg C/C++ 函数的支持。对于 vararg 或非原型函数,任何浮点值都必须在相应的常规用途的寄存器中复制。超过前 4 个的任何参数必须存储在堆栈上,位置在前 4 个的后备存储器之上,在调用之前。Varargs 中提供了 Vararg 函数的详细信息。非原型函数中提供了关于非原型函数的详细信息。
对齐方式

大多数结构的对齐方式为自然对齐。主要异常是堆栈指针和 malloc 或 alloca 内存,为了提高性能,它们的对齐方式为 16 字节对齐。超过 16 字节的对齐必须手动完成,但由于 16 字节是 XMM 操作的常用对齐大小,所以对大多数代码应该足够了。有关结构布局和对齐方式的更多信息,请参见类型和存储。有关堆栈布局的信息,请参见堆栈使用。
展开性

必须使用数据[被称作 xdata 或 ehdata,它被指出来源于 pdata]批注所有非叶函数[这些函数既不调用函数,也不自己分配任何堆栈空间],该数据向操作系统描述如何正确展开这些函数以及恢复非易失性的寄存器。Prolog 和 epilog 受到严格限制,以便可在 xdata 中正确对它们进行描述。在不属于 epilog 或 prolog 的任何代码部分中,堆栈指针的对齐方式必须为 16 字节对齐(叶函数除外)。有关 prolog 和 epilog 函数的正确结构的详细信息,请参见保护现场和恢复现场。有关异常处理和异常处理/展开 pdata 和 xdata 的更多信息,请参见异常处理 (x64)。

谢谢两位
2014-1-10 11:51
0
游客
登录 | 注册 方可回帖
返回
//