探索Android的HOOK之旅
来源:互联网 发布:mysql中的level 编辑:程序博客网 时间:2024/06/05 09:06
探索Android的HOOK之旅
因为项目需求,最近在研究Android的hook方法,总结一下研究的结果,做一个笔记。
因为我只研究了Android中Java层的代码hook,Native层的hook还未实际研究与应用。
一、Hook是什么
Hook的中文翻译是“钩子”,简单的说就是,钩住你的代码,对你的方法执行前后做一些操作,例如:改变方法返回值,改变传入方法的参数,替换现有的方法。
当然,这些改变都是不可以在原有代码上进行更改,因为改变原有方法,有时成本很大,并且很繁琐,而且hook不光是hook自己写的代码,还可以hook系统原有的代码。例如你要更改你代码所有的文字样式,在Android中也就是TextView,如果在应用已经完成,再去自定义一个TextView更改起来就很麻烦,此时你只需要hook住TextView中相应的方法,就可以更改所有文字的样式了。
二、Hook的应用
Hook 的应用场景有很多,前边提到的hook其实并不常用,常用的hook应该就是热更新技术了。所谓的热更新,就是在应用不重新安装新版本,而修复和升级一些bug和功能。
因为热更新技术就是hook应用的完美展现,所以围绕热更新技术去研究hook技术,是一个不错的方向。
三、热更新技术
热更新技术阿里和腾讯都有自己的实现方案,阿里的Sophix,微信用的Tinker,
这是三种热更新技术的对比图。网上有很多详细的,这里就不讲了。
四、我走过的路
因为公司需求并不是热更新,一开始我一直在寻找Android的Hook方法,准确来说是无侵入的Hook方法,就是不改变原有代码的基础上去hook。
最先看的到是Xposed框架,这个框架实现hook更改手机所有应用的代码,框架很好,但是需要手机进行了root权限,这就直接pass了。
后来又找到的Legend的框架,这个的确是实现了我的需求,它只需要很少的代码,就可以hook到你自己应用中的方法,对方法进行更改,但是很可惜,他并不可以在Android 7.0以上的系统上运行。这个作者好像是在高二时候写的(给跪),现在也不更新了,所以只好放弃了。
后来我采用的是YAHFA去做的,这个框架总体还是很好的,支持7.0,虽然7.0是在测试阶段,但是并没有发现什么错误。只不过他不是在本应用中添加代码,而是以插件的形式,把你的代码打包成一个debug.apk,存储到sd卡中,进行加载,从而更改代码。这更像是热更新的操作,只是如果sd卡中删除了这个debug.apk,就失效了。不过热更新用这个应该很不错,我的需求,我更喜欢在本应用中添加hook方法,而不是插件式添加。
五、YAHFA的应用
GitHub地址:https://github.com/rk700/YAHFA
很感谢作者提供的这个框架。
在GitHub中,作者对框架的介绍已经很详细了,我就简单的再说一下。
下载demo后导入Android studio,其中有一个demoApp和demoPlugin,还有一个library,library中就是hook的逻辑,其实hook就是代码的反射调用,AOP编程的一些逻辑,不知道AOP的朋友可以百度一下。
把demoApp安装到你的手机,把demoPlugin打包成一个debug.apk,存入你的手机内存,只要在demoApp中的lication的类中指定这个dubug的路径就好。
在demoPlugin中编写你要hook的方法。
className是指定的hoook的类名
methodName是指定要hook 的方法
methodSig是指定的类型签名
(Ljava/lang/String;)Ljava/net/URI;
(Ljava/lang/String;)Ljava/net/URI;
括号中是参数的签名,括号外是返回值的签名
签名是jni中经常用法哦的,如归不是基本数据类型,就要L开头,后边跟类的全路径名用“/”分割
基本数据类型有自己的类型签名
hook方法是你重写的代码逻辑
origin方法是你的原放啊
如果返回值不是基本数据类型,就写成Object
oringin方法中写什么都可以,不影响运行
1.静态方法
public class Hook_url { public static String className = "java.net.URI"; public static String methodName = "create"; public static String methodSig = "(Ljava/lang/String;)Ljava/net/URI;"; public static Object hook(String url) { Log.w("YAHFA", "in hook_url: "+url); Log.w("YAHFA", "网址"); url = "http://suggest.taobao.com/sug?code=utf-8&q=袜子&callback=cb"; return origin(url); } public static Object origin(String url) { Log.w("YAHFA", "String.startsWith() should not be here"); return url; }}
这是静态方法的hook,静态方法和静态差不多,区别就是,非静态的方法在hook和origin的参数中,多加一个Object 的参数
url是传入的参数,把url更改,在调用origin,这样就是更改了访问网址
2. 非静态方法
public class hookbean { public static String className = "lab.galaxy.yahfa.demoApp.DemoBean"; public static String methodName = "getbean"; public static String methodSig = "(Ljava/lang/String;Ljava/lang/String;)Llab/galaxy/yahfa/demoApp/Bean;"; public static Object hook(Object obj,String a, String b) { Log.w("YAHFA", "in getBean: "+a+b); a = "ni"; b = "咱们"; return origin(obj,a, b); } public static Object origin(Object obj,String a, String b) { Log.w("YAHFA", "ClassWithStaticMethod.tac() should not be here"); return ""; }}
这是非静态方法的hook,返回值是我自定义的类,所以签名是我的全路径,返回值类型是Object
3. 返回值为非基本数据类型
可以参考2,静态和非静态都是如此
4. 参数是非基本数据类型
public class Hook_WebViewClient_onReceivedSslError { public static String className = "android.webkit.WebViewClient"; public static String methodName = "onReceivedSslError"; public static String methodSig = "(Landroid/webkit/WebView;Landroid/webkit/SslErrorHandler;Landroid/net/http/SslError;)V"; public static void hook(Object thiz, WebView webView, SslErrorHandler handler, SslError error) { Log.w("YAHFA", "WebViewClient.onReceivedSslError()"); handler.proceed(); }}
任何情况下都可以不写origin方法,这样只是不调用原方法了
5. Jni方法
以后补充
6. jar中的方法
如果需要hook第三方依赖,jar包的方法,需要把debug.apk中也添加依赖和jar
7.内部类的hook
内部类只是编译时的概念,一旦编译成功,就会出现两个不同的类,例如,类outClass中有个intClass,那么编译后就出现一个名为outClass.class和一个outClass$intClass.class的类。所以className中就要指定类路径为a.b.c.outClass$intClass。
六、总结
Hook主要就是通过反射,有很多例子,都是直接反射调用类,然后更改,只是用了框架,就不用一个个代码去反射调用更该了,省了很多的时间去做一些你更该后的代码优化等操作。
- 探索Android的HOOK之旅
- android的hook技术之hook所有view的监听器
- 探索NDIS HOOK新的实现方法
- 对于SSDT HOOK的疑惑和探索
- Android探索之旅 | 国际化你的App+网站推荐
- Android Hook机制之Binder Hook
- Android探索之旅 | Android简介
- 探索Android的Context之Context是什么
- Android Bitmap开发之旅--OOM探索
- Android探索之旅 | StrictMode严苛模式
- Android之LayoutInflater探索
- android探索之MVP
- android之ExoPlayer探索
- Android逆向之旅---Native层的Hook神器Cydia Substrate使用详解
- Android逆向之旅---Native层的Hook神器Cydia Substrate使用详解
- Android探索之旅(第十一篇) 探索一种更轻,更便捷的操作数据库的库
- Android蓝牙之Gatt Hook
- Android Hook学习之ptrace函数的使用
- Android 6.0指纹识别相关API
- 基于golang http包实现的文件服务器
- 数据结构<三>: 线程结构的应用
- mahony 滤波原理
- ubuntu 12.04中安装Jenkins
- 探索Android的HOOK之旅
- Struts2值栈和OGNL表达式
- 微信小程序发送模板消息
- SQL Server 2008索引使用技巧
- adb 启动命令
- mysql linux 区分大小写问题
- BAT 一键安装JDK
- 牛客网PAT题目1001——A+B和C(Java)
- 2018年及以后的物联网商业趋势