Android 中的 SYSCALL_INLINE

2024-03-13

我需要在 Android NDK 内部使用系统调用来防止包装函数的挂钩。 在 Linux 中,有像 SYSCALL_INLINE 这样的宏,它允许在没有包装函数的情况下使用系统调用。因此,宏将系统调用汇编代码直接嵌入到项目中。

我在 Android NDK 中找不到类似的宏。

也许我可以编写自己的函数,就像这样;https://git.busybox.net/uClibc/tree/libc/sysdeps/linux/arm/syscall.c https://git.busybox.net/uClibc/tree/libc/sysdeps/linux/arm/syscall.c

但我需要有相同功能的arm、arm_64、x86和x86_64版本。

你能帮助我吗?我怎样才能找到解决方案?


Android 的 Linux 内核仍然使用与常规 Linux 相同的系统调用号和 ABI,不是吗? (所以如何从用户空间访问系统调用? https://stackoverflow.com/questions/11609110/how-to-access-the-system-call-from-user-space)所以你应该能够使用正常的方法,电话号码来自<asm/unistd.h>.

您可以使用 MUSL libc 系统调用内联函数arch/x86_64/syscall_arch.h http://git.musl-libc.org/cgit/musl/tree/arch/x86_64/syscall_arch.h。对于每个不同数量的参数,它都有不同的参数,而不是一个大的参数。


MUSL 有以下版本syscall_arch.h for ARM http://git.musl-libc.org/cgit/musl/tree/arch/arm/syscall_arch.h、AArch64、i386 和 x86-64,以及它支持的其他架构。它已获得许可宽松的麻省理工学院许可证 http://www.musl-libc.org/intro.html,因此您只需复制这些标头即可。

例如,他们的 ARM 版本定义了__asm_syscall作为一个宏(在非 Thumb 模式下)asm volatile("svc 0" : "=r"(r0) : inputs); return r0;,并定义包装器,例如:

static inline long __syscall3(long n, long a, long b, long c)
{
    register long r7 __ASM____R7__ = n;  // macro trickery for not clobbering r7 in thumb mode (where it may be the frame pointer)
    register long r0 __asm__("r0") = a;
    register long r1 __asm__("r1") = b;
    register long r2 __asm__("r2") = c;
    __asm_syscall(R7_OPERAND, "0"(r0), "r"(r1), "r"(r2));
    // includes "=r0"(r0) and return r0
 // FIXME: add a "memory" clobber because pointed-to memory can be an input or output
}

不幸的是,这并不安全:这不会告诉编译器指针操作数已被取消引用,因此它可能会在之前将存储处理到缓冲区中write()作为死店并优化它们!

解决这个问题很简单:添加一个"memory"破坏。或者看如何指示可以使用内联 ASM 参数*指向*的内存? https://stackoverflow.com/questions/56432259/how-can-i-indicate-that-the-memory-pointed-to-by-an-inline-asm-argument-may-be对于仅告诉编译器一个操作数的方法,对于特定的系统调用,您知道哪些操作数是指针以及它们是输入、输出还是两者。

我不知道这是否是 glibc 删除类似系统调用宏并仅提供非内联系统调用的动机的一部分function。或者也许他们不想鼓励人们将系统调用 ABI 嵌入到他们的程序中,这样理论上它就可以在未来变得更加高效。

你会像这样使用它

#include <asm/unistd.h>   // for __NR_write
#include <stdlib.h>       // for ssize_t
#include "syscall_arch.h"

// doesn't set errno or force all error returns to -1
// return values from -1 to -4095 are errors, e.g. -EBADF or -EFAULT

__attribte__((noinline))  // hack for inline asm unsafety
ssize_t my_write(int fd, const void *buf, size_t count) {
    return __syscall3(__NR_write, fd, (long)buf, count);
}

我把这个在 Godbolt 编译器资源管理器上 https://gcc.godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(j:1,lang:c%2B%2B,source:%27%23define+__SYSCALL_LL_E(x)+%5C%0D%0A((union+%7B+long+long+ll%3B+long+l%5B2%5D%3B+%7D)%7B+.ll+%3D+x+%7D).l%5B0%5D,+%5C%0D%0A((union+%7B+long+long+ll%3B+long+l%5B2%5D%3B+%7D)%7B+.ll+%3D+x+%7D).l%5B1%5D%0D%0A%23define+__SYSCALL_LL_O(x)+0,+__SYSCALL_LL_E((x))%0D%0A%0D%0A%23ifdef+__thumb__%0D%0A%0D%0A/*+Avoid+use+of+r7+in+asm+constraints+when+producing+thumb+code,%0D%0A+*+since+it!%27s+reserved+as+frame+pointer+and+might+not+be+supported.+*/%0D%0A%23define+__ASM____R7__%0D%0A%23define+__asm_syscall(...)+do+%7B+%5C%0D%0A%09__asm__+__volatile__+(+%22mov+%251,r7+%3B+mov+r7,%252+%3B+svc+0+%3B+mov+r7,%251%22+%5C%0D%0A%09:+%22%3Dr%22(r0),+%22%3D%26r%22((int)%7B0%7D)+:+__VA_ARGS__+:+%22memory%22)%3B+%5C%0D%0A%09return+r0%3B+%5C%0D%0A%09%7D+while+(0)%0D%0A%0D%0A%23else%0D%0A%0D%0A%23define+__ASM____R7__+__asm__(%22r7%22)%0D%0A%23define+__asm_syscall(...)+do+%7B+%5C%0D%0A%09__asm__+__volatile__+(+%22svc+0%22+%5C%0D%0A%09:+%22%3Dr%22(r0)+:+__VA_ARGS__+:+%22memory%22)%3B+%5C%0D%0A%09return+r0%3B+%5C%0D%0A%09%7D+while+(0)%0D%0A%23endif%0D%0A%0D%0A/*+For+thumb2,+we+can+allow+8-bit+immediate+syscall+numbers,+saving+a%0D%0A+*+register+in+the+above+dance+around+r7.+Does+not+work+for+thumb1+where%0D%0A+*+only+movs,+not+mov,+supports+immediates,+and+we+can!%27t+use+movs+because%0D%0A+*+it+doesn!%27t+support+high+regs.+*/%0D%0A%23ifdef+__thumb2__%0D%0A%23define+R7_OPERAND+%22rI%22(r7)%0D%0A%23else%0D%0A%23define+R7_OPERAND+%22r%22(r7)%0D%0A%23endif%0D%0A%0D%0A%0D%0Astatic+inline+long+__syscall3(long+n,+long+a,+long+b,+long+c)%0D%0A%7B%0D%0A%09register+long+r7+__ASM____R7__+%3D+n%3B%0D%0A%09register+long+r0+__asm__(%22r0%22)+%3D+a%3B%0D%0A%09register+long+r1+__asm__(%22r1%22)+%3D+b%3B%0D%0A%09register+long+r2+__asm__(%22r2%22)+%3D+c%3B%0D%0A%09__asm_syscall(R7_OPERAND,+%220%22(r0),+%22r%22(r1),+%22r%22(r2))%3B%0D%0A%7D%0D%0A%0D%0A%23include+%3Cstdlib.h%3E%0D%0A%23include+%3Casm/unistd.h%3E%0D%0A//%23include+%22syscall_arch.h%22%0D%0A//+doesn!%27t+set+errno+or+force+all+error+returns+to+-1%0D%0A//+return+values+from+-1+to+-4095+are+errors,+e.g.+-EBADF+or+-EFAULT%0D%0Assize_t+my_write(int+fd,+const+void+*buf,+size_t+count)+%7B%0D%0A++++return+__syscall3(__NR_write,+fd,+(long)buf,+count)%3B%0D%0A%7D%0D%0A%27),l:%275%27,n:%270%27,o:%27C%2B%2B+source+%231%27,t:%270%27)),k:52.32368921824802,l:%274%27,n:%270%27,o:%27%27,s:0,t:%270%27),(g:!((g:!((h:compiler,i:(compiler:armhfg54,filters:(b:%270%27,binary:%271%27,commentOnly:%270%27,demangle:%270%27,directives:%270%27,execute:%271%27,intel:%270%27,trim:%271%27),lang:c%2B%2B,libs:!(),options:%27-xc+-O3+-std%3Dgnu11+-Wall+-Wextra+-mcpu%3Dcortex-a53+-marm%27,source:1),l:%275%27,n:%270%27,o:%27ARM+gcc+5.4+(linux)+(Editor+%231,+Compiler+%231)+C%2B%2B%27,t:%270%27)),k:47.67631078175198,l:%274%27,m:50,n:%270%27,o:%27%27,s:0,t:%270%27),(g:!((h:output,i:(compiler:1,editor:1,wrap:%271%27),l:%275%27,n:%270%27,o:%27%231+with+ARM+gcc+5.4+(linux)%27,t:%270%27)),header:(),l:%274%27,m:50,n:%270%27,o:%27%27,s:0,t:%270%27)),k:47.67631078175198,l:%273%27,n:%270%27,o:%27%27,t:%270%27)),l:%272%27,n:%270%27,o:%27%27,t:%270%27)),version:4有足够的ARMsyscall_arch.h复制以进行编译。 Godbolt 的一些 ARM gcc 安装丢失<asm/unistd.h>,但是 gcc5.4 有一个可以工作的。 ARM模式下的结果是:

my_write:
    str     r7, [sp, #-4]!
    mov     r7, #4
@ system-calling convention mostly matches function-calling convention
@ so args are in the right registers already
    svc 0
    ldr     r7, [sp], #4
    bx      lr

当然,这个函数可以内联到调用者中,这样保存/恢复r7整个函数发生一次。

(编辑):如果内联到调用者中,这将是不安全的,死存储可能会被优化掉。更好的强力选项是在内联 asm 语句上使用内存破坏器,或者更多的工作是为读取或写入用户空间内存的系统调用添加虚拟内存操作数(请参阅).或者为了munmap确保没有存储到正在释放的页面中并在内存取消映射后发生。

即使没有内联,它的过程间优化也使得这不是严格安全的,所以__attribute__((noinline,noipa)),或者只是使用"memory"破坏在asm陈述!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 中的 SYSCALL_INLINE 的相关文章

  • 如何在 Android 中保存相机的临时照片?

    在尝试从相机拍照并将其保存到应用程序的缓存文件夹中时 我没有得到任何可见的结果 应用程序不会崩溃 但在 LogCat 上 当我尝试将 ImageView src 字段设置为刚刚获取的文件的 URI 时 我收到此消息 09 17 14 03
  • 如何重试已消耗的 Observable?

    我正在尝试重新执行失败的已定义可观察对象 一起使用 Retrofit2 和 RxJava2 我想在单击按钮时重试特定请求及其订阅和行为 那可能吗 service excecuteLoginService url tokenModel Ret
  • 如何创建可获取数字的小矮人计算机 (LMC) 代码。奇数时显示1,偶数时显示0

    我的研究需要帮助 如果数字是偶数 它可以显示 1 如果数字是奇数 它可以显示 0 例如 如果输入是 99 它将显示输出 1 这意味着奇数 如果我显示 10 它将显示输出 0 这意味着偶数 我没有任何代码 因为我不知道如何开始 请帮忙 我对这
  • CardView 圆角获得意想不到的白色

    When using rounded corner in CardView shows a white border in rounded area which is mostly visible in dark environment F
  • 谷歌坐标认证

    当我尝试连接到 Google 坐标时 总是出现异常GoogleAuthException 我拥有 Google 地图协调中心许可证 我确实使用我的包应用程序名称和 SHA1 在 google 控制台中创建了我的客户端 ID 我将权限添加到清
  • java.lang.NoClassDefFoundError:org.apache.batik.dom.svg.SVGDOMImplementation

    我在链接到我的 Android LibGDX 项目的 Apache Batik 库时遇到了奇怪的问题 但让我们从头开始 在 IntelliJ Idea 中我有一个项目 其中包含三个模块 Main Android 和 Desktop 我强调的
  • Android Activity 生命周期函数基础知识

    我正在测试这段代码 它显示活动所处的状态 public class Activity101Activity extends Activity String tag Lifecycle Called when the activity is
  • Android SIP 来电使用带有广播接收器的服务

    大家好 其实我正在尝试创建一个应用程序 支持基于 SIP 通过互联网进行音频呼叫 这里使用本机 sip 我遇到了来电问题 我已经完成了服务的注册部分 但是在接听电话时我无法接听电话 请帮助我 Service file package exa
  • 是否必须删除 Intent extra?

    这可能是一个愚蠢的问题 但是是否有一条规则规定消费活动必须显式删除 Intent 额外内容 或者只有在回收 Intent 对象时才如此 换句话说 如果我总是通过执行以下操作来链接到下一个活动 Intent i new Intent MyCu
  • Android:捕获的图像未显示在图库中(媒体扫描仪意图不起作用)

    我遇到以下问题 我正在开发一个应用程序 用户可以在其中拍照 附加到帖子中 并将图片保存到外部存储中 我希望这张照片也显示在图片库中 并且我正在使用媒体扫描仪意图 但它似乎不起作用 我在编写代码时遵循官方的Android开发人员指南 所以我不
  • 获取当前 android.intent.category.LAUNCHER 活动的实例

    我创建了一个库项目 并在多个应用程序之间共享 我实现了一个简单的会话过期功能 该功能将在一段时间后将用户踢回到登录屏幕 登录屏幕活动是我的主要活动 因此在清单中它看起来像这样
  • Ubuntu 16.04 - Genymotion:找不到 /dev/hw_random

    I install Genymotion on the Ubuntu 16 04 64Bit I created a virtual emulator for Android 6 0 then I run this emulator but
  • 在两个活动之间传输数据[重复]

    这个问题在这里已经有答案了 我正在尝试在两个不同的活动之间发送和接收数据 我在这个网站上看到了一些其他问题 但没有任何问题涉及保留头等舱的状态 例如 如果我想从 A 类发送一个整数 X 到 B 类 然后对整数 X 进行一些操作 然后将其发送
  • 字符串数组文本格式化

    我有这个字符串 String text Address 1 Street nr 45 Address 2 Street nr 67 Address 3 Street nr 56 n Phone number 000000000 稍后将被使用
  • Android向menuItem添加子菜单,addSubMenu()在哪里?

    我想根据我的参数以编程方式将 OptionsMenu 内的子菜单添加到 menuItem 中 我检查了android sdk中的 MenuItem 没有addSubMenu 方法 尽管你可以找到 hasSubMenu 和 getSubMen
  • 在activity_main.xml中注释

    我是安卓新手 据我所知 XML 中的注释与 HTML 中的注释相同 使用 形式 我想在 Android 项目的 Activity main xml 配置文件中写一些注释 但它给了我错误 值得注意的是 我使用的是 Eclipse 但目前 我直
  • 如何确定对手机号码的呼叫是本地呼叫还是 STD 或 ISD

    我正在为 Android 开发某种应用程序 但不知道如何获取被叫号码是本地或 STD 的号码的数据 即手机号码检查器等应用程序从哪里获取数据 注意 我说的是手机号码 而不是固定电话 固定电话号码 你得到的数字是字符串类型 因此 您可以获取号
  • 实现滚动选择 ListView 中的项目

    我想使用 ListView 您可以在其中滚动列表来选择一个项目 它应该像一个 Seekbar 但拇指应该是固定的 并且您必须使用该栏来调整它 我面临的一个问题是 我不知道这种小部件是如何调用的 这使得我很难搜索 所以我制作了下面这张图片 以
  • android sdk 的位置尚未在 Windows 操作系统的首选项中设置

    在 Eclipse 上 我转到 windows gt Android SDK 和 AVD Manager 然后弹出此消息 Android sdk 的位置尚未在首选项中设置 进入首选项 在侧边栏找到 Android 然后会出现一个 SDK 位
  • Crashlytics 出现 Android Studio 构建错误

    我正在尝试将 CrashLytics 与 Android Studio 和 gradle 一起使用 但出现一个令人困惑的错误 java lang NoSuchMethodError 我的 build gradle 是 buildscript

随机推荐

  • 从 C# 运行 Bash 命令

    我试图弄清楚如何从在 IIS 7 Net 4 5 上运行的 C 运行 bash 命令 我一直在网上搜索 很多答案都假设您已经安装 就位了某些东西 我已经有了Git 1 9 4 msysgit 2与 Git Bash 和 Git Giu 一起
  • 如何列出 iOS 中开放的端口?

    我正在使用一个 已越狱设备 我想要写一个应用程序列出打开的端口 例如 TCP 端口 我有两个想法 使用一些本机 API 获取打开的端口列表 执行 shell 命令以获取打开的端口列表并解析此 shell 命令的结果 我应该使用哪个 API
  • 如何在 recyclerview 上设置 OnClickListener 而不取决于位置

    我希望 onclicklistener 方法打开与对象相关的活动 entidad1 entidad2 或 entidad3 MainActivity java 上的 OnRecipe 方法 我希望它能够实现 如果 entidad1 出现 它
  • 根据插入时间从 std::map 中删除元素

    我需要根据插入时间 或其他比这更有效的方法 从 std map 中删除元素 该地图可能会包含数千个元素 如果我存储时间并迭代地图以检查每个元素的时间 那么最终可能会非常耗时 有谁知道如何在 std map 变老时删除它们 The std m
  • double 是否会使方程中的每个 int 都加倍?

    是否存在一种浮点数据类型 例如double 确保所有 等数学运算都假定双操作数 如果故事比这更复杂 是否有描述这些规则的资源 我是否应该不问这样的问题并始终明确地投射int to double当方程的结果是double 这是我正在考虑的一些
  • 首次加载时仅加载一次广告 (div)

    我想知道如何才能让一个 div 具有要加载的广告或仅在第一次加载页面时可见 但每次刷新页面时隐藏它 我只有用 Jquery 加载 div 的代码 但不知道刷新页面后如何隐藏它 document ready function referral
  • UINavigationBar自定义过渡动画

    我使用以下协议在视图控制器之间创建了自定义转换 UIViewControllerAnimatedTransitioning and UIViewControllerTransitioningDelegate 是否可以使用默认的UINavig
  • 是什么让这两个数组相加不同?

    我用它来获取用户输入并清理代码 我试图解决这个问题 然后代码停止工作 这有效 BindVar array BindVar Email BindVar pass 然而 这并没有 BindVar array Email pass 这是当我更改该
  • Flask-SQLAlchemy 小写索引 - 跳过功能,SQLAlchemy 反射不支持

    首先 如果这个问题已经得到解答 我深表歉意 但我在任何地方都找不到答案 我需要在 Flask SQLAlchemy 对象上定义一个小写索引 我遇到的问题是我需要将模型用户名和电子邮件字段存储为小写 以便我可以检查它们User query f
  • DI Singleton 实例与 Transient 实例

    几年前 IoC 性能指南指出 IoC 容器应仅用于解析长期实例 基本上是单例 而应使用单例工厂 由容器保存 创建瞬态类型对象 我现在正在阅读有关 ASP NET Core 的内容 我看到的几个示例对其注入的对象使用瞬态生命周期 现在瞬态是提
  • 如何在 Meteor 提供的服务器中设置环境变量?

    我想在远程服务器上测试流星谷歌分析包 设置 json public ga account UA dfgddhdh 5 在本地服务器中 我只是传入 settings选项 我在看http meteorpedia com read Environ
  • 如何在各种单独的文件中分离与特定模式匹配的文件名和内容

    我试图将与特定模式匹配的文件名分离到一个单独的文件中 并将其内容分离到与特定模式匹配的不同文件中 我的文件名包含特殊字符 如 我尝试使用 grep 命令 Grep Ril 和 Grep H 打印文件名 但它不起作用 bin bash cd
  • Flutter,后台获取包不工作,androidx 不兼容

    我想在应用程序未运行时进行一些操作 所以我决定使用后台提取包 我一步步按照android设置 这是我的 pubspec yaml 的一部分 version 1 0 0 1 environment sdk gt 2 1 0 lt 3 0 0
  • 在 C++ 中编写可移植动态可加载库的最简单方法是什么?

    我正在开发一个具有多个相似代码路径的项目 我想将其从主项目中分离到插件中 该项目必须保持跨平台兼容 并且我研究过的所有动态库加载 API 都是特定于平台的 创建一个无需额外修改代码即可在多个操作系统上编译和运行的动态库加载系统的最简单方法是
  • 如何使用卡图生成概述国家的世界地图

    我最近一直在看卡图仪 据我所知 我们使用 kartograph py 生成 svg 然后使用 kartograph js 中的 svg 在 Web 界面中渲染地图 我想生成这样的东西http kartograph org showcase
  • 自动加载类的父类是否调用 __autoload() ?

    In main php 添加自动加载并创建一个新对象 function autoload class require once class php t new Triangle side1 side2 side3 In Triangle p
  • python:改变“全局变量”以动态地将事物放入范围内

    这是多么可怕的想法 班级monad实施with将事物放入和超出范围的接口 因此我可以编写一个通用函数库 例如 m chain 引用函数unit and bind谁可以在运行时放入实现 所有这些代码的作用或它是否是一个好主意并不重要 我尝试过
  • 如何从应用程序(布局)XML 变量中获取清单版本号?

    我希望有一种方法可以在代码的主要部分引用项目的清单版本号 到目前为止 我一直在做的是将字符串 XML 文件中的版本号链接到清单 string Version 我想要做的是反过来 将字符串 XML 变量链接到清单中的版本 原因 我只想更改一个
  • iOS Webrtc - 捕获本地视频流时崩溃

    我正在尝试使用 Google 存储库中的 webrtc 库 我按照这些步骤创建了一个单独的项目 其中包含类似于 APPRTC 的说明和代码 并且我能够让它工作 我能够在两台设备之间进行会议 但是当我尝试与旧项目集成时 Webrtc 崩溃了
  • Android 中的 SYSCALL_INLINE

    我需要在 Android NDK 内部使用系统调用来防止包装函数的挂钩 在 Linux 中 有像 SYSCALL INLINE 这样的宏 它允许在没有包装函数的情况下使用系统调用 因此 宏将系统调用汇编代码直接嵌入到项目中 我在 Andro