Android Java进程动态注入Hack技术

时间:2024-03-22 22:14:21

前言

        Android Java进程注入Hack技术可以一定程度上弥补离线日志方式下问题分析方法的不足,即可以在离线运行条件下动态注入故障进程,实时获取进程内部运行时数据,也可以为热修复、调试提供技术基础。

        Android系统在加载启动一个apk应用时,ActivityManagerService服务(后续简称AMS)会首先确认应用包名、用户名、签名信息以及目标进程名,然后通过用户名与目标进程名判断系统当前是否有启动符合这些信息的进程,如果有这样的进程,则通知这个进程加载启动对应包名的组件,如果没有这样的进程,AMS则会创建新的进程然后再加载对应包名的组件。也就是说,一个apk应用在安装到Android系统中后,包名、用户名、签名信息以及目标进程名都会确定下来,之后任意时候任意方式启动该应用,这些信息都是确定的,不会改变,所以如果想要动态调整一个应用的目标进程名是没有办法实现的。

        正常情况下,Android系统中每个应用都有自己的独立运行空间与私有数据,除非应用显示的输出内部数据信息,比如显示界面、日志输出等,其他内部数据用户是看不到的,但实际上,我们在保证系统安全性时会在某些时候要查询某个应用的内部数据信息,比如在故障分析时,如果能获得更多的应用进程运行时内部数据信息,将会给故障分析带来很大帮助。

        上面已说明目前Android系统启动应用时,包名、用户名、签名信息以及目标进程名都是确定的,所以想要进入某个应用内部以便查询进程内部数据信息,目前的办法只能是设计安装一个和目标应用用户名、签名信息、进程名信息均一致的apk应用,而不同的目标应用需要设计安装不同的对应apk应用,这就非常繁琐了,基本上没法实施。

         本文将讲述Android Java进程动态注入技术,可以实现设计安装一个apk应用动态注入Android系统中任意一个目标Java进程中。同时,注入之后,通过am指令,可以持续向注入的组件服务发送控制命令,达到控制查询目标应用进程的效果。当需要继续注入另一个目标进程时,可以使用am指令通知当前被注入的目标进程卸载注入的组件,然后再按照上诉办法注入新的目标应用进程。这样在实际使用中就非常方便操作了。

注入Java进程指令

am startservice --es pro com.csdn.yeqishi.launcher2 appinject

        AMS服务接收到上诉指令后,解析到关键字appinject,就会创建注入应用的组件信息,然后解析指令中pro对应的目标进程进程名参数(即com.csdn.yeqishi.launcher2)并将其设定到注入应用组件信息的进程信息中。随后AMS根据目标进程名通知目标进程使其加载注入应用的组件服务。

        当需要对另一目标进程进行注入控制时,需要先从当前目标进程卸载注入组件,然后按照上诉命令注入新的进程。从当前目标进程卸载注入组件的命令如下:

退出Java进程指令

am stopservice appinject

       同样,AMS服务在解析到appinject关键字时,就会创建注入应用的组件信息,然后按照注入应用的组件信息执行组件卸载动作。

进程动态注入过程框架

Android Java进程动态注入Hack技术

 

上图描绘进程动态注入过程描述如下:

<1> 设计安装注入应用apk

<2> PackageManager服务将注入应用信息写入文件系统,同时加载到Android运行时的缓存中,已提供其他服务使用(如AMS)

<3> 执行注入应用启动命令

<4> AMS服务根据appject关键字,获取并创建注入应用的组件信息,然后将其设置为预启动组件

<5> AMS服务根据启动命令pro对应的参数,寻找当前匹配的目标进程信息

<6> AMS服务通知目标进程加载预启动组件

<7> 目标进程执行加载预启动组件,如果设定了控制参数,预启动组件根据参数执行约定好的动作

 

预启动组件加工过程

        AMS服务在接收到应用组件启动命令时,会按照以下逻辑,判断加工预启动组件信息,然后按照正常流程执行组件启动动作。

Android Java进程动态注入Hack技术

       按照上诉逻辑对预启动组件进行判断加工后,就可以将一个应用组件动态加载到任意一个目标应用进程中,无需再安装多个一一对应的注入应用。

卸载注入组件

       如果需要从当前应用进程卸载注入的组件时,AMS服务同样需要判断加工处理预卸载组件信息,流程图如下:

Android Java进程动态注入Hack技术

 

备注

       以上技术实现方法未能具体到代码实现上,细节上有疑问欢迎与我联系。