我是Aarch64程序集的新手(但我知道x86程序集的一些基础知识)。我正在尝试写一些类似于" shellcode"在Android OS上。
将此shellcode注入另一个函数。它应该使用/data/local/tmp/AAABBBCCC
和execve
创建文件/system/bin/sh -c
。在我的情况下,我不必关心空字节。
在execve
来电之前,我发了一个系统调用open_at
(O_CREAT
和O_EXCL
)并在/data/local/tmp/
中创建另一个文件(我加载了地址使用adr x1, path
)的文件名。
...
call to open_at
...
// push terminating 0
mov x1, 0
str x1, [sp, #-16]!
// push arg2
adr x1, arg2
str x1, [sp, #-16]!
// push arg1
adr x1, arg1
str x1, [sp, #-16]!
// push arg0
adr x1, arg0
str x1, [sp, #-16]!
// call execve
adr x0, command
ldr x1, [sp]
mov x2, 0
mov x8, SYS_EXECVE
svc 0
...
.balign 4
command:
.string "/system/bin/sh"
arg0:
.string "/system/bin/sh"
arg1:
.string "-c"
arg2:
.string "/system/bin/touch /data/local/tmp/AAABBCCC"
我知道对于x86,你需要使用带有CALL
指令的技巧来获取第一个字符串的地址,以便在堆栈上创建参数数组,因为如果你像我在这里使用的那样使用标签,标签的地址包含在指令操作码中,注入后它们无效。但这应该是一个不同的情况,对吗?指令ADR
应该是与pc相关的,并且在其操作码中我看不到任何地址,只是相对距离。
当我将代码注入函数时,对open_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
感谢您的回答!
答案 0 :(得分:2)
在我发布这个问题几分钟后,我意识到错误在哪里。
在堆栈上创建参数数组的正确方法是使用STP指令。它一次存储两个寄存器(之前我错误地使用了它 - 我以错误的顺序提供了寄存器)。它应该这样做:
mov x1, 0
adr x2, arg2
stp x2, x1, [sp, #-16]!
adr x1, arg1
adr x2, arg0
stp x2, x1, [sp, #-16]!