linux_x64 下的一样平常汇编函数与syscall调用约定

打印 上一主题 下一主题

主题 913|帖子 913|积分 2739

在 linux_x86_64(即 64 位 Linux 系统上的 x86-64 架构)下,函数调用约定(Calling Convention)定义了函数调用时参数传递、返回值传递、寄存器使用、栈帧的构建等方面的规则。这些约定在不同的操作系统和架构上可能有所不同。在 Linux 上的 x86-64 架构中,遵循的紧张是 System V ABI (Application Binary Interface),这是一种广泛使用的应用二进制接口。
  1. 参数传递

在 x86_64 架构下,函数参数的传递遵循以下规则:


  • 前 6 个整数参数(包罗 int、char、long 等)通过 寄存器 传递:

    • RDI:第一个参数
    • RSI:第二个参数
    • RDX:第三个参数
    • RCX:第四个参数
    • R8:第五个参数
    • R9:第六个参数

  • 额外的参数(超过 6 个参数)通过 传递。

    • 这些参数从栈中读取,栈的增长方向是向下(地址减小)。

2. 浮点参数传递

浮点数参数(如 float、double)通过 SSE 寄存器 传递:


  • 前 8 个浮点数参数(float 和 double)使用 XMM 寄存器传递,按顺序依次存放:

    • XMM0:第一个浮点数参数
    • XMM1:第二个浮点数参数

    • XMM7:第八个浮点数参数

如果函数的参数超过了这些寄存器的数量,剩余的浮点数参数会通过栈传递。
3. 返回值传递



  • 整数返回值:函数返回值通常通过 RAX 寄存器返回。RAX 会保存返回值。
  • 浮点返回值:如果函数返回的是浮点数值(如 float 或 double),则使用 XMM0 寄存器来存储返回值。
4. 栈帧和栈的使用



  • 在每个函数调用时,调用者 会将其参数(如果超出 6 个整数或 8 个浮点数)压入栈中。
  • 被调用者 负责保存其用到的寄存器,尤其是那些它会修改的寄存器(例如,RBX、R12 到 R15 寄存器是被调用者保存的寄存器)。
  • 调用者和被调用者通过约定保持栈平衡,确保栈在函数返回时是精确的。
5. 寄存器的使用约定



  • RAX:返回值寄存器。函数的返回值通过此寄存器传递。
  • RCX、RDX、R8、R9:用于传递函数参数(前 6 个整数参数中,RDI 到 R9 使用这 5 个寄存器)。
  • R10-R15:这些寄存器是临时寄存器,调用者需要包管它们的值。如果调用函数不需要修改这些寄存器,调用者可以使用这些寄存器。
  • RBX、RBP、R12-R15:这些寄存器是被调用者保存的寄存器,如果一个函数要修改这些寄存器,必须在返回之前恢复它们的值。
6. 栈对齐

在 x86_64 架构下,栈必须 按 16 字节对齐。这意味着每次函数调用时,栈指针 (rsp) 必须是 16 的倍数。为此,调用者在调用之前可能需要调整栈指针,确保栈对齐。这个对齐要求对于向内存中传递参数(特别是浮点数参数)非常紧张。
7. 调用和返回过程

函数调用:


  • 参数传递:起首,将前 6 个参数传递到相应的寄存器中,如果有更多参数,调用者会将它们压入栈中。
  • 保存寄存器:调用者保存需要保存的寄存器(如 RBX、R12 到 R15)和栈帧。
  • 跳转到被调用函数:执行函数调用指令(如 call),跳转到被调用函数。
  • 栈帧建立:被调用函数建立自己的栈帧,保存必要的寄存器(如 RBX、R12 到 R15)。
  • 执行函数体:函数体开始执行。
函数返回:


  • 返回值传递:被调用函数将返回值放入 RAX 或 XMM0(浮点数)。
  • 恢复寄存器:被调用函数恢复调用时保存的寄存器,确保返回时栈平衡。
  • 跳转返回:被调用函数执行 ret 指令,跳回调用者处。
8. 总结:

在 x86_64 架构下的 Linux 系统中,函数调用约定的关键要点如下:


  • 前 6 个整数参数通过 寄存器(RDI 到 R9)传递。
  • 前 8 个浮点数参数通过 SSE 寄存器(XMM0 到 XMM7)传递。
  • 如果参数超过了这些数量,剩余的参数通过 传递。
  • 返回值:整数通过 RAX 返回,浮点数通过 XMM0 返回。
  • 栈对齐:栈必须按 16 字节对齐。
  • 寄存器使用:有些寄存器是调用者保存的(如 RBX、R12 到 R15),而有些是被调用者保存的(如 RBP)。
syscall

在 x64 架构下,syscall 是用来触发系统调用的指令。x64 系统调用遵循特定的约定来传递参数和执行操作,这些约定包罗通过寄存器传递参数和选择系统调用编号。
x64 系统调用约定

在 x64 架构下,系统调用的参数会通过以下寄存器传递:


  • rax: 系统调用号(syscall number)
  • rdi: 第一个参数
  • rsi: 第二个参数
  • rdx: 第三个参数
  • r10: 第四个参数
  • r8: 第五个参数
  • r9: 第六个参数
syscall 指令通过 rax 寄存器来指定调用的系统调用编号,rdi, rsi, rdx 等寄存器则用来传递参数。
1. 一个简单的 x64 syscall 示例

假设我们想执行 exit 系统调用(调用号 60),并返回一个退出代码。我们需要将 60 放入 rax 寄存器,将退出码放入 rdi 寄存器。
  1. mov rax, 60         ; 系统调用号 (60: exit)
  2. mov rdi, 0          ; 退出码 0
  3. syscall             ; 调用系统调用
复制代码


  • rax = 60:表现调用 exit 系统调用。
  • rdi = 0:表现传递的参数(退出码 0)。
  • syscall:触发系统调用。
2. 更复杂的系统调用:execve

另一个常见的系统调用是 execve(执行一个程序)。execve 的系统调用号是 59,它需要三个参数:


  • rdi: 程序路径
  • rsi: 参数数组(argv)
  • rdx: 环境变量数组(envp)
例如,要执行 /bin/sh 并传递一个空的参数和环境变量列表,我们可以构建以下汇编代码:
  1. section .data
  2.     sh_path db '/bin/sh', 0        ; 程序路径
  3.     argv db '/bin/sh', 0           ; 参数数组,只有一个元素(路径本身)
  4.     envp db 0                      ; 环境变量数组(空)
  5. section .text
  6.     global _start
  7. _start:
  8.     ; 设置 execve 参数
  9.     mov rax, 59         ; 系统调用号 (59: execve)
  10.     mov rdi, sh_path    ; 将程序路径 '/bin/sh' 传递给 rdi
  11.     mov rsi, argv       ; 将参数数组传递给 rsi
  12.     mov rdx, envp       ; 将环境变量数组传递给 rdx
  13.     syscall             ; 执行系统调用
复制代码
3. 关于系统调用号

不同的操作系统和架构有不同的系统调用号。例如,在 Linux x64 上,常见的系统调用号包罗:
系统调用系统调用号 (rax)exit60execve59read0write1open2close3 你可以查阅相关文档(如 Linux 系统调用表)来找到系统调用号。
4. 组合 syscall 和 shellcraft

pwntools 的 shellcraft 模块可以帮助你快速生成包含系统调用的汇编代码。如果你在举行漏洞使用,通常会使用这个模块来生成 syscall 相关的汇编代码。例如,如果你想执行 execve("/bin/sh"),可以使用 pwntools 来生成汇编代码:
  1. from pwn import *
  2. context(arch='amd64', os='linux')
  3. # 生成 execve("/bin/sh") 系统调用的 shellcode
  4. shellcode = shellcraft.execve('/bin/sh')
  5. # 查看汇编代码
  6. print(shellcode)
  7. # 查看机器码
  8. print(asm(shellcode))
复制代码
生成的汇编代码会主动处置惩罚传递参数并触发系统调用。
5. 总结



  • syscall 是用来触发系统调用的指令。
  • x64 架构下,系统调用号存储在 rax 寄存器,其他参数存储在 rdi, rsi, rdx, r10, r8, r9 寄存器中。
  • 常见的系统调用如 exit, execve 都需要使用 syscall 指令来触发。
通过这些汇编技巧,你可以构建各种系统调用来与操作系统交互,执行文件、操作文件描述符、获取系统信息等。在举行漏洞使用时,明白系统调用是很紧张的,由于它们提供了和操作系统举行交互的根本方式。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

自由的羽毛

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表