java - AOSP 5.1 - 如何使用实根权限执行我的应用程序?

标签 java android android-source su android-5.1.1-lollipop

在我的 AOSP 5.1-build 中,我尝试创建一个 MySetupApp.apk 应用程序,它根据用户执行一些设置操作。
例如。除此之外(大多数还需要 root),用户应该能够在我的 MySetupApp.apk 中选择启动动画。 bootanimation 保存在 /sdcard/ 上,apk 应该将其移动到正确的系统文件夹 /system/media/bootanimation.zip 这在 adb-shell 上运行良好。以下命令提供所需的结果(新的启动动画):

adb remount
adb shell cp /sdcard/bootanimation.zip /system/media/
adb shell chmod 777 /system/media/bootanimation.zip

应用程序正在以系统用户身份运行: android:sharedUserId="android.uid.system" 我可以在 adb-shell 上验证这一点:

root@astar-yh:/system/bin # ps
system    9634  170   1242144 35536 ffffffff b6e51bf4 S com.mycompany.MySetupApp

我已在我的 AOSP 构建中添加了该应用程序:

/android/device/softwinner/common/prebuild/apk/Android.mk:

include $(CLEAR_VARS)
LOCAL_MODULE := MySetupApp
LOCAL_MODULE_TAGS := optional
LOCAL_CERTIFICATE := platform
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_PRIVILEGED_MODULE := true
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
include $(BUILD_PREBUILT)

因此,该应用程序安装在 /system/priv-app 中,并使用平台 key 进行签名。

我还调整了/android/system/extras/su/su.c:

myuid = getuid();
// added AID_SYSTEM
if (myuid != AID_ROOT && myuid != AID_SHELL && myuid != AID_SYSTEM) {
   fprintf(stderr,"su: uid %d not allowed to su\n", myuid);
   return 1;
}

// Removed this code-block
/*if(setgid(gid) || setuid(uid)) {
    fprintf(stderr,"su: permission denied\n");
    return 1;
}*/

这是我的 Java 代码。输出位于行后面的注释中:

public void doRootStuff(){
  try {
    String line;
    Process process = Runtime.getRuntime().exec("su");

    OutputStream stdin = process.getOutputStream();
    InputStream stderr = process.getErrorStream();
    InputStream stdout = process.getInputStream();

    stdin.write(("getenforce\n").getBytes()); // "Permissive"
    stdin.write(("mount -o rw,remount -t ext4 /system\n").getBytes()); //E/[Error]: mount: Operation not permitted
    stdin.write(("ls /data/data/\n").getBytes()); // Works! Shows the directory contents
    stdin.write(("touch /system/media/test\n").getBytes()); // Does nothing - no error but also no file
    stdin.write(("cp -f /sdcard/bootanimation.zip /system/media/bootanimation_test.zip\n").getBytes()); // E/[Error]: cp: /system/media/bootanimation_test.zip: Read-only file system
    stdin.write("exit\n".getBytes());
    stdin.flush();

    stdin.close();
    BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
    while ((line = br.readLine()) != null) {
      Log.d("[Output]", line);
    }
    br.close();
    br = new BufferedReader(new InputStreamReader(stderr));
    while ((line = br.readLine()) != null) {
      Log.e("[Error]", line);
    }
    br.close();
    process.waitFor();
    process.destroy();

  } catch (Exception ex) {
    Log.e(TAG, ex.toString());
    ex.printStackTrace();
  }
}

按照建议here ,我还编辑了 android_filesystem_config.h,但没有任何运气

    { 06755, AID_ROOT,      AID_ROOT,      0, "system/priv-app/MySetupApp/*" },

在我的应用程序中调用 setuid(0); 也不起作用:

com.mycompany.MySetupApp W/art: Failed to find OatDexFile for DexFile /system/priv-app/MySetupApp/MySetupApp.apk ( canonical path /system/priv-app/MySetupApp/MySetupApp.apk) with checksum 0x73b2ee8d in OatFile /data/dalvik-cache/arm/system@priv-app@<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a4e9ddf7c1d0d1d4e5d4d4e4e9ddf7c1d0d1d4e5d4d48ac5d4cf" rel="noreferrer noopener nofollow">[email protected]</a>@classes.dex
com.mycompany.MySetupApp W/System.err: android.system.ErrnoException: setuid failed: EPERM (Operation not permitted)

因此,无法从 apk 中重新挂载系统目录并在其中复制内容!

我该怎么做才能使这项工作成功?我应该在我的应用程序或 Android 源代码中更改哪些内容?

更新

我还尝试将功能转移到脚本 setup_device.sh 中,并将其放入 /system/bin/setup_script.sh 中。当我尝试在 java 中运行它时:

Process process = Runtime.getRuntime().exec("su");
stdin.write(("./system/bin/setup_device.sh\n").getBytes());

它说:

E/[Error]: sh: <stdin>[2]: ./system/bin/setup_device.sh: Permission denied

最佳答案

我能够解决我的问题:

1.) 正如问题中提到的,我编写了一个简单的脚本,它将启动动画从 /sdcard/ 复制到 /system/media/。将此脚本放入 /system/bin/

setup_device.sh

#!/sbin/busybox sh

BUSYBOX="/sbin/busybox"

echo "Remount /system-partition to rw"
mount -o remount,rw /system

if [ -e /sdcard/bootanimation.zip ] ; then
    echo "copy bootanimation"
    $BUSYBOX cp -fp "/sdcard/bootanimation.zip" "/system/media/bootanimation.zip"
    chmod 777 "/system/media/bootanimation.zip"
    chown 0.0 "/system/media/bootanimation.zip"
    $BUSYBOX rm "/sdcard/bootanimation.zip"
else
    echo "Bootanimation not in /sdcard/-folder"
fi

2.) 在 init.rc 中调用此脚本并在属性更改时执行

service setup_device /sbin/busybox sh /system/bin/setup_device.sh
    user root
    group root
    disabled
    oneshot

on property:start.setup=1
    start setup_device

3.) 在setup.apk中,只需设置此属性:

Process proc = Runtime.getRuntime().exec(new String[] { "/system/bin/sh", "-c", "setprop start.setup 1" });
proc.waitFor();

应用程序设置此属性后,setup_device.sh脚本将触发并以root权限执行代码! bootanimation.zip 最终将复制到 /system/media/,重启设备后即可看到新的 bootanmiation。

陷阱:

  • 当您在 init.rc 中声明脚本名称时,请确保它不超过 16 个字符的字符限制!也仅限用户字母数字字符和 -_

关于java - AOSP 5.1 - 如何使用实根权限执行我的应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46888792/

相关文章:

java - Android 中的位置未更新

Java applet 与 Rails 应用程序通信

android - Android 是否有一些功能会杀死所有正在运行的进程并需要重新启动才能修复?

android - 为 Nexus 5 构建 AOSP,clang 错误

Android,从本地/NDK 共享库访问资源文件

java - 带有 JScrollPane 和原型(prototype)单元格值的 JList 包裹元素名称(用点替换而不是显示水平滚动条),为什么?

java - 在IDEA中引用Eclipse UserLibrary

android - 使用 cordova 如何获取 android 设备上已安装应用程序的列表?

android - 在谷歌地图上找到最近的药店

java - 将不可序列化的数据发送到新的 Activity