Android Studio 64 位内联 ARM 程序集 [英] Android Studio 64 bit inline ARM assembly

查看:43
本文介绍了Android Studio 64 位内联 ARM 程序集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从 Android Studio 3.4.2 为 aarch64 运行一些内联​​汇编代码,但出现编译错误 错误:尚不知道如何处理约束 'r' 的间接寄存器输入.

I am trying to run some inline assembly code for aarch64 from Android Studio 3.4.2 and I got a compilation error error: Don't know how to handle indirect register inputs yet for constraint 'r'.

我的代码片段如下

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 系统调用

ARM64 syscalls based on this article

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 还是我在这里做错了什么?任何建议表示赞赏.

I am not sure if the error is due to Android Studio or am I doing something wrong here? Any advice is appreciated.

**** 编辑 ****

**** EDIT ****

我想我可能看错了系统调用号.相反,我应该看看

I think I may have been looking at the wrong syscall number. Instead, I should be looking at

#define __NR_openat 56
__SC_COMP(__NR_openat, sys_openat, compat_sys_openat)

现在我正在尝试这样做,但似乎是错误的.

Now I am trying to do this and it seems to be wrong.

    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",但无论文件是否存在,它都是相同的数字.和系统调用号一样是巧合吗?

I can see a number "56" returned in logcat but it is the same number regardless the file exists or not. Is it a coincidence that it is the same as the syscall number?

推荐答案

作为一般规则,您希望尽可能多地将代码移出内联组件.例如,在本例中,您将 #180 移至 x8 以指示要调用的服务编号.但是如果你想连续打开 2 个文件,两次都在 x8 中传递 180 怎么办?理想情况下,如果可以,您希望避免将相同的值设置两次到同一个寄存器中,对吗?但是通过将 mov 放在 asm 中,您每次都强制设置该值.

As a general rule, you want to move as much of the code out of the inline asm as possible. In this case for instance, you are moving #180 to x8 to indicate the service number to invoke. But what if you want to open 2 files in a row, passing 180 in x8 both times? Ideally you'd want to avoid setting the identical value into the same register twice if you could, right? But by putting the mov inside the asm, you are forcing the value to be set every time.

您可以通过将作业移出 asm 来避免这种情况.虽然我没有 arm64 平台来运行它,但 Godbolt 的输出看起来是正确的:

You can avoid that by moving the assignments out of the asm. While I don't have an arm64 platform to run this on, the output from godbolt looks right:

std::string system_file = "/system/bin/sh";
const char *ptr  = system_file.c_str();
register std::int64_t file_descriptor asm("x0");
register std::int64_t x8 asm("x8") = 180;
register std::int64_t x1 asm("x1") = 0;

__asm__ volatile("svc #1"
                :"=r"(file_descriptor)
                :"0"(ptr),"r"(x1),"r"(x8)
                :"memory"
                );

由于 x1 和 x8 被列为输入(即在第二个冒号之后),gcc 假定它们的值不变.而且由于赋值是在 C 代码中进行的,它也知道那里有什么值.

Since x1 and x8 are listed as inputs (ie after the 2nd colon), gcc assumes their value is unchanged. And since the assignments took place in C code, it knows what values are there too.

0"可能看起来有点奇怪,但它表示 ptr 将与参数 #0 位于同一位置(即 file_descriptor,它使用 asm("x0")).所以输入将是ptr,输出将是file_descriptor,并且都使用相同的寄存器.

The "0" might look a bit odd, but it's saying that ptr will be in the same place as parameter #0 (ie file_descriptor, which uses asm("x0")). So the input will be ptr, the output will be file_descriptor, and both use the same register.

我还要提一下,我见过的所有 svc 示例都使用 svc #0.

I'll also mention that all the svc samples I've seen use svc #0.

这篇关于Android Studio 64 位内联 ARM 程序集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆