Android Studio 64位嵌入式ARM程序集 [英] Android Studio 64 bit inline ARM assembly

查看:168
本文介绍了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 ****

我认为我可能一直在查看错误的syscall号码.相反,我应该看看

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天全站免登陆