Apk静默安装之调用系统隐藏API
Posted ttdevs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Apk静默安装之调用系统隐藏API相关的知识,希望对你有一定的参考价值。
文章目录
0x00 问题
何为隐藏的API?
简单来说就是在源码中被用 @hide
标记的代码块,比如常量,方法等。以常用的 ActivityManager.java
为例,里面就有大量的隐藏API:
@SystemService(Context.ACTIVITY_SERVICE)
public class ActivityManager
...
/**
* System property to enable task snapshots.
* @hide
*/
public final static boolean ENABLE_TASK_SNAPSHOTS;
...
/**
* Return the default limit on the number of recents that an app can make.
* @hide
*/
static public int getDefaultAppRecentsLimitStatic()
return getMaxRecentTasksStatic() / 6;
...
以上代码来自 AOSP
源码,我们下载的 android SDK
源码中是找不到这些代码的。
而用 Android Studio
进行系统App的开发的我们,有时候难免会调用到系统隐藏的API,那我们怎么办呢?
0x01 调用系统隐藏API
如果你之前做过功课,你会发现网上有很多通过反射来调用系统API的例子,既然反射能调到,说明这些方法在我们的运行环境中是存在的。那这些方法从哪里加载的呢?这就要提到设备中的一个jar:/system/framework/framework.jar
,他和我们 SDK 中加载的 android.jar
的区别就是他里面包含了这些隐藏的API。到这里我们就得出两种调用系统隐藏API的方法:
-
反射
这个最常见了,如:
public static boolean silentInstall(PackageManager packageManager, String apkPath) Class<?> pmClz = packageManager.getClass(); try Method method = pmClz.getDeclaredMethod("installPackage", Uri.class, Class.forName("android.content.pm.IPackageInstallObserver"), int.class, String.class); method.setAccessible(true); method.invoke(packageManager, Uri.fromFile(new File(apkPath)), null, 2, null); return true; catch (Exception e) e.printStackTrace(); return false;
-
替换 SDK 中的
android.jar
这个就厉害了,反射一次只可以反射一个方法,这种方式所有系统的隐藏API都可以直接调用到。Github上有个一个项目 android-hidden-api ,在这里我们可以下载别人收集的带隐藏API的
android.jar
。
个人不是很喜欢反射,就研究了下第二种方法,但是很遗憾,我没成功(可能是因为我的build工具版本比较高)。那么还有其他方法吗?
由于我们有系统的源码,因此我们可否从源码入手?简单总结了一个思路:创建一个项目,在这个项目中对要调用的系统隐藏API做一些封装,然后在AOSP中编译生成jar包,最后将这个jar包拷贝到 Android Studio
中使用。下面以App的静默安装为例,说明此思路的具体实现。
0x02 SystemHideAPI
这里有一个前提,系统隐藏API可以通过各种方法调到,但是能不能调成功却是另外一回事,因为有些隐藏API不是普通权限的App可以调用的。若要升级你的App为系统App,可以按照下面几步操作:
-
AndroidManifest.xml 中添加
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.your.pkg" android:sharedUserId="android.uid.system"> ... </manifest>
-
系统签名
使用系统密钥给App签名。一般位于:build/target/product/security/
中。 需要signapk.jar,命令如下:
java -jar signapk.jar platform.x509.pem platform.pk8 in.apk out.apk
-
安装
直接推到/system/app/
或者/system/priv-app/
下面,重启即可。
下面回到我们App静默安装的例子。
bash-3.2$ tree
vendor
|-- ...
|-- SystemHideAPI
| |-- Android.mk
| `-- com
| `-- your
| `-- pkg
| `-- utils
| `-- SystemHideAPI.java
SystemHideAPI.java
public class SystemHideAPI
/**
* Silent install
* @param pm
* @param apkPath
* @return
*/
public static boolean silentInstall(PackageManager pm, String apkPath, OnInstallResultListener listener)
if(null == pm || TextUtils.isEmpty(apkPath))
return false;
pm.installPackage(Uri.fromFile(new File(apkPath)), new PackageInstallObserver()
@Override
public void onPackageInstalled(String basePackageName, int returnCode, String msg, Bundle extras)
if (null != listener)
listener.onResult(basePackageName, returnCode, msg);
, PackageManager.INSTALL_REPLACE_EXISTING, "");
return true;
/**
* App install callback
*/
public interface OnInstallResultListener
/**
* App install callback
*
* @param pkg
* @param returnCode
* @param msg
*/
void onResult(String pkg, int returnCode, String msg);
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_MODULE := SystemHideAPI
LOCAL_MODULE_TAGS := optional
LOCAL_JACK_ENABLED := disabled
include $(BUILD_STATIC_JAVA_LIBRARY)
Build
mma
classes.jar
生成的jar文件位于下面目录:
out/target/common/obj/JAVA_LIBRARIES/SystemAPI_intermediates/
➜ SystemHideAPI_intermediates tree -L 1
.
├── anno
├── classes
├── classes-full-debug.jar
├── classes.jar
└── link_type
2 directories, 3 files
➜ SystemHideAPI_intermediates
最后,将生成的 classes.jar
拷贝到Android Studio项目,使用 SystemHideAPI
中的方法,即可正常编译,运行了。
0x03 总结
相比反射,这种方式的灵活性更大,如上面静默安装的例子,如果我想监听安装的回调,还需要去反射 PackageInstallObserver 这个类(这个类也是hide)。如果还需要其他隐藏的API,只需要增加响应的方法即可。给我们在AndroidStuido
中调用系统隐藏API带来很大方便
0xFF 参考
- https://developer.android.com/distribute/best-practices/develop/restrictions-non-sdk-interfaces?hl=zh-cn
- https://github.com/skylot/jadx/releases
- https://github.com/anggrayudi/android-hidden-api
- https://blog.csdn.net/pshiping2014/article/details/79549680
- https://stackoverflow.com/questions/17035271/what-does-hide-mean-in-the-android-source-code
以上是关于Apk静默安装之调用系统隐藏API的主要内容,如果未能解决你的问题,请参考以下文章