Assembly ARM64程序集-堆栈上的execve参数
我不熟悉Aarch64汇编(但我知道x86汇编的一些基础知识)。我正在尝试在Android操作系统上编写类似“外壳代码”的东西 这个外壳代码被注入到另一个函数中。它应该使用Assembly ARM64程序集-堆栈上的execve参数,assembly,stack,arm64,shellcode,execve,Assembly,Stack,Arm64,Shellcode,Execve,我不熟悉Aarch64汇编(但我知道x86汇编的一些基础知识)。我正在尝试在Android操作系统上编写类似“外壳代码”的东西 这个外壳代码被注入到另一个函数中。它应该使用execve和/system/bin/sh-c创建一个文件/data/local/tmp/AAABBBCCC。在我的例子中,我不必关心空字节 在调用execve之前,我进行一个系统调用open_at(使用O_create和O_EXCL)并在/data/local/tmp/中创建另一个文件(我使用adr-x1,path加载文件名
execve
和/system/bin/sh-c
创建一个文件/data/local/tmp/AAABBBCCC
。在我的例子中,我不必关心空字节
在调用execve
之前,我进行一个系统调用open_at
(使用O_create
和O_EXCL
)并在/data/local/tmp/
中创建另一个文件(我使用adr-x1,path
加载文件名的地址)
我知道,对于x86,为了在堆栈上创建参数数组,需要使用CALL
指令的技巧获取第一个字符串的地址,因为如果像我在这里所做的那样使用标签,标签的地址包含在指令操作码中,并且在注入之后它们是无效的。但这应该是另一种情况,对吗?指令ADR
应该是pc相关的,在其操作码中我看不到任何地址,只是相对距离
当我将代码注入函数时,调用open\u at
总是成功,并创建文件。但是,从不创建应由execve
创建的文件
在Aarch64上,在堆栈上为execve
创建参数数组的正确方法是什么?堆栈必须是16对齐的,所以我尝试每次推送两个参数(使用STP
),但这也不起作用
注入代码是使用aarch64 linux android工具链生成的,如下所示:
as -o code.o code.asm
objcopy -O binary code.bin code.o
xxd -i code.bin
mov x1, 0
adr x2, arg2
stp x2, x1, [sp, #-16]!
adr x1, arg1
adr x2, arg0
stp x2, x1, [sp, #-16]!
谢谢你的回答 在我发布这个问题几分钟后,我意识到错误在哪里 在堆栈上创建参数数组的正确方法是使用STP指令。它一次存储两个寄存器(我以前用错了——我以错误的顺序提供了寄存器)。应该这样做:
as -o code.o code.asm
objcopy -O binary code.bin code.o
xxd -i code.bin
mov x1, 0
adr x2, arg2
stp x2, x1, [sp, #-16]!
adr x1, arg1
adr x2, arg0
stp x2, x1, [sp, #-16]!
您是否尝试过使用
strace
来理解代码执行的系统调用?或者您可以使用[sp,#-8]
一次推送一个值,而不是存储8个字节并将SP递减16。但是,是的,stp
显然更好,因为它速度快并且节省了全部指令。真的吗?如果你看这个,“问题”标题下的第一个代码列表,以“损坏的AArch64实现…”
开头,说它不起作用…啊,谢谢,我不太了解AArch64;谢谢你的链接。我不知道在任何时候都需要16字节的堆栈对齐,并且由硬件强制执行!(显然可以通过特权代码禁用:)这是一个有趣的特性;我想知道为什么他们会这样做,而不是像x86和其他ISA那样,让调用约定来要求/保证堆栈对齐。