X64的调用约定
来源:互联网 发布:孢子mac下载 编辑:程序博客网 时间:2024/04/29 10:26
接触x64之后继续看PG的文章,今天开始读msdn上有关x64的解释 http://msdn.microsoft.com/zh-cn/library/7kcdt6fy
调用约定简化了:一律使用__fastcall,前四个参数用 RCX、RDX、R8 和 R9传递,除了这四个外加RAX、R10、R11,其他寄存器都是非易失的。
接下来要看的是x64异常处理
调用约定简化了:一律使用__fastcall,前四个参数用 RCX、RDX、R8 和 R9传递,除了这四个外加RAX、R10、R11,其他寄存器都是非易失的。
比如下面这段NtCreateFile的代码:
PAGE:0000000140382B8C mov r11, rsp;r11 保存rspPAGE:0000000140382B8F sub rsp, 88h ;开辟压栈参数空间,而不是用push,前四个参数在寄存器中所以不管PAGE:0000000140382B96 xor eax, eaxPAGE:0000000140382B98 mov [r11-10h], raxPAGE:0000000140382B9C mov [rsp+88h+var_18], 20hPAGE:0000000140382BA4 mov [rsp+88h+var_20], eaxPAGE:0000000140382BA8 mov [r11-28h], raxPAGE:0000000140382BAC mov [rsp+88h+var_30], eaxPAGE:0000000140382BB0 mov eax, [rsp+88h+EaLength] ;其他参数拷贝入栈PAGE:0000000140382BB7 mov [rsp+88h+var_38], eaxPAGE:0000000140382BBB mov rax, [rsp+88h+EaBuffer]PAGE:0000000140382BC3 mov [r11-40h], raxPAGE:0000000140382BC7 mov eax, [rsp+88h+CreateOptions]PAGE:0000000140382BCE mov [rsp+88h+var_48], eaxPAGE:0000000140382BD2 mov eax, [rsp+88h+CreateDisposition]PAGE:0000000140382BD9 mov [rsp+88h+var_50], eaxPAGE:0000000140382BDD mov eax, [rsp+88h+ShareAccess]PAGE:0000000140382BE4 mov [rsp+88h+var_58], eaxPAGE:0000000140382BE8 mov eax, [rsp+88h+FileAttributes]PAGE:0000000140382BEF mov [rsp+88h+var_60], eaxPAGE:0000000140382BF3 mov rax, [rsp+88h+AllocationSize]PAGE:0000000140382BFB mov [r11-68h], raxPAGE:0000000140382BFF call IopCreateFilePAGE:0000000140382C04 add rsp, 88h ;平衡堆栈返回PAGE:0000000140382C0B retnPAGE:0000000140382C0B NtCreateFile endpNtCreateFile是直接调用IoCreateFile的,比较特殊,下面跟进IoCreateFile PAGE:0000000140377CF0 ; FUNCTION CHUNK AT PAGE:00000001403D665F SIZE 0000008C BYTESPAGE:0000000140377CF0PAGE:0000000140377CF0 mov [rsp+arg_18], r9;无论是否有四个参数,函数开头都会把这四个参数入栈PAGE:0000000140377CF5 mov [rsp+arg_10], r8PAGE:0000000140377CFA mov [rsp+arg_8], edxPAGE:0000000140377CFE mov [rsp+arg_0], rcxPAGE:0000000140377D03 push rbx;微软承诺的非已易失寄存器,会全部入栈,这是PAGE:0000000140377D04 push rsiPAGE:0000000140377D05 push rdiPAGE:0000000140377D06 push r12PAGE:0000000140377D08 push r13PAGE:0000000140377D0A push r14PAGE:0000000140377D0C push r15PAGE:0000000140377D0E sub rsp, 60hPAGE:0000000140377D12 mov r14d, edxPAGE:0000000140377D15 xor r15d, r15dPAGE:0000000140377D18 mov [rsp+98h+var_54], r15dPAGE:0000000140377D1D mov rax, gs:188hPAGE:0000000140377D26 mov r13d, [rsp+98h+arg_68]PAGE:0000000140377D2E movzx r12d, byte ptr [rax+1F6h]PAGE:0000000140377D36 bt r13d, 8PAGE:0000000140377D3B cmovb r12d, r15dPAGE:0000000140377D3F mov rsi, gs:20hPAGE:0000000140377D48 mov rbx, [rsi+800h]PAGE:0000000140377D4F inc dword ptr [rbx+14h]PAGE:0000000140377D52 mov rcx, rbx ; ListHeadPAGE:0000000140377D55 call RtlpInterlockedPopEntrySList;epilogadd rsp, 60hpop r15pop r14pop r13pop r12pop rdipop rsipop rbxretn
平衡堆栈的任务交给调用者来完成了,这里入参没有用push而是sub xx 调用之后再add xx
另外这里没有用rbp来存储父esp,因为这只是prolog的一个可选项
MOV [RSP+8h],RCX
MOV [RSP+10h],RDX
MOV [RSP+18h],R8
MOV [RSP+20h],R9
PUSH RBP
MOV RBP,RSP
;……
LEA RSP,[RBP]
POP RBP
RET
寄存器的用法:
Register
状态
使用
RAX
易失的
返回值寄存器
RCX
易失的
第一个整型参数
RDX
易失的
第二个整型参数
R8
易失的
第三个整型参数
R9
易失的
第四个整型参数
R10:R11
易失的
必须根据需要由调用方保留;在 syscall/sysret 指令中使用
R12:R15
非易失的
必须由被调用方保留
RDI
非易失的
必须由被调用方保留
RSI
非易失的
必须由被调用方保留
RBX
非易失的
必须由被调用方保留
RBP
非易失的
可用作帧指针;必须由被调用方保留
RSP
非易失的
堆栈指针
XMM0
易失的
第一个 FP 参数
XMM1
易失的
第二个 FP 参数
XMM2
易失的
第三个 FP 参数
XMM3
易失的
第四个 FP 参数
XMM4:XMM5
易失的
必须根据需要由调用方保留
XMM6:XMM15
非易失的
必须根据需要由被调用方保留。
1: kd> bp iocreatefile1: kd> gBreakpoint 0 hitnt!IoCreateFile:fffff800`0418bf40 4c8bdc mov r11,rsp1: kd> dq rspfffff880`03727568 fffff960`000d8bad 00000000`00000000fffff880`03727578 00000000`000007ff 00000000`00000000fffff880`03727588 00000000`00000001 00000000`00000000fffff880`03727598 fffffa80`00000080 fffff8a0`00000001fffff880`037275a8 00000000`00000001 00000000`00000010fffff880`037275b8 00000000`00000000 fffff8a0`00000000fffff880`037275c8 fffff8a0`00000000 00000000`00000000fffff880`037275d8 fffff800`00000301 00000000`000000001: kd> u fffff960`000d8badwin32k!bCreateSection+0x129:fffff960`000d8bad 408ace mov cl,silfffff960`000d8bb0 8bd8 mov ebx,eaxfffff960`000d8bb2 ff15c88f2300 call qword ptr [win32k!_imp_IoSetThreadHardErrorMode (fffff960`00311b80)]fffff960`000d8bb8 413bdd cmp ebx,r13dfffff960`000d8bbb 7d07 jge win32k!bCreateSection+0x140 (fffff960`000d8bc4)fffff960`000d8bbd 33c0 xor eax,eaxfffff960`000d8bbf e970020000 jmp win32k!bCreateSection+0x3b0 (fffff960`000d8e34)fffff960`000d8bc4 488b4c2470 mov rcx,qword ptr [rsp+70h]1: kd> r rax=fffff88003727688 rbx=fffff900c0081000 rcx=fffff880037275e0rdx=00000000001200a9 rsi=0000000000000001 rdi=0000000000000000rip=fffff8000418bf40 rsp=fffff88003727568 rbp=fffff880037277d0 r8=fffff88003727608 r9=fffff880037275f0 r10=0000000000000000r11=fffffa800ecc6860 r12=fffff88003727740 r13=0000000000000000r14=0000000000000001 r15=fffff88003727920iopl=0 nv up ei pl zr na po nccs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00000246nt!IoCreateFile:fffff800`0418bf40 4c8bdc mov r11,rsp1: kd> dt _OBJECT_ATTRIBUTES fffff88003727608ntdll!_OBJECT_ATTRIBUTES +0x000 Length : 0x30 +0x008 RootDirectory : (null) +0x010 ObjectName : 0xfffff880`03727688 _UNICODE_STRING "\??\C:\WINDOWS\FONTS\EUDC.TTE" +0x018 Attributes : 0x240 +0x020 SecurityDescriptor : (null) +0x028 SecurityQualityOfService : (null)
接下来要看的是x64异常处理
参考:
http://msdn.microsoft.com/zh-cn/library/7kcdt6fy
http://bbs.pediy.com/showthread.php?t=43967
- X64的调用约定
- x64的调用约定
- x64不同平台的调用约定
- x64 调用约定概述
- X64平台调用约定
- Windows x64汇编函数调用约定
- windows x64函数调用约定(function call convention)
- x64 调用约定,参数传递以及函数返回值
- Windows平台X64函数调用约定与汇编代码分析
- windows x64函数调用约定(function call convention)
- windows x64函数调用约定(function call convention)
- delphi的调用约定
- 详细的调用约定
- 函数的调用约定
- 约定的调用
- 函数的调用约定
- 调用约定的认识
- 调用约定的坑
- QT SDK 连接 MySql (windows 7 )
- 软文营销的概念
- 金蝶时期的那些笔记
- 网络整合营销之策略
- printf和scanf的缺陷,标准流类、文件流类、串流类,I/O成员函数
- X64的调用约定
- poj2367 Genealogical tree
- shellapi.h(55) : error C2065: 'HDROP' : undeclared identifier
- Longest Substring Without Repeating Characters
- 【UML】UML几种图的绘制
- publishing failed with multiple errors
- 名人问题 (Celebrity problem)
- 一道收集优惠券的面试题
- 求两个数组的交集