【发布时间】:2019-12-12 19:37:22
【问题描述】:
我正在尝试从 Android Studio 3.4.2 为 aarch64 运行一些内联汇编代码,但出现编译错误 error: Don't know how to handle indirect register inputs yet for constraint 'r'。
我的代码sn-p如下
std::string system_file = "/system/bin/sh";
std::int64_t file_descriptor = -1;
#ifdef __aarch64__
__asm__ volatile("mov x8, #180\n\t"
"mov x0, %1\n\t"
"mov x1, #0\n\t"
"svc #1\n\t"
"mov %0, x0\n\t"
:"=r"(file_descriptor)
:"r"(system_file)
:"x0","x1","x8"
);
#endif
基于本文的 ARM64 系统调用
https://reverseengineering.stackexchange.com/questions/16917/arm64-syscalls-table
取自
https://github.com/torvalds/linux/blob/v4.17/include/uapi/asm-generic/unistd.h
我不确定错误是由于 Android Studio 还是我在这里做错了什么?任何建议表示赞赏。
**** 编辑 ****
我想我可能一直在查看错误的系统调用号。相反,我应该看看
#define __NR_openat 56
__SC_COMP(__NR_openat, sys_openat, compat_sys_openat)
现在我正在尝试这样做,但似乎是错误的。
std::string system_file = "/system/bin/sh";
const char *ptr = system_file.c_str();
std::int64_t file_descriptor = 0;
register std::int64_t x8 asm("x8") = 56;
register std::int64_t x0 asm("x0") = 0;
register std::int64_t x2 asm("x2") = 0;
__asm__ volatile("svc #1"
:"=r"(file_descriptor)
:"r"(x0),"r"(ptr),"r"(x2),"r"(x8)
:"memory"
);
__android_log_print(ANDROID_LOG_DEBUG,"native_code","file_descriptor: %i",file_descriptor);
我可以在 logcat 中看到一个数字“56”,但无论文件是否存在,它都是相同的数字。和系统调用号一样是巧合吗?
【问题讨论】:
-
我没有设置来测试这个,但您是否打算将字符串的 address 传递给调用?如果是这样,也许使用
system_file.c_str()? -
不要忘记使用
"memory"clobber 或虚拟输入操作数来告诉编译器您读取了system_file指向的内存。 (您不能将std::string按值放入一个寄存器中)。此外,您不需要也不应该在模板中使用任何mov指令:使用register long callnum asm("x0");等本地变量将您的输入/输出放在正确的寄存器中。例如iOS ARM64 Syscalls 有点好。与 Linux 电话号码相同的内联汇编应该可以工作。 -
这是一个 AArch64 Linux 示例:How to specify an individual register as constraint in ARM GCC inline assembly?
-
@PeterCordes - 我正在为此尝试使用本地寄存器变量。我无法确认的一件事是
svc指令可能会破坏(r0 除外)的哪些寄存器(如果有)。例如,我知道 amd64 clobbers rcx 和 r11,但找不到 arm64 的类似参考。它会留下其他一切吗? -
@DavidWohlferd:对于 Linux,我认为是这样。默认情况下,Linux 保留除 return val 之外的所有 reg,除非 syscall 指令本身破坏了一些(如 x86-64
syscall)。 iOS 显然最多可以返回 2 个寄存器并修改标志以指示错误与否,但 Linux 系统调用只使用 1 个 reg 作为返回值,并使用返回值 >= unsigned-4095对错误“带内”进行编码
标签: android-studio assembly inline-assembly arm64