“个人能量无穷无尽,只有强大暗能量才能统治Android界。
受屎吧!!! =≡Σ((( つ•̀ω•́)つ ”
-- 来自暗世界android工程师java
前言:android
这是黑科技系列的第二篇,是Android知识正营中较有深度难理解的知识。若是你是一个初学者,牵扯的知识太深,文中没有从零讲起。皆是拔云见雾的带你们看。能够先收藏起来,往后慢慢系统性的对着文中的Github源码写一遍。git
这个世界上手机有三大系统,苹果、 安卓、 中国安卓 。本篇强烈呼吁你们不要去作哪些违反用户体验的黑科技功能,研究研究玩玩就行了啦。全当增加技术,在真实的项目开发中尽可能能不用就不要用得好。道理你们都懂的。github
那些年Android黑科技②:欺骗的艺术windows
hook一词最先我是在用windows的时候学习到的。当时用来作键盘监听。懵逼的我没法理解这个翻译叫“钩子”东西究竟是什么鬼。网络
那么先说下hook究竟是在干吗。咱们能够把hook看成代理模式或劫持来理解。在一个方法的前或后动态插入一段咱们的逻辑事情,甚至改变本来方法在执行前的参数,返回后的参数。总之能够hook任意java写的代码,修改替换apk内部的资源文件。一摸索到如今到android中hook已知有两种。这两种分别是:app
xposed是一个hook的框架。通常是用来作手机插件的。好比修改系统电池图标、信号、按键交换位置等等,可是也有人用来作一些应用的破解等。咱们先说下xposed原理。只有明白原理了才知道这个东西是怎么玩的。框架
apk在android运行的时候是经过ActivityManagerService(如下简称AMS)发送Socket给Zygote进程进行通讯。由Zygote进程fork一个子进程来启动咱们的apk程序。
AMS -> Socket-> Zygote->apk启动
重点来了。下面将是android Xposed Hook的核心原理。仔细看。
在android运行环境中,Zygote进程是全部虚拟机进程的父亲,Zygote进程在开机初始化的时候会建立一个虚拟机,AMS发消息给Zygote建立的时候其实是copy一份虚拟机的实例在子进程中。同时在初始化的时候还会注册一些android核心Jni的库放在虚拟机实例内提供上层api调用。fork出的虚拟机会共享这些jni类库。 那么实际上XPosed就是在root后对替换/system/bin/app_process并将注入XposedBridge.jar。app_process是用来控制Zygote的,经过替换成修改后的 app_process可使Zygote进程加载到咱们的XposedBridege.jar。而这个库就是用来作动态Hook java代码形成劫持的。
插件也是同样用android Studio写就能够了,只是咱们不须要任何活动容器。
1 .新建一个工程在gradle里添加xposedApi依赖
dependencies { provided ‘de.robv.android.xposed:api:++’ }
2.在AndroidManifest中配置声明标签让xposed壳认识你的插件
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <meta-data android:name="xposedmodule" android:value="true" /> <meta-data android:name="xposeddescription" android:value=" example " /> <meta-data android:name="xposedminversion" android:value="22" /> </application>
3.使用xposed提供的接口作具体的hook逻辑
4.串改变量示例
public class Demo implements IXposedHookInitPackageResources{ @Override public void handleInitPackageResources(XC_InitPackageResources.InitPackageResourcesParam resparam) { //判断当前须要hook的包名 if (resparam.packageName.equals("com.android.xxxx")) { //调用setReplacement方法替换名为aaa的变量值为false resparam.res.setReplacement(resparam.packageName, "String", "aaa", “123”); } }
5.在工程里的assets目录下建立名称为xposed_init的配置文件(注意是无格式的文本),在该文件里写入你插件的包名。xposed框架会在设备开机的时候读取的插件。
com.bolex.xxx
6.打包出来 安装到手机上 而后在Xposed里面勾上你的插件重启便可
Xposed框架在玩机的发烧友手机上号称是必装的神器。做为android的咱们实际上是有能力本身写插件的。同时若是咱们是作付费软件和金融软件的对Xposed仍是要作一些防范。好比加固、混淆你的应用让坏人无法很轻松的知道你的代码逻辑。
相信作过android的同窗就算没有用过反射也听过。咱们知道反射能够在不修改源代码的状况下对私有方法和成员变量调用或修改。同上一个章节讲到的hook技术同样。除了Xposed的方式之外,反射自己也能作hook。
一般有两种方式动态代理、静态代理,本文使用动态代理来说解,因此若是你不明白动态代理的原理能够去补补这块的知识。简单来讲就是动态代理会利用被被代理对象的接口,经过反射模拟一份同样的接口来实现代理。
能够作的事情:
原理剖析:
android系统层会提供接口的形式来实现一些回调操做。咱们经过反射去获取持有接口引用的对象。而后偷梁换柱的将本身的接口塞进去替换原有的对象。致使系统调用接口的时候是调用咱们换过的代理对象。咱们在代理对象内部再去调用本来的对象的接口方法,这样就能够作到hook的目的。
好比咱们经常使用的 OnClickListener()接口,用于点击事件的回调。若是hook View的ListenerInfo对象名称为mListenerInfo。就能够拦截点击或者在点击以前和以后作一些咱们想作的事情。下面咱们讲一个高深且好玩一点的案例。
先思考一个问题,为何咱们的Activity须要在AndroidManifest.xml文件中注册?若是不注册能不能启动呢?
咱们知道是AMS负责调起Activity。在启动以前他作了些什么事情呢?前面咱们说过实际上AMS是给Zygote发送了消息,由Zygote进程fork一个虚拟机进程来。
那么其实在开机时Zygote进程在运行时第一个fork的进程是system_server的进程,这个服务用于管理系统级别的服务启动。
System_server进程包含了如下顶级的系统服务
既然AMS承载了调用逻辑。咱们是否能够对AMS动刀子来作到不注册Activity也能直接启动呢?
这里为何咱们前面要讲system_server服务,缘由是咱们要知道AMS进程不在咱们本身的应用内,而是独立的远程服务进程。java层的上的反射是没法作到跨进程的。因此咱们能够在本身的应用内利用AIDL的特性拿代理对象,去欺骗AMS服务。
流程以下:
这里咱们经过反射获取到AMS的代理本地代理对象Hook之后动态串改Intent为已注册的来躲避检测
经过动态代理实现对startActivity中的Intent串改,具体逻辑见代码和注释。
hook ActivityThread 中的 handle 在这里咱们须要替换咱们未被注册的Activity Intent
拦截启动消息
替换咱们真实要被启动的Intent
封装之后咱们ASMHook将变得很是简单,简单到一行代码就能够实现不注册的状况下启动Activity。
其中HostActivity是咱们的壳,OtherActivity是未被注册的。咱们能够像平时正常调用API的条件下直接使用startActivity了。
结果 启动了。
哎妈呀,好腻害的样子,喘口气看看刚刚发生了什么事情。
献上封装好的HookAMS菊花(GitHubDemo):https://github.com/BolexLiu/AndroidHookStartActivity
做者:香脆的大鸡排 连接:http://www.jianshu.com/p/2ad105f54d07 來源:简书 著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。