脱壳时写patch补丁时Native代码并没有太高的权限,以至于如文件IO、网络IO等基本的C函数都无法使用,提示权限不足。在网上搜索了资料大致进行以下几种尝试:
1、APK在安装时会在/data/system/packages.xml记录当前app需要申请的权限,如下:
<package name="com.example.unpacker" codePath="/data/app/com.example.unpacker-1.apk" nativeLibraryPath="/data/app-lib/com.example.unpacker-1" flags="572998" ft="1504bc58f90" it="1504bad7c65" ut="1504bc5913e" version="1" userId="10078"> <sigs count="1"> <cert index="9" key="xxx" /> </sigs> <perms> <item name="android.permission.ACCESS_WIFI_STATE" /> <item name="android.permission.CHANGE_NETWORK_STATE" /> <item name="android.permission.ACCESS_NETWORK_STATE" /> <item name="android.permission.INTERNET" /> <item name="android.permission.CHANGE_WIFI_STATE" /> </perms> <signing-keyset identifier="1" /> </package>
尝试将所有权限添加到此packages.xml里没有作用,测试失败,具体原因以后再看
2、直接绕过permission验证修改framework代码,相关参考http://www.cnblogs.com/GnagWang/archive/2011/03/21/1990507.html
ActivityManagerService.java (frameworks\base\services\java\com\android\server\am)中将checkPermission、checkCallingPermission、enforceCallingPermission函数返回值修改为PERMISSION_GRANTED,修改后编译framework.jar、framework2.jar、services.jar然后刷入机器测试发现此修改容易造成系统起不来,不稳定,具体原因以后再看;
3、修改zygote fork后的进程的权限,zygote fork进程最终会调用forkAndSpecializeCommon函数,在forkAndSpecializeCommon中会判断是不是启动systemserver进程还是其它app进程,其它进程的话permittedCapabilities和effectiveCapabilities将设置成0
if (isSystemServer) { /* * Don‘t use GET_ARG_LONG here for now. gcc is generating code * that uses register d8 as a temporary, and that‘s coming out * scrambled in the child process. b/3138621 */ //permittedCapabilities = GET_ARG_LONG(args, 5); //effectiveCapabilities = GET_ARG_LONG(args, 7); permittedCapabilities = args[5] | (int64_t) args[6] << 32; effectiveCapabilities = args[7] | (int64_t) args[8] << 32; } else { mountMode = args[5]; permittedCapabilities = effectiveCapabilities = 0; //其它app进程则允许权限和有将权限清o //将上一行修改为 permittedCapabilities = effectiveCapabilities = 125910048; StringObject* seInfoObj = (StringObject*)args[6]; if (seInfoObj) { seInfo = dvmCreateCstrFromString(seInfoObj); if (!seInfo) { ALOGE("seInfo dvmCreateCstrFromString failed"); dvmAbort(); } } StringObject* niceNameObj = (StringObject*)args[7]; if (niceNameObj) { niceName = dvmCreateCstrFromString(niceNameObj); if (!niceName) { ALOGE("niceName dvmCreateCstrFromString failed"); dvmAbort(); } } }
因此直接强制将app启动进程时的允许权限和有效权限全设置成固定的就可以实现权限绕过:
编译Libdvm.so拷贝到手机发现现在进程权限已经和system_server权限一样了。