Android进程注入
全部代码在这里下载:http://download.csdn.net/detail/a345017062/8133239
里面有两个exe。inj是一个C层进程注入的样例。inj_dalvik是我写的Java注入。
C层的进程注入借直接拉的洗大师的开源项目(https://code.google.com/p/libandroidinjector/)
Android的基础服务大部分都是使用Java写的,仅仅是C层的注入,想要直接訪问的话还是比較麻烦。所以须要在远端载入一个dex包(代码中写死了载入/data/local/inj文件夹下的dex)。
载入dex须要Dalvik虚拟机的Context。也就是JNIEnv,这个略微遇到了一些麻烦,直接在源代码上面编译的话。构建源代码的编译环境就比較费时间了。最后还是从源代码中拉出Header文件,又从我的手机(ZTE N5 4.1.2)中adb pull下来了android_runtime和nativehelper这两个.so才攻克了编译、链接的问题。
C层载入dex之后。能够调用Java的main方法运行Java代码了,可是想做一些訪问系统服务的事情的话,没有Context是不行的。所以通过反射调用ActivityThread。拿到Application。
我最初的想法是使用inj_dalvik注入到system_server进程,然后訪问里面全部的Android系统服务,但后来发现这样有两个问题,dex在system_server进程运行时不能使用PackageManager这种远端服务代理,仅仅能使用ServiceManager.getService("package")直接获取PackageManagerService实例。并且发现PackageManagerServer这种服务,接口变动比較频繁。版本号适配上比較麻烦。
所以最后还是决定注入到一个user为system的客户进程。比方com.android.settings。然后整个流程就跑通了。
如今面临的一个未解决的问题是com.android.setting这种进程并非系统Daemon,不是常驻进程,我们的代码注入后不能永远存活。但其他像/system/bin/surfaceflinger这种进程。由于本身是C程序。启动时并没有AndroidRuntime,无法载入我们的Dex并Java代码。
所以,要么在须要运行远端代码时后台偷偷启动com.android.settings进程,要么自己fork出一个具有AndroidRuntime的进程来。并把它注冊到init.rc中。
补充于2014.11.19
手机助手中通常都须要用到这种功能,停用某个用户不使用的系统应用,或者为了禁止应用被后台唤起而停用应用中的某个组件。通过Root后有一种比較简单的办法就是在su下运行pm命令。但这种方式有几个比較大的缺陷:一个是效率低,由于须要新开进程。
二个是假设一个组件的类是个内部类,类名中包括$这种符号的话,pm命令会运行失败。三个是应用自身能够恢复自身组件的停用状态。
这里提供一个比較简单的实现方案。
我们研究PackageManagerService代码发现,调用setComponentEnabledSetting、setApplicationEnabledSetting这样方法假设是针对其他应用的话,检查的是system权限。所以我们仅仅要造一个具有system权限的进程,并在这个进程内部调用这两个方法就OK。这一点已经通过上面的Android进程注入方案中,通过注入到com.android.settings包中得到了验证。我们须要这几步:
一、參考pm、am等工具的实现方式,在源代码下编译一个Jar包。在代码中启动一个Socket服务。接收外部命令。进行校验后运行。
二、把Jar包拷贝到/system/framework下,并在system/bin下建立启动入口。然后使用app_process启动该服务。
三、在init.rc中添加一个services项。以system权限启动该Jar包,这样下次开机时也能自己主动启动。
补充于2014.11.24
进程注入的流程例如以下:
一、attach目标进程。
使用ptrace来attach目标进程,内核将发送 SIGSTOP 将目标进程挂起。我们使用waitpid接收到SIGSTOP以后。使用ptrace_getregs把当前寄存器的内容保存在regs_t中(regs_t这个数据结构的定义在ptrace.h)。再调用PTRACE_CONT使用进程继续运行。
二、在linker找到dlopen,dlsym,dlclose的地址。
搜索/proc/$pid/maps中/system/bin/linker在虚拟进程中的地址。然后在linker的地址范围内搜索分别找到dlopen,dlsym,dlclose的地址。存储在数据结构dl_fl_t中。
三、载入并运行本地SO。
Android中的动态载入与Linux中有些不同,是没有懒载入的,C代码中引用到的.so会在进程启动时载入完毕。假设C代码中用到dlopen等显式动态载入方法时,须要在编译时加上libdl.so,但代码实际运行中逻辑实现是在linker中的。所以我们在linker中就能够找到dlopen,dlsym,dlclose的handle。
通过第二步拿到dlopen,dlsym的地址之后。就能够通过ptrace改写远程进程的寄存器的PC寄存器地址(R15)到dlopen的地址,然后ptrace_cont,就能够载入本地的SO库了。
Android进程注入的更多相关文章
- Android中通过进程注入技术改动广播接收器的优先级
前言 这个周末又没有吊事,在家研究了怎样通过进程的注入技术改动广播接收器的优先级.关于这个应用场景是非常多的.并且也非常重要.所以就非常急的去fixed了. Android中的四大组件中有一个广播:B ...
- Android中通过进程注入技术修改广播接收器的优先级
前言 这个周末又没有吊事,在家研究了如何通过进程的注入技术修改广播接收器的优先级,关于这个应用场景是很多的,而且也很重要,所以就很急的去fixed了. Android中的四大组件中有一个广播:Broa ...
- Android中通过进程注入技术修改系统返回的Mac地址
致谢 感谢看雪论坛中的这位大神,分享了这个技术:http://bbs.pediy.com/showthread.php?t=186054,从这篇文章中学习到了很多内容,如果没有这篇好文章,我在研究的过 ...
- Android进程的so注入--Poison(稳定注入版)
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/53869796 Android进程的so注入已经是老技术了,网上能用的Android ...
- Android进程so注入Hook java方法
本文博客链接:http://blog.csdn.net/qq1084283172/article/details/53769331 Andorid的Hook方式比较多,现在来学习下,基于Android ...
- Android 进程常驻----开机广播的简单守护以及总结
这是一个轻量级的库,配置几行代码,就可以实现在Android上实现进程常驻,也就是在系统强杀下,以及360获取root权限下,clean master获取root权限下都无法杀死进程 支持系统2.3到 ...
- Android so注入(inject)和Hook技术学习(三)——Got表hook之导出表hook
前文介绍了导入表hook,现在来说下导出表的hook.导出表的hook的流程如下.1.获取动态库基值 void* get_module_base(pid_t pid, const char* modu ...
- Android 进程常驻(5)----开机广播的简单守护以及总结
这是一个轻量级的库,配置几行代码.就能够实如今android上实现进程常驻,也就是在系统强杀下,以及360获取root权限下.clean master获取root权限下都无法杀死进程 支持系统2.3到 ...
- Android so注入( inject)和Hook(挂钩)的实现思路讨论
本文博客:http://blog.csdn.net/qq1084283172/article/details/54095995 前面的博客中分析一些Android的so注入和Hook目标函数的代码,它 ...
随机推荐
- XCode快捷键 转
1. 文件 CMD + N: 新文件CMD + SHIFT + N: 新项目CMD + O: 打开CMD + S: 保存CMD + SHIFT + S: 另存为CMD + W: 关闭窗口CMD + S ...
- duplicate symbol _main in: / linker command failed with exit code 1
duplicate symbol _main in: /Users/mb467/Library/Developer/Xcode/DerivedData/barChartDemo-gevlnavnpan ...
- 玩转rocketMQ
下载地址https://github.com/alibaba/RocketMQ 安装环境需要jdk,maven,git http://maven.apache.org/download.html
- [Git] Git fetch和git pull的区别
reference : http://blog.csdn.net/hudashi/article/details/7664457 Git中从远程的分支获取最新的版本到本地有这样2个命令:1. git ...
- mysqldump与source
mysqldump示例 mysqldump --default-character-set=utf8 -d --opt -hlocalhost -uroot -p123456 --where=&quo ...
- Cocos2dx 3.0 过渡篇(二十七)C++11多线程std::thread的简单使用(下)
本篇接上篇继续讲:上篇传送门:http://blog.csdn.net/star530/article/details/24186783 简单的东西我都说的几乎相同了,想挖点深的差点把自己给填进去. ...
- JavaBean示例
例1.通过非可视化的JavaBean,封装邮箱地址对象,通过JSP页面调用该对象来验证邮箱地址是否合法. (1)创建名称为Email的JavaBean对象,用于封装邮箱地址,关键代码如下: packa ...
- 基于zabbix 的memached 多实例监控
基于zabbix 的memached 多实例监控 zabbix agentd 配置文件新增配置: UserParameter=memcached.server.discovery[*],ps uax ...
- Simplify Path leetcode java
题目: Given an absolute path for a file (Unix-style), simplify it. For example, path = "/home/&qu ...
- Android -- 加载大图片的方法
在android中要加载一张大图片到内存中如果通过如下方式进行: Bitmap bitmap= BitmapFactory.decodeFile("/sdcard/a.jpg"); ...