前言
最近由于练车和项目紧的原因未更新博文,今天给大家讲解 GG修改器是如何实现跨进程读写应用内存的。
关于跨进程读写应用内存的文章和案例我翻遍了csdn,简书,github,gitee,发现没有一篇文章,于是决定发布一篇博文来粗略讲解一下原理,有基础的朋友完全可以上手开发。
进入话题
此技术核心用到了java反射技术和AIDL(IPC)管道通信技术。
大体逻辑
使用root拉起一个java的su进程 -> 创建IPC管道 -> 回调主进程连接Service
如何创建su进程
在linux中有两个命令,可以创建java进程,dalvikvm和app_process,建议使用app_process,因为app_process底层也是dalvikvm,具体创建进程命令和参数可百度查询。
如何在SU进程发送广播
在拉起su进程之后,
- 反射调用ActivityThread.systemMain()方法,获取ActivityThread对象
- 反射调用ActivityThread.getSystemContext()方法,得到ContextImpl对象
- 反射调用 ActivityManagerNative.getDefault()方法, 或 反射调用ActivityManager.getService()方法,得到IActivityManager对象
- 反射得到IActivityManager对象的broadcastIntenot方法(注意,API 21+ broadcastIntent有12个形参,API 24+ broadcastIntent有13个形参)
- 最后调用broadcastIntent方法,传入参数,完成创建IPC服务(broadcastIntent的参数请查看安卓源码)
- 注意:记得阻塞SU进程,否则运行完成会直接退出
// api24 +
int broadcastIntent(in IApplicationThread caller, in Intent intent,
in String resolvedType, in IIntentReceiver resultTo, int resultCode,
in String resultData, in Bundle map, in String[] requiredPermissions,
int appOp, in Bundle options, boolean serialized, boolean sticky, int userId);
// api 21+
public int broadcastIntent(IApplicationThread caller, Intent intent,
String resolvedType, IIntentReceiver resultTo, int resultCode,
String resultData, Bundle map, String requiredPermission,
int appOp, boolean serialized, boolean sticky, int userId) throws RemoteException;
如何让JNI拥有Root环境
当我们创建好su进程后,可以使用System.load函数加载动态so库,这时候这个so就是root环境,就实现了跨进程读写内存,再通过ipc就能实现主进程的主动调用su进程函数
注:我们拉起的su进程是无法创建UI视图的。在主进程结束后,请kill掉su进程,某些情况下,su进程不会因为主进程的死亡而死亡,而是继续运行。
转载或引用文本请注明出处:https://blog.csdn.net/qq_38944721/article/details/114363535?utm_source=app&app_version=4.5.2