ARM64程序集 - 在堆栈上执行参数

时间:2018-04-09 16:07:34

标签: assembly stack arm64 shellcode execve

我是Aarch64程序集的新手(但我知道x86程序集的一些基础知识)。我正在尝试写一些类似于" shellcode"在Android OS上。

将此shellcode注入另一个函数。它应该使用/data/local/tmp/AAABBBCCCexecve创建文件/system/bin/sh -c。在我的情况下,我不必关心空字节。

execve来电之前,我发了一个系统调用open_atO_CREATO_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

感谢您的回答!

1 个答案:

答案 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]!