linux_x64 下的一般汇编函数与syscall调用约定

news2024/12/19 22:31:27

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

1. 参数传递

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

  • 前 6 个整数参数(包括 intcharlong 等)通过 寄存器 传递:
    • RDI:第一个参数
    • RSI:第二个参数
    • RDX:第三个参数
    • RCX:第四个参数
    • R8:第五个参数
    • R9:第六个参数
  • 额外的参数(超过 6 个参数)通过 传递。
    • 这些参数从栈中读取,栈的增长方向是向下(地址减小)。

2. 浮点参数传递

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

  • 前 8 个浮点数参数floatdouble)使用 XMM 寄存器传递,按顺序依次存放:
    • XMM0:第一个浮点数参数
    • XMM1:第二个浮点数参数
    • XMM7:第八个浮点数参数

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

3. 返回值传递

  • 整数返回值:函数返回值通常通过 RAX 寄存器返回。RAX 会保存返回值。
  • 浮点返回值:如果函数返回的是浮点数值(如 floatdouble),则使用 XMM0 寄存器来存储返回值。

4. 栈帧和栈的使用

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

5. 寄存器的使用约定

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

6. 栈对齐

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

7. 调用和返回过程

函数调用:
  1. 参数传递:首先,将前 6 个参数传递到相应的寄存器中,如果有更多参数,调用者会将它们压入栈中。
  2. 保存寄存器:调用者保存需要保留的寄存器(如 RBXR12R15)和栈帧。
  3. 跳转到被调用函数:执行函数调用指令(如 call),跳转到被调用函数。
  4. 栈帧建立:被调用函数建立自己的栈帧,保存必要的寄存器(如 RBXR12R15)。
  5. 执行函数体:函数体开始执行。
函数返回:
  1. 返回值传递:被调用函数将返回值放入 RAXXMM0(浮点数)。
  2. 恢复寄存器:被调用函数恢复调用时保存的寄存器,确保返回时栈平衡。
  3. 跳转返回:被调用函数执行 ret 指令,跳回调用者处。

8. 总结:

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

  • 前 6 个整数参数通过 寄存器RDIR9)传递。
  • 前 8 个浮点数参数通过 SSE 寄存器XMM0XMM7)传递。
  • 如果参数超过了这些数量,剩余的参数通过 传递。
  • 返回值:整数通过 RAX 返回,浮点数通过 XMM0 返回。
  • 栈对齐:栈必须按 16 字节对齐。
  • 寄存器使用:有些寄存器是调用者保存的(如 RBXR12R15),而有些是被调用者保存的(如 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 寄存器。

mov rax, 60         ; 系统调用号 (60: exit)
mov rdi, 0          ; 退出码 0
syscall             ; 调用系统调用
  • rax = 60:表示调用 exit 系统调用。
  • rdi = 0:表示传递的参数(退出码 0)。
  • syscall:触发系统调用。

2. 更复杂的系统调用:execve

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

  • rdi: 程序路径
  • rsi: 参数数组(argv
  • rdx: 环境变量数组(envp

例如,要执行 /bin/sh 并传递一个空的参数和环境变量列表,我们可以构建以下汇编代码:

section .data
    sh_path db '/bin/sh', 0        ; 程序路径
    argv db '/bin/sh', 0           ; 参数数组,只有一个元素(路径本身)
    envp db 0                      ; 环境变量数组(空)

section .text
    global _start

_start:
    ; 设置 execve 参数
    mov rax, 59         ; 系统调用号 (59: execve)
    mov rdi, sh_path    ; 将程序路径 '/bin/sh' 传递给 rdi
    mov rsi, argv       ; 将参数数组传递给 rsi
    mov rdx, envp       ; 将环境变量数组传递给 rdx
    syscall             ; 执行系统调用

3. 关于系统调用号

不同的操作系统和架构有不同的系统调用号。例如,在 Linux x64 上,常见的系统调用号包括:

系统调用系统调用号 (rax)
exit60
execve59
read0
write1
open2
close3

你可以查阅相关文档(如 Linux 系统调用表)来找到系统调用号。

4. 组合 syscallshellcraft

pwntoolsshellcraft 模块可以帮助你快速生成包含系统调用的汇编代码。如果你在进行漏洞利用,通常会使用这个模块来生成 syscall 相关的汇编代码。例如,如果你想执行 execve("/bin/sh"),可以使用 pwntools 来生成汇编代码:

from pwn import *

context(arch='amd64', os='linux')

# 生成 execve("/bin/sh") 系统调用的 shellcode
shellcode = shellcraft.execve('/bin/sh')

# 查看汇编代码
print(shellcode)

# 查看机器码
print(asm(shellcode))

生成的汇编代码会自动处理传递参数并触发系统调用。

5. 总结

  • syscall 是用来触发系统调用的指令。
  • x64 架构下,系统调用号存储在 rax 寄存器,其他参数存储在 rdi, rsi, rdx, r10, r8, r9 寄存器中。
  • 常见的系统调用如 exit, execve 都需要使用 syscall 指令来触发。

通过这些汇编技巧,你可以构建各种系统调用来与操作系统交互,执行文件、操作文件描述符、获取系统信息等。在进行漏洞利用时,理解系统调用是很重要的,因为它们提供了和操作系统进行交互的基本方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2262384.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【自动化】Python SeleniumUtil 油猴 工具 自动安装用户脚本

【自动化】Python SeleniumUtil 油猴 工具 【自动化】Python SeleniumUtil 工具-CSDN博客【自动化】Python SeleniumUtil 工具。https://blog.csdn.net/G971005287W/article/details/144565691 油猴工具 import timefrom selenium.webdriver.support.wait import WebDriverW…

盛元广通畜牧与水产品检验技术研究所LIMS系统

一、系统概述 盛元广通畜牧与水产品检验技术研究所LIMS系统集成了检测流程管理、样品管理、仪器设备管理、质量控制、数据记录与分析、合规性管理等功能于一体,能够帮助实验室实现全流程的数字化管理。在水产、畜牧产品的质检实验室中,LIMS系统通过引入…

clickhouse-数据库引擎

1、数据库引擎和表引擎 数据库引擎默认是Ordinary,在这种数据库下面的表可以是任意类型引擎。 生产环境中常用的表引擎是MergeTree系列,也是官方主推的引擎。 MergeTree是基础引擎,有主键索引、数据分区、数据副本、数据采样、删除和修改等功…

GEE+本地XGboot分类

GEE本地XGboot分类 我想做提取耕地提取,想到了一篇董金玮老师的一篇论文,这个论文是先提取的耕地,再做作物分类,耕地的提取代码是开源的。 但这个代码直接在云端上进行分类,GEE会爆内存,因此我准备把数据下…

Docker搭建kafka环境

系统:MacOS Sonoma 14.1 Docker版本:Docker version 27.3.1, build ce12230 Docker desktop版本:Docker Desktop 4.36.0 (175267) 1.拉取镜像 先打开Docker Desktop,然后在终端执行命令 docker pull lensesio/fast-data-dev …

校园点餐订餐外卖跑腿Java源码

简介: 一个非常实用的校园外卖系统,基于 SpringBoot 和 Vue 的开发。这一系统源于黑马的外卖案例项目 经过站长的进一步改进和优化,提供了更丰富的功能和更高的可用性。 这个项目的架构设计非常有趣。虽然它采用了SpringBoot和Vue的组合&am…

Linux文件属性 --- 硬链接、所有者、所属组

三、硬链接数 1.目录 使用“ll”命令查看,在文件权限的后面有一列数字,这是文件的硬链接数。 对于目录,硬链接的数量是它具有的直接子目录的数量加上其父目录和自身。 下图的“qwe”目录就是“abc”目录的直接子目录。 2.文件 对于文件可…

Centos7 部署ZLMediakit

1、拉取代码 #国内用户推荐从同步镜像网站gitee下载 git clone --depth 1 https://gitee.com/xia-chu/ZLMediaKit cd ZLMediaKit #千万不要忘记执行这句命令 git submodule update --init 2、安装编译器 sudo yum -y install gcc 3、安装cmake sudo yum -y install cmake 4…

无管理员权限 LCU auth-token、port 获取(全网首发 go)

一: 提要: 参考项目: https://github.com/Zzaphkiel/Seraphine 想做一个 lol 查战绩的软件,并且满足自己的需求(把混子和大爹都表示出来),做的第一步就是获取 lcu token ,网上清一色…

《云原生安全攻防》-- K8s安全框架:认证、鉴权与准入控制

从本节课程开始,我们将来介绍K8s安全框架,这是保障K8s集群安全比较关键的安全机制。接下来,让我们一起来探索K8s安全框架的运行机制。 在这个课程中,我们将学习以下内容: K8s安全框架:由认证、鉴权和准入控…

spring\strust\springboot\isp前后端那些事儿

后端 一. 插入\更新一条数据&#xff08;老&#xff09; Map<String, Object> parameterMap MybatisUtil.initParameterSave("Send_ProjectFrozenLog", sendProjectFrozenLog); commonMapper.insert(parameterMap);parameterMap MybatisUtil.initParameter…

UE5安装Fab插件

今天才知道原来Fab也有类似Quixel Bridge的插件&#xff0c;于是立马就安装上了&#xff0c;这里分享一下安装方法 在Epic客户端 - 库 - Fab Library 搜索 Fab 即可安装Fab插件 然后重启引擎&#xff0c;在插件面板勾选即可 然后在窗口这就有了 引擎左下角也会多出一个Fab图标…

对于使用exe4j打包,出现“NoClassDefFoundError: BOOT-INF/classes”的解决方案

jar使用exe4j打包exe&#xff0c;出现NoClassDefFoundError: BOOT-INF/classes 注意选取的jar包是使用build&#xff0c;而不是maven中的install 本文介绍解决这个方法的方案 点击Project Structure 按照如图所示选择 选择main class&#xff0c;选择你要打的main 如果遇到/M…

文件上传之文件内容检测

一.基本概念 介绍&#xff1a;文件内容检测就是检测上传的文件里的内容。 文件幻数检测 通常情况下&#xff0c;通过判断前10个字节&#xff0c;基本就能判断出一个文件的真实类型。 文件加载检测 一般是调用API或函数对文件进行加载测试。常见的是图像渲染测试&#xff0c;再…

WebSpoon9.0(KETTLE的WEB版本)编译 + tomcatdocker部署 + 远程调试教程

前言 Kettle简介 Kettle是一款国外开源的ETL工具&#xff0c;纯Java编写&#xff0c;可以在Window、Linux、Unix上运行&#xff0c;绿色无需安装&#xff0c;数据抽取高效稳定 WebSpoon是Kettle的Web版本&#xff0c;由Kettle社区维护&#xff0c;不受Pentaho支持&#xff0c;…

搭建Tomcat(三)---重写service方法

目录 引入 一、在Java中创建一个新的空项目&#xff08;初步搭建&#xff09; 问题&#xff1a; 要求在tomcat软件包下的MyTomcat类中编写main文件&#xff0c;实现在MyTomcat中扫描myweb软件包中的所有Java文件&#xff0c;并返回“WebServlet(url"myFirst")”中…

CAN配置---波特率中断引脚等---autochips-AC7811-ARM-M3内核

1、配置工具 虽然不怎么好用&#xff0c;但比没有强多了。具体看图&#xff1a; 时钟选着 NVIC配置 GPIO配置 2、生成的具体配置信息 NXP的配置工具里面&#xff0c;具体的波特率可以直接显示&#xff0c;这个工具没有&#xff0c;怎么办&#xff1f; 它放到了生成的代码里面…

matlab Patten的使用(重要)(Matlab处理字符串一)

原文连接&#xff1a;https://www.mathworks.com/help/releases/R2022b/matlab/ref/pattern.html?browserF1help 能使用的搜索函数&#xff1a; contains确定字符串中是否有模式matches确定模式是否与字符串匹配count计算字符串中模式的出现次数endsWith确定字符串是否以模式…

Docker创建一个mongodb实例,并用springboot连接 mongodb进行读写文件

一、通过Docker 进行运行一个 mongodb实例 1、拉取镜像 docker pull mongo:5.0.5 2、创建 mongodb容器实例 docker run -d --name mongodb2 \-e MONGO_INITDB_ROOT_USERNAMEsalaryMongo \-e MONGO_INITDB_ROOT_PASSWORD123456 \-p 27017:27017 \mongo:5.0.5 3、进入容器&am…

#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍02-基于错误消息的SQL注入(Error-Based SQL Injection)

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…