背景

  • 软件: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 才能运行,因此我们给suothers 加上可读可执行:

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 之旅相关推荐

  1. App调用safar

    /调用safar打开网页 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"http://www.cnblo ...

  2. 如何修改app服务器数据库连接,app调用服务器数据库连接

    app调用服务器数据库连接 内容精选 换一换 GaussDB(for Influx)提供使用内网.公网.负载均衡和程序代码的连接方式. GaussDB(for MySQL)全兼容MySQL协议,因此, ...

  3. vue js 和原生app调用回调方法问题

    vue js 和原生app调用回调方法问题 import Vue from 'vue' export default { name: 'list', components: { }, data: () ...

  4. android app调用第三方地图路线规划导航(百度,高德,腾讯)

    android app调用第三方地图路线规划导航(百度,高德,腾讯) 因为直接使用高德的sdk提供的导航被投诉说不准,所以需要接第三方. 把BAT系的地图都接上了,有兄弟找到其他的地图调用方法告诉下小 ...

  5. apiCloud app调用浏览器打开网页的方法

    在APP调用浏览器有两种方法: 1.使用openApp 2.使用openWin 两种方法调用浏览器后的效果有一点不同: 1.使用openApp调用浏览器后,如果手机内有多个浏览器,会首先弹出选择浏览器 ...

  6. APP调用支付宝支付

    申请支付宝支付,获取appid,开发者私钥,开发者公钥,支付宝公钥 下载支付宝sdk : https://docs.open.alipay.com/54/106370/ 核心代码,$setNotify ...

  7. Android相机资源占用,为保护用户隐私Android 11调整相机选项 APP调用相机时只可使用默认相机...

    据外媒报道目前谷歌在 Android 11 测试版里带来新的调整,此次调整是关于安卓系统对于默认相机调用选择的. 在安卓旧版本中当APP调用相机时会罗列用户已经安装的所有相机应用,这当然也包括那些自带 ...

  8. 可以两人一起记日记的共享记事本app有哪些

    现代生活中,我们总会遇到一些美好的瞬间,想要把它们记录下来,留作回忆.而对于情侣.夫妻.朋友等一起生活的人们来说,共享一本日记本成为了一种特别的方式.但是,现实中很难有两个人同时在一本日记本上写下自己 ...

  9. app调用另一个app的方法

    APP调用APP在编程应用中很常见,浏览了许多大神的文章,颇有心得.谢谢前辈们的总结.下面总结给自己: 主要的套路是:intent =packageManager.getLaunchIntentFor ...

  10. android 读取wps_安卓APP调用WPS打开Office文件并返回APP

    原创文章:转载请注明出处 安卓APP调用WPS打开Office文件并返回APP功能实现(附wps工具) 在某些app(如OA系统app)开发工程中,往往会遇到编辑Office文档的需求,而我们一般采取 ...

最新文章

  1. 数学工具WZgrapher
  2. 为什么要学python语言_我们为什么要学习Python语言?
  3. opencv3 ubuntu安装脚本
  4. JS实现sleep功能 JS遍历document对象
  5. 解决Linux下vi或vim操作Found a swap file by the name
  6. JS 动态创建元素、删除元素、替换元素、修改元素
  7. Chronos首页、文档和下载 - 作业调度器 - 开源中国社区
  8. Q99:当Bezier曲面(Utah Teapot)同时遇上“噪声纹理”和“Phong反射模型”
  9. 第二章 人工智能专题之Python进阶 - Matplotlib库
  10. while循环python次数定义_Python学习笔记之While循环用法分析
  11. bin to npy
  12. dos2unix install on mac_费德勒和瑞士运动品牌On昂跑合作推出以网球为灵感的高科技运动鞋...
  13. Phalloidin——Acti-stain555鬼笔环肽研究
  14. Git 六 时光穿梭机
  15. BZOJ 4031 HEOI2015 小Z的房间 Matrix-Tree定理
  16. 【MySQL】6、Delete From删除语句
  17. Android APP如何实现支付宝支付
  18. Android中APK打包流程
  19. 线程与进程之间的共享资源
  20. 08 基础代谢率计算

热门文章

  1. dell服务器新bois系统设置u盘启动,跟大家讲讲dell新版biosU盘启动顺序
  2. 研究生实证论文数据经验分享
  3. JavaScript 原形链
  4. iTunes下载的ipa文件的目录位置
  5. android mac地址不可用,Android手机里的mac地址显示不可用是为什么。我的手机是海信E920....
  6. 加装固态硬盘后计算机不显示,安装固态硬盘后无法读取,如何解决?
  7. python ip地址处理_Python学习笔记-IP地址处理模块Ipy
  8. Ubuntu20.04.iso光盘镜像源文件百度云下载
  9. rust编程 UI框架 -druid -Selector选择器
  10. Contect、SharedPreferences及Intent学习小记