为什么我的 Android 应用程序(具有 root 权限)无法访问 /dev/input?

2024-04-18

我的应用程序针对已root的Android设备,它具有root权限并且需要访问该目录/dev/input,但为什么它会抛出opendir failed, Permission denied even /dev/input已经是chmod to 777?

我使用下面的代码来获取root权限:

Process root = Runtime.getRuntime().exec("su");

并使用下面的代码来更改权限/dev/input:

Shell.runCommand("chmod 777 /dev/input");

上面两个步骤都成功了,但是为什么我的应用程序仍然无法访问它?经过搜索,有人说应用程序的运行时权限与文件系统中文件的权限无关。 Android运行时的权限系统是怎样的?我怎样才能让应用程序能够访问/dev/input?

添加:

我的测试环境是Android 5.1.1,主要部分代码为:

jint Java_com_foo_funnyapp_Native_scanInputDevicesJNI(JNIEnv* env, jclass clazz)
{
    const char *dirname = "/dev/input";

    DIR *dir;
    dir = opendir(dirname); // opendir failed, Permission denied
    if(dir == NULL)
        return -1;

    ......

    return 0;
}

SELinux 错误来自/prog/kmsg

<36>[19700411_05:32:43.957165]@0 type=1400 audit(8631163.939:1105): avc: denied { write } for pid=15706 comm="app_process64_o" name="system@[email protected] /cdn-cgi/l/email-protection" dev="mmcblk0p43" ino=442379 scontext=u:r:shell:s0 tcontext=u:object_r:dalvikcache_data_file:s0 tclass=file permissive=0
<11>[19700411_05:32:44.118202]@0 init: untracked pid 15674 exited with status 0
<11>[19700411_05:32:44.202288]@0 init: untracked pid 15704 exited with status 224
<36>[19700411_05:32:44.225334]@0 type=1400 audit(8631164.209:1106): avc: denied { read } for pid=15734 comm="Thread-111" name="input" dev="tmpfs" ino=12525 scontext=u:r:untrusted_app:s0 tcontext=u:object_r:input_device:s0 tclass=dir permissive=0
<36>[19700411_05:32:44.332135]@0 type=1400 audit(8631164.319:1107): avc: denied { write } for pid=15742 comm="app_process64_o" name="system@[email protected] /cdn-cgi/l/email-protection" dev="mmcblk0p43" ino=442379 scontext=u:r:shell:s0 tcontext=u:object_r:dalvikcache_data_file:s0 tclass=file permissive=0

正如评论中所指出的,除了 Linux 文件权限之外,现代 Android 还有许多额外的防御层。其中之一是 SELinux。

即使拥有提升的权限,围绕 SELinux 进行工作也很困难相当复杂 https://su.chainfire.eu/#selinux——它是专门为了防止这种情况而设计的。所有 Android SELinux 设置都存储在修改过的单个文件中sepolicy https://android.googlesource.com/platform/external/sepolicy/格式。该文件是只读系统映像的一部分,修补它基本上等同于对设备进行 root。几乎只有从事超级用户应用程序开发的人才是超级用户应用程序的开发人员,例如 SuperSu 或this one https://github.com/phhusson/Superuser.

我建议您利用已安装的 su 应用程序已经完成的任何操作,而不是尝试自己克服 SELinux。例如,SuperSu 在不受限制的 SELinux 上下文中运行传递给它的命令(请参阅上面 Chainfire 站点的链接),本质上就好像 SELinux 不存在一样。这允许您通过 su 运行专门的二进制文件来克服 SELinux,这会为您完成肮脏的工作。

遗憾的是,可用于此类纯本机二进制文件的公共高级 API 非常少。您可以使用 Linux 内核系统调用和一些 C 库函数……仅此而已。幸运的是,如果您想要的只是打开一堆受保护的文件,则无需在本机帮助程序二进制文件中移动大量逻辑。相反,您可以使用“开放服务器”库,例如this one https://github.com/Alexander--/fdshare:

Context context = ...

try (FileDescriptorFactory factory = FileDescriptorFactory.create(context);
     ParcelFileDescriptor fd = factory.open("/dev/input", 2))
{
  // the file descriptor is yours, as if you have gotten it by
  // calling ParcelFileDescriptor#open
  // You can use it from Java or pass to native code to read/write/ioctl on it
  ...
} catch (FactoryBrokenException oups) {
    // most likely the root access being denied
    ...
} catch (IOException ioerr) {
    ...
}

免责声明:我是链接库的作者。

“开放服务器”的概念非常简单:

  1. 普通的 Android 应用程序会创建一个Linux 域套接字 http://developer.android.com/reference/android/net/LocalServerSocket.html
  2. 普通 Android 应用程序通过系统“su”启动二进制文件
  3. 二进制文件连接到套接字
  4. 二进制文件读取应用程序写入套接字的文件名并打开它们
  5. 二进制文件通过相同的套接字将所述文件的文件描述符发送到应用程序(该技术也称为“文件描述符传递” https://google.com/search?q=file+descriptor+passing)

只要安装的“su”应用程序成功克服 SELinux 并为通过它运行的命令提供不受限制的上下文,这个巧妙的技巧就会起作用。我所知道的所有现代人都是如此。


EDIT: 这个答案已经写了很久了。最新的 Android sepolicy 格式不再被视为“修改”,它们的更改已成功上游(幽默地导致创建完后还有向后不兼容的 sepolicy 格式)。上面链接的库总体上仍然可以正常工作,但它的功能受到现代 SEAndroid 策略的进一步限制,因此您可能对其感兴趣新迭代 https://github.com/chdir/fdutil。事实上,SELinux 策略对每个人强制执行额外的检查read/write除了标准 Unix 检查之外open,使用共享内存和 Linux 管道来仔细解决该策略可能是更明智的做法,而不是将原始描述符传递给调用者。

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

为什么我的 Android 应用程序(具有 root 权限)无法访问 /dev/input? 的相关文章

  • 使用 Eclipse 的 Android“Hello World”教程

    我尝试编写我的第一个应用程序 Hello World 我已经遇到了一个无法修复的错误 当我运行该程序时 我得到 无效的命令行参数 文件 提示 使用 foo 启动名为 foo 的虚拟设备 请使用 help 获取更多信息 有谁知道这意味着什么以
  • 如何从屏幕上的任意位置拖动底页?

    我正在尝试实现类似 YouTube 的体验 并允许用户从屏幕中的任何位置拖动底部工作表 我尝试了很多解决方案没有任何帮助 我终于从这个解决方案中找到了解决方案在外部区域达到阈值后允许 BottomSheet 向上滑动 https stack
  • 在 Android 中打开受密码保护的 ZIP?

    有没有一个库或一个简单的方法如何在 Android 中打开受密码保护的 ZIP 存档 我知道 ZIP 加密有不同类型 我想打开最简单的一个 在 Unix 中使用以下命令创建zip e命令 可以在 Windows 中打开相同的文件 将要求输入
  • React Native:由于 SoLoader 问题,应用程序在启动时崩溃

    我的 Android 应用程序出现问题 iOS 运行正常 每次我进行构建时 当我打开应用程序时 它会在开始之前关闭 我已经在Github和这里尝试了很多我一直在寻找的解决方案 但我还没有能够解决它 安装是干净的 我已经检查过没有遗漏任何东西
  • 更改 Android 软键盘示例设计、按钮和背景图像

    我正在通过修改 SDK 中的 android 软键盘示例来构建自定义键盘 我想更改按钮和背景的图像 但我无法弄清楚这些值的存储位置 它们存储在哪里或者我如何更改图像或简单的颜色 在 onClick 方法中 您需要更改按钮的图像 这样 pub
  • 自定义用户代理字符串或标头,无需修改 cordova 库

    我有一个与 ASP NET MVC Web 应用程序交互的 Android Phonegap Cordova 应用程序 我正在尝试检测服务器端是否从浏览器或我的 Phonegap Cordova 应用程序加载网页 我考虑过以下几种方法 更改
  • 变量名称后面的“-”(破折号)在这里有什么作用?

    if n BASH o n ZSH VERSION then hash r 2 gt dev null fi 我在哪里可以找到这方面的参考资料 谢谢 a 内的变量 称为 参数扩展 搜索该词在在线手册中 https man cx bash h
  • 如何找到某个命令的目录?

    我知道 当您使用 shell 时 唯一可以使用的命令是可以在 PATH 上设置的某些目录中找到的命令 即使我不知道如何查看 PATH 变量上的目录 这是另一个可以回答的好问题 我想知道的是 我来到 shell 并写道 lshw 我想知道 s
  • Android NDK r5b外部构建和supc++链接问题

    我正在尝试在 Ubuntu 10 10 上使用 r5b NDK 为 Android 平台交叉编译我们的 C 代码库 使用 CMake 编译阶段成功 但是在 so 的最终链接阶段 有许多对 libsupc a 文件 我指定链接到的文件 中的符
  • Apache HttpClient 摘要式身份验证

    基本上我需要做的是执行摘要身份验证 我尝试的第一件事是可用的官方示例here http svn apache org repos asf httpcomponents httpclient tags 4 0 1 httpclient src
  • Linux 上的最大子进程数

    下面的代码将产生尽可能多的子级 自己不会进一步fork 一旦父进程退出就会变成僵尸 父进程将产生多少个子进程 int main int argc char arg while fork gt 0 子进程的数量可以通过以下方式限制设置限制 2
  • 如何为 ActionBar 的 ActionMode 背景设置动画?

    背景 可以更改操作栏的背景 甚至可以在两种颜色之间设置动画 如下所示 public static void animateBetweenColors final ActionBar actionBar final int colorFrom
  • Linux 上的 Chrome - 查询浏览器以查看打开了哪些选项卡?

    我在 Ubuntu Linux 上运行 Chromium 开源 chrome 版本 我可以编写一个程序来查看我打开了哪些选项卡吗 我想编写一个程序来监控我在事情上花费了多少时间 是否有命令行程序 某种调用 chromium browser
  • java.lang.IndexOutOfBoundsException:无效索引 7,大小为 7

    我正在尝试实现视图寻呼机 在我的视图寻呼机图像来自服务器 我能够显示和滚动 但当我到达最后一个图像时 它显示错误并且应用程序崩溃 以下是我的代码片段 public class Test Pager extends Activity priv
  • 在我的 Linux 机器上安装 lisp

    我使用 Vim 作为我的编辑器 Practical common Lisp 建议安装 Lispbox 我不知道如何使用 emacs 不知道如何用那个 T T 运行 lisp 代码 之后我找到了一个名为 limp vim 的 vim lisp
  • 每次我们想在应用程序中更改字体时,是否都必须复制 Font TTF

    以前 为了使我的应用程序可以在 Gingerbread 及以上设备中运行 我必须将 Robotto 字体资源复制到 asset 文件夹中 这是因为 Gingerbread 本身不附带 Robotto 字体 但是 假设我决定仅将我的应用程序部
  • 如何在 Android 上的 SharedPreferences 中保存/存储对象?

    我需要在很多地方获取用户对象 其中包含很多字段 登录后 我想保存 存储这些用户对象 我们如何实现这样的场景呢 我无法像这样存储它 SharedPreferences Editor prefsEditor myPrefs edit prefs
  • 窗口放置:适用于 Linux (KDE) 的类似 WinSplit Revolution 的应用程序? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 适用于 Linux KDE 的类似 WinSplit Revolution 的应用程序是什么 或者也许 KDE 中有一个我缺少的功能 平铺通常是窗口管
  • 如何从指纹扫描仪获取输入并保存[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我正在使用 Android Marshmallow 和 Moto G4 以及一台设备进行测试 我想创建一个应用程序 它将接受指纹输入并
  • 打算在 Android 上打开 Instagram 用户个人资料

    我正在开发一款社交网络应用程序 我们的用户可以将他们的 Instagram 帐户连接到我们的服务 我想直接在他们的官方 Android 应用程序 如果已安装 中打开 Instagram 个人资料 但我找不到任何方法来做到这一点 然而 有一个

随机推荐

  • android中的react-native-snap-carousel上手动水平滚动的问题

    我正在使用react native snap carousel来显示横幅 它在 iOS 中的手动滚动和间隔后自动滚动都运行良好 但在 Android 中手动滚动时面临两个问题 对于某些设备 特别是三星 它会卡在第三个索引处 手动完成时 但自
  • 在 Mac 上开发 .Net 应用程序? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我是 Net 开发人员 开始使用 Mac OS 我在这个系统上唯一怀念的是 VISUAL STUDIO 我不想使用两个系统 你认为如何开发 Ne
  • Impala 表中的压缩

    我想了解 Impala 表中的压缩 但找不到可供研究的材料 有哪些不同的技术以及我在哪里可以找到研究它的材料 主要技术为compaction是为了避免small file problem这取决于您的用例 例如 您可能有一个将小文件写入的进程
  • 函数式 GUI 编程可能吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我最近发现了 FP bug 试图学习 Haskell 到目前为止所看到的东西给我留下了深刻的印象 一流的函数 惰性求值和所有其他好处 我还不是专
  • Jfrog CLI 不尊重配置的 API 密钥

    我正在使用 Powershell DSC 设置 Windows Server 2012 R2 盒子 作为配置过程的一部分 我将配置 jfrog exe 并作为服务帐户执行配置命令 jfrog rt config url localArtif
  • 读取 WCF 消息正文两次 - “消息无法读取”

    我有一个 WCF 消息 Channels Message 我正在尝试使用 GetBody 提取正文 但是 我注意到我只能执行一次 如果我尝试再次使用 GetBody 我会收到 此消息无法支持该操作 因为它已被读取 知道如何重新阅读邮件正文吗
  • F# 有异步验证库吗?

    我在代码中经常使用 asyncResult 但它会在第一个错误时退出 asyncResult let a allGood let b thisReturnsError let c neverExecuted 但有时我想执行所有函数并总结错误
  • 具有多个条件的 SqlAlchemy 案例

    我正在尝试做这样的事情 x db session query Candidate func count case Jobs interview type PHONE SCREEN and Jobs interview type INCLIN
  • 补丁优先级及其对 Criminsi 基于范例的修复的影响

    我正在尝试实现基于示例的修复 如提议的Criminsi http research microsoft com pubs 67276 criminisi tip2004 pdf等等人 以其原始格式 在进行进一步优化之前 我有一些理论上的疑问
  • 从BackgroundWorker C# 更改控件的属性

    我正在尝试从目录加载一堆文件 在加载时显示进度条状态以及显示正在处理哪个文件的标签 private void FileWorker DoWork object sender DoWorkEventArgs e for int i 0 i l
  • 从 URL 加载图像

    我正在尝试根据以下教程在我的应用程序中加载一些图像 http www anddev org novice tutorials f8 imageview with loading spinner t49439 html http www an
  • NSIS 滚动许可证欢迎屏幕

    我的安装程序在与滚动许可证插件交互时遇到问题 安装程序在没有插件的情况下也能很好地工作 这就是插件让我包括的内容 include MUI nsh define MUI PAGE CUSTOMFUNCTION SHOW LicenseShow
  • 如何限制循环的迭代次数?

    假设我有一个项目列表 我想迭代其中的前几个 items list range 10 I mean this to represent any kind of iterable limit 5 简单的实现 来自其他语言的 Python 新手可
  • 从 Octave 导出的图中具有透明背景

    我在 Win 10 下使用便携式 Octave 5 1 0 我的意思是写一个具有透明背景的 png 绘图 免责声明 这个问题与下面链接的两个问题类似 我选择了提出当前不同的问题 https meta stackoverflow com qu
  • GCE - HTTP 负载平衡返回错误 502(错误网关) - 仅当通过 C# 发布时

    我们有一个 C 应用程序 可以获取数据并将其发布到我们的网站 在使用 Compute Engine 测试 HTTP 负载平衡时 我们遇到的唯一问题是当 C 应用程序尝试提交数据时返回 502 Bad Gateway HTTP 负载平衡中是否
  • 将名字和姓氏添加到 Django-Registration

    我使用的是默认的Djangoregistration 版本 0 8 在我的项目中 用户只需输入他们的用户名 电子邮件和密码 但是 我希望用户也在注册页面上输入他们的名字和姓氏 我怎样才能轻松做到这一点 您可以做的是覆盖默认的 UserReg
  • numpy reshape 是如何工作的?

    我有一个 numpy 数组中的数据 a np arange 100 a a reshape 20 5 当我打字时 a 10 它返回 array 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1
  • 为什么 sscanf() 不将 CSV 文件中的行读入数组?

    我正在尝试将 CSV 文件中的整数读入二维数组 这是我的代码 FILE fp fopen argv 1 r int counter 0 char line 50 while fgets line 50 fp counter int arry
  • msscript.ocx 从哪里安装

    我在我的应用程序中使用 msscript ocx 它是 Windows 的 ActiveX 脚本主机 尽管我希望能够对高度可定制的 XP 嵌入式 XPe 使用相同的功能 1 我想知道在XPe上是否可以选择性安装msscript ocx 2
  • 为什么我的 Android 应用程序(具有 root 权限)无法访问 /dev/input?

    我的应用程序针对已root的Android设备 它具有root权限并且需要访问该目录 dev input 但为什么它会抛出opendir failed Permission denied even dev input已经是chmod to