x86_64通过汇编指令调用Windows API

记录下第二次思考过程,终于看明白了,不需要死记。
64位系统下调用函数先抬栈,然后默认需要4个寄存器rcx,rdx,r8,r9,每个寄存器8字节,之后call进去把寄存器的值放到栈上。
所以说问题来了,先抬栈应该抬多少?4个寄存器每个8字节,一共32字节,call有个返回地址占用8字节,但是栈必须按照16字节分配,前面4个寄存器32字节已经对齐了16字节,但是返回地址只有8字节没有对齐,所以还需要多分配8字节。最终得到答案,先抬栈32+8=40=0x28,之后加上返回地址8字节=48字节就对齐了。
那么当参数超过4个的时候应该抬栈多少呢?很简单,4个以上的参数只能通过栈传递,栈每次必须分配16字节,所以假设有5个参数需要传递,32字节(前4个参数)+16字节(第5个参数)+8字节(为了与返回地址对齐)=56字节=0x38。另外函数调用完之后最好xor eax, eax清空eax保持好习惯。

分割线下方是第一次的学习过程


64位寄存器占用8字节(RAX,RCX…)

参数传递顺序如下:

第一个参数:RCX
第二个参数:RDX
第三个参数:R8
第四个参数:R9
第五个参数:rsp+20
第六个参数:rsp+28
第七个参数:rsp+30
...以此类推,目的是保持栈对齐16字节(记结论好了)

栈调整量=32字节影子空间+8字节返回地址+额外参数量*16字节 转换为16进制

示例调用MessageBoxExA

int MessageBoxExA(
  [in, optional] HWND   hWnd,
  [in, optional] LPCSTR lpText,
  [in, optional] LPCSTR lpCaption,
  [in]           UINT   uType,
  [in]           WORD   wLanguageId
);

32+8+1*16=56 = 38(hex)

sub rsp,栈调整量
mov rcx,参数
mov rdx,参数
mov r8,参数
mov r9,参数
mov [rsp+20],
call MessageBoxExA
add rsp,栈调整量
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇