记一次蛋疼的App 调用su 之旅
背景
软件:AOSP Android 10 userdebug with sepolicy on;
硬件:无需关心;
事由:好朋友阿P说需要他的盒子调用su 实现不可告人的目的。
调试过程
代码
使用AndroidStudio 新建一个工程,基本一路默认,修改代码如下:
MainActivity.java
package com.nobita.su;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle; import android.util.Log;import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.InputStreamReader;public class MainActivity extends AppCompatActivity {private static final String TAG = "NOBITA";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}@Overrideprotected void onResume() {super.onResume();String result = runRootCommand("echo hello");Log.d(TAG, result);}private String runRootCommand(String command) {try {Process process = Runtime.getRuntime().exec("su");DataOutputStream os = new DataOutputStream(process.getOutputStream());os.writeBytes(command + "\n");os.writeBytes("exit\n");os.flush();process.waitFor();BufferedReader resultBuffReader = new BufferedReader(new InputStreamReader(process.getInputStream()));BufferedReader errorBuffReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));String line;StringBuilder sb = new StringBuilder();sb.append("result:\n");while ((line = resultBuffReader.readLine()) != null) {sb.append(line);sb.append("\n");}sb.append("error:\n");while ((line = errorBuffReader.readLine()) != null) {sb.append(line);sb.append("\n");}return sb.toString();} catch (Exception e) {e.printStackTrace();}return "error!";} }
调试
1. 默认配置调试
使用上述代码,默认其他配置(AndoridManifest、build.gradle 、 签名等),运行报错:
09-09 03:52:26.132 4710 4710 W System.err: java.io.IOException: Cannot run program "su": error=13, Permission denied
09-09 03:52:26.133 4710 4710 W System.err: at java.lang.ProcessBuilder.start(ProcessBuilder.java:1050)
09-09 03:52:26.133 4710 4710 W System.err: at java.lang.Runtime.exec(Runtime.java:698)
09-09 03:52:26.133 4710 4710 W System.err: at java.lang.Runtime.exec(Runtime.java:528)
09-09 03:52:26.133 4710 4710 W System.err: at java.lang.Runtime.exec(Runtime.java:425)
09-09 03:52:26.133 4710 4710 W System.err: at com.nobita.su.MainActivity.runRootCommand(MainActivity.java:30)
09-09 03:52:26.133 4710 4710 W System.err: at com.nobita.su.MainActivity.onResume(MainActivity.java:24)
09-09 03:52:26.134 4710 4710 W System.err: at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1453)
09-09 03:52:26.134 4710 4710 W System.err: at android.app.Activity.performResume(Activity.java:7941)
09-09 03:52:26.134 4710 4710 W System.err: at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4195)
09-09 03:52:26.134 4710 4710 W System.err: at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4237)
09-09 03:52:26.134 4710 4710 W System.err: at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52)
09-09 03:52:26.134 4710 4710 W System.err: at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
09-09 03:52:26.134 4710 4710 W System.err: at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
09-09 03:52:26.135 4710 4710 W System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
09-09 03:52:26.135 4710 4710 W System.err: at android.os.Handler.dispatchMessage(Handler.java:107)
09-09 03:52:26.135 4710 4710 W System.err: at android.os.Looper.loop(Looper.java:214)
09-09 03:52:26.135 4710 4710 W System.err: at android.app.ActivityThread.main(ActivityThread.java:7356)
09-09 03:52:26.135 4710 4710 W System.err: at java.lang.reflect.Method.invoke(Native Method)
09-09 03:52:26.136 4710 4710 W System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
09-09 03:52:26.136 4710 4710 W System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:995)
09-09 03:52:26.136 4710 4710 W System.err: Caused by: java.io.IOException: error=13, Permission denied
09-09 03:52:26.138 4710 4710 W System.err: at java.lang.UNIXProcess.forkAndExec(Native Method)
09-09 03:52:26.138 4710 4710 W System.err: at java.lang.UNIXProcess.<init>(UNIXProcess.java:133)
09-09 03:52:26.139 4710 4710 W System.err: at java.lang.ProcessImpl.start(ProcessImpl.java:141)
09-09 03:52:26.139 4710 4710 W System.err: at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
09-09 03:52:26.139 4710 4710 W System.err: ... 19 more
很遗憾,不能运行,查看callStack 发现是forkAndExec 不给运行,看起来跟系统权限相关。
2. 修改为su 可执行权限运行
上述默认配置告诉我们su
这个指令比较特殊,需要特殊权限才能运行,逆向思维一下,为何常规指令能够运行呢,做了一个小实验:
which pwd|xargs ls -l
lrwxr-xr-x 1 root shell 6 2022-09-09 02:52 /system/bin/pwd -> toybox
which su|xargs ls -l
-rwsr-x--- 1 root shell 11520 2022-09-09 02:10 /system/xbin/su
从其配置的权限来看,默认只有root、shell 才能运行,因此我们给su
others 加上可读可执行:
chmod o+rx $(which su) && ls -l $(which su)chmod o+rx /system/xbin //因为发现xbin 这个目录others 不可读不可执行
再次运行:
logcat 报错一致,接着查看dmesg发现:
[ 2131.476008] type=1400 audit(1662697533.946:93): avc: denied { execute } for comm="com.nobita.su" name="su" dev="mmcblk1p5" ino=3158 scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:su_exec:s0 tclass=file permissive=0 duplicate messages suppressed
3. 修改为shell 用户执行
看来我们第二部修改已经有所成效,已经可以确认即使修改su 可运行依然会碰撞到sepolicy 的问题,此时我跟阿P 沟通,记得修改fs_config.cpp
和sepolicy 哦,阿p 说这不行啊,这样要改动的东西太大了,而且还要OTA之后才能使用,不得行,遂进行接下来的实验。
AndroidManifest.xml 修改增加
android:sharedUserId="android.uid.shell"
:<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:sharedUserId="android.uid.shell"package="com.nobita.su">... ... ... ...
build.grade 修改增加系统签名配置:
signingConfigs {release {File strFile = new File("../sign-keys/debug.keystore")storeFile file(strFile)keyAlias 'platform'keyPassword 'android'storePassword 'android'}debug {File strFile = new File("../sign-keys/debug.keystore")storeFile file(strFile)keyAlias 'platform'keyPassword 'android'storePassword 'android'}}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'signingConfig signingConfigs.release}debug {signingConfig signingConfigs.debug}}
运行喜提一个tombsone:
09-09 04:46:49.281 5826 5826 E SELinux : seapp_context_lookup: No match for app with uid 2000, seinfo platform, name com.nobita.su 09-09 04:46:49.281 5826 5826 E SELinux : selinux_android_setcontext: Error setting context for app with uid 2000, seinfo platform:privapp:targetSdkVersion=29:complete: Success 09-09 04:46:49.281 3481 3510 I ActivityManager: Start proc 5826:com.nobita.su/2000 for activity {com.nobita.su/com.nobita.su.MainActivity} 09-09 04:46:49.281 5826 5826 F zygote64: jni_internal.cc:811] JNI FatalError called: (com.nobita.su) frameworks/base/core/jni/com_android_internal_os_Zygote.cpp:1097: selinux_android_setcontext(2000, 0, "platform:privapp:targetSdkVersion=29:complete", "com.nobita.su") failed 09-09 04:46:49.294 3301 3301 I display : Failed to commit pset ret=-22 09-09 04:46:49.304 5826 5826 F zygote64: runtime.cc:630] Runtime aborting...... ... ... ... 09-09 04:46:49.365 5835 5835 F DEBUG : Abort message: 'JNI FatalError called: (com.nobita.su) frameworks/base/core/jni/com_android_internal_os_Zygote.cpp:1097: selinux_android_setcontext(2000, 0, "platform:privapp:targetSdkVersion=29:complete", "com.nobita.su") failed'
4. 修改包名为com.android.shell 运行
继续逆向思维,为什么Shell 这个apk 能以shell 用户运行,但是我不行?查看了一下它的功能,发现基本可以干掉:
dumpsys package com.android.shell Receiver Resolver Table:Non-Data Actions:com.android.internal.intent.action.BUGREPORT_STARTED:a80b1ba com.android.shell/.BugreportReceiver filter 5851b84Action: "com.android.internal.intent.action.BUGREPORT_STARTED"Action: "com.android.internal.intent.action.BUGREPORT_FINISHED"com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED:ece886b com.android.shell/.RemoteBugreportReceiver filter 4271f6dAction: "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED"com.android.internal.intent.action.BUGREPORT_FINISHED:a80b1ba com.android.shell/.BugreportReceiver filter 5851b84Action: "com.android.internal.intent.action.BUGREPORT_STARTED"Action: "com.android.internal.intent.action.BUGREPORT_FINISHED"Provider Resolver Table:Non-Data Actions:android.content.action.DOCUMENTS_PROVIDER:942dfc8 com.android.shell/.BugreportStorageProvider filter b89c7a2Action: "android.content.action.DOCUMENTS_PROVIDER"Registered ContentProviders:com.android.shell/androidx.core.content.FileProvider:Provider{e586861 com.android.shell/androidx.core.content.FileProvider}com.android.shell/.BugreportStorageProvider:Provider{942dfc8 com.android.shell/.BugreportStorageProvider}ContentProvider Authorities:[com.android.shell.documents]:Provider{942dfc8 com.android.shell/.BugreportStorageProvider}applicationInfo=ApplicationInfo{7782f86 com.android.shell}[com.android.shell]:Provider{e586861 com.android.shell/androidx.core.content.FileProvider}applicationInfo=ApplicationInfo{7782f86 com.android.shell}... ... ... ...
接着build.gradle修改包名:
defaultConfig {applicationId "com.android.shell"... ... ... ...
这回运行终于不报错了,但是却报了su内部的错误:
09-09 05:07:26.646 6012 6012 D NOBITA : result: 09-09 05:07:26.646 6012 6012 D NOBITA : error: 09-09 05:07:26.646 6012 6012 D NOBITA : su: setgid failed: Operation not permitted
啊,好享受这种努力到最后一无所有的感受啊~
记一次蛋疼的App 调用su 之旅相关推荐
- App调用safar
/调用safar打开网页 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://www.cnblo ...
- 如何修改app服务器数据库连接,app调用服务器数据库连接
app调用服务器数据库连接 内容精选 换一换 GaussDB(for Influx)提供使用内网.公网.负载均衡和程序代码的连接方式. GaussDB(for MySQL)全兼容MySQL协议,因此, ...
- vue js 和原生app调用回调方法问题
vue js 和原生app调用回调方法问题 import Vue from 'vue' export default { name: 'list', components: { }, data: () ...
- android app调用第三方地图路线规划导航(百度,高德,腾讯)
android app调用第三方地图路线规划导航(百度,高德,腾讯) 因为直接使用高德的sdk提供的导航被投诉说不准,所以需要接第三方. 把BAT系的地图都接上了,有兄弟找到其他的地图调用方法告诉下小 ...
- apiCloud app调用浏览器打开网页的方法
在APP调用浏览器有两种方法: 1.使用openApp 2.使用openWin 两种方法调用浏览器后的效果有一点不同: 1.使用openApp调用浏览器后,如果手机内有多个浏览器,会首先弹出选择浏览器 ...
- APP调用支付宝支付
申请支付宝支付,获取appid,开发者私钥,开发者公钥,支付宝公钥 下载支付宝sdk : https://docs.open.alipay.com/54/106370/ 核心代码,$setNotify ...
- Android相机资源占用,为保护用户隐私Android 11调整相机选项 APP调用相机时只可使用默认相机...
据外媒报道目前谷歌在 Android 11 测试版里带来新的调整,此次调整是关于安卓系统对于默认相机调用选择的. 在安卓旧版本中当APP调用相机时会罗列用户已经安装的所有相机应用,这当然也包括那些自带 ...
- 可以两人一起记日记的共享记事本app有哪些
现代生活中,我们总会遇到一些美好的瞬间,想要把它们记录下来,留作回忆.而对于情侣.夫妻.朋友等一起生活的人们来说,共享一本日记本成为了一种特别的方式.但是,现实中很难有两个人同时在一本日记本上写下自己 ...
- app调用另一个app的方法
APP调用APP在编程应用中很常见,浏览了许多大神的文章,颇有心得.谢谢前辈们的总结.下面总结给自己: 主要的套路是:intent =packageManager.getLaunchIntentFor ...
- android 读取wps_安卓APP调用WPS打开Office文件并返回APP
原创文章:转载请注明出处 安卓APP调用WPS打开Office文件并返回APP功能实现(附wps工具) 在某些app(如OA系统app)开发工程中,往往会遇到编辑Office文档的需求,而我们一般采取 ...
最新文章
- 数学工具WZgrapher
- 为什么要学python语言_我们为什么要学习Python语言?
- opencv3 ubuntu安装脚本
- JS实现sleep功能 JS遍历document对象
- 解决Linux下vi或vim操作Found a swap file by the name
- JS 动态创建元素、删除元素、替换元素、修改元素
- Chronos首页、文档和下载 - 作业调度器 - 开源中国社区
- Q99:当Bezier曲面(Utah Teapot)同时遇上“噪声纹理”和“Phong反射模型”
- 第二章 人工智能专题之Python进阶 - Matplotlib库
- while循环python次数定义_Python学习笔记之While循环用法分析
- bin to npy
- dos2unix install on mac_费德勒和瑞士运动品牌On昂跑合作推出以网球为灵感的高科技运动鞋...
- Phalloidin——Acti-stain555鬼笔环肽研究
- Git 六 时光穿梭机
- BZOJ 4031 HEOI2015 小Z的房间 Matrix-Tree定理
- 【MySQL】6、Delete From删除语句
- Android APP如何实现支付宝支付
- Android中APK打包流程
- 线程与进程之间的共享资源
- 08 基础代谢率计算
热门文章
- dell服务器新bois系统设置u盘启动,跟大家讲讲dell新版biosU盘启动顺序
- 研究生实证论文数据经验分享
- JavaScript 原形链
- iTunes下载的ipa文件的目录位置
- android mac地址不可用,Android手机里的mac地址显示不可用是为什么。我的手机是海信E920....
- 加装固态硬盘后计算机不显示,安装固态硬盘后无法读取,如何解决?
- python ip地址处理_Python学习笔记-IP地址处理模块Ipy
- Ubuntu20.04.iso光盘镜像源文件百度云下载
- rust编程 UI框架 -druid -Selector选择器
- Contect、SharedPreferences及Intent学习小记