一、前言

Android中hook框架已经非常多了,最优秀的当属Xposed和Substrate了,这两个框架我在之前的文章都详细介绍过了,不了解的同学,可以转战这里:http://www.wjdiankong.cn;但是这两个框架用于破解逆向是非常有用的,可惜他们最大的局限性就是需要root权限,这个几乎现阶段可能阻碍了很多产品的商业化,毕竟国内人的安全意识越来越高了。所以这里就需要借助一个免root的hook框架了。而对于免root的框架最大的好处就在于无需root权限,但是弊端就是只能hook自身,对于系统其它app无能无力,就有人好奇了,只能hook自己有个卵用,的确是没什么用,但是也并非一点用都没有。

二、免root的hook功能用途

关于Android中的Hook机制,我在之前已经说得非常详细了,大致就两个方式:

第一个方式:root权限,直接hook系统,可以干掉所有app。

第二种方式:免root权限,但是只能hook自身。

对于免root权限只能hook自身,并非一点用都没有,比如我之前介绍到的自动破解签名校验工具kstools,就是借助这个原理实现,不了解原理的同学可以看这里:Android中自动破解签名校验工具kstools,我们在破解逆向app的时候,需要反编译,二次打包,那么这时候其实我们想针对于这个app做点手脚,就可以借助这个技术,比如现在想改一个app,使得他获取系统的imei值是随机的,有这种需求的,有的游戏有的功能会用设备的imei值做唯一处理,随机imei值的话就可以跳过这个功能了。那么这时候我们可以反编译这游戏,在游戏入口处加上hook代码,即hook游戏自身的imei值即可,这就是需求,只需要hook这一款游戏即可。这样无需在用xposed来编写外挂了。游戏二次打包即可使用了。

三、以往hook框架原理分析

那么其实免root进行hook功能在之前我已经介绍过了一款阿里的开源框架Dexposed了,不过这个框架已经废弃了,取而代之的是AndFix,原理很简单在native层把Java层的方法强制改成native类型,然后在将方法的native标志指向自定义的native函数即可。这样原来的方法就会走到自定义的native函数中,这个框架是非常优秀的AOP框架,可惜兼容性问题不能继续维护了。取而代之的是AndFix,关于它的原理就更简单了,他没有了AOP功能,直接将原始方法和自定义的新方法信息进行对换,这样原来方法执行的逻辑就是新的方法了。这个框架主要用于热修复,所以没必要需要AOP功能了。而今天介绍的这款框架原理也是类似,只不过觉得比较好的是,他把大部分的功能都放到了Java层,这样的兼容性就非常好了,而且自身的兼容也很优秀。

四、Legend框架原理分析

下面就来介绍一下他的原理,代码量不是很多,框架下载地址可以去github上:https://github.com/asLody/legend,下载下来直接运行就ok了,我们继续来分析它的代码吧:

进入这个方法查看:

到这里我们会发现,他是编译传入进来的class类,然后编译他所有用到了Hook注解的方法,获取其需要hook的方法信息,具体样式为:类名::方法名@参数1#参数2#...

然后解析完了注解获取方法签名信息之后,开始调用hookMethod进行hook操作:

这里看到,每个hook方法必须是static类型的,然后会区分是art还是dalvik的,分别处理,这里直接分析dalvik方法,后面的代码是有一个缓存池,用于缓存每次替换完之后的原始方法信息,为了后面会调用原始方法功能。下面继续来看dalvik方法的hook代码:

这里首先会获取原始方法和hook新方法对应的dalivk的数据结构信息,这个就是框架的核心点了,关于dalivk对应的方法结构体信息大致如下:

  • accessFlags: 各个不同标志位表示此方法的多个属性,其中标志位0x00000100表明此方法是native的
  • registersSize: 该方法总共用到的寄存器个数,包含输入参数所用到的寄存器,还有方法内部另外使用到的寄存器,在调用方法时会为其申请栈内存
  • outsSize: 该方法调用其他方法时使用到的寄存器个数,注意:只有此方法为非native方法时,此值才有效.
  • insSize: 该方法输入参数用到的寄存器个数(registersSize包含此值)
  • insns: 若方法类型为1,这里指向实际的字节码首地址;若方法类型为2,这里指向实际的JNI函数首地址;若方法类型为3,这里为null
  • jniArgInfo: 当方法类型为2时有效,记录了一些预先计算好的信息(具体信息格式与实际CPU架构有关,但总是包含返回值类型),从而不需要在调用的时候再通过方法的参数和返回值实时计算了,提高了JNI调用的速度。如果第一位为1(即0x80000000),则Dalvik虚拟机会忽略后面的所有信息,强制在调用时实时计算
  • nativeFunc: 若方法类型为1,此值无效;若方法类型为2,这里指向dvmCallJNIMethod;若方法类型为3,这里指向实际的处理函数(DalvikBridgeFunc类型)
还记得最后一个参数吗?当初介绍Dexposed框架就是利用这个参数进行操作的,他对应的就是一个方法的native函数,对于AndFix框架,其实也就是直接替换方法的这些结构体信息即可。

替换新旧方法的结构体信息,做到移花积木的功能:

然后就把替换之后额数据写入到内存中,而这里我们要注意的是,操作内存,Java实在不靠谱的,所以这里需要将工作移动到native层做,操作内存数据,指针是万能的,所以就跑到C++中干了:

这里看到,其实不是写入内存,而是对内存数据的一个替换,直接利用指针方便快捷。

五、案例用法

那么到这里,其实我们就大致分析完了这个框架的功能,关于art类型的可以自行分析代码,原理都是一样的,这里的hook机制非常简洁,直接构造出新旧方法对应的虚拟机数据结构,然后替换信息,会写到内存中即可。和阿里的AndFix框架原理几乎一样。分析完了原理之后,接下来才是正事,演示一个案例,这里主要介绍两个案例,首先来看看如何hook系统的imei值:

这里需要用到注解,形式如:类名::方法名,因为这里没有参数信息,所以忽略,然后在定义一个新的hook方法,每个hook方法第一个参数必须是hook方法所属的类类型,这里直接返回imei值为110,然后在获取imei值看看效果:

看到了,hook成功了,操作就是这么简单。

下面再来看一个例子,就是hook应用中所有的webview加载的url值,这个也是这次我要分析这个框架的原因,因为项目需要,想拦截应用所有webview加载的url值:

这里看到了,我们一般用WebView加载url都会走shouldOverrideUrlLoading方法,所以直接hook这个方法即可,看到这里的注解类型也好理解:类名::方法名@参数1#参数2...,这里还有一个重要的知识就是调用callSuper方法可以调用原来的方法,这样我们只做了一层拦截,不要破坏原始方法的执行流程,而这里可以调用原始方法其实就是利用之前提到的原始方法缓存池功能即可实现,这里可以看出有AOP的意思了。运行看一下效果:

这里会把每个页面加载请求的url进行拦截了,这就是我项目想要的功能。

因为上面分析了框架的原理,大部分功能都是在Java层做的,这样很大程度上能够做到兼容,因为这样,我也想尝试利用这个框架来操作项目,毕竟也算是一种尝试。

注意:
1、框架可以选择不使用注解的方式进行hook,直接使用api方式,具体用法参见github上说明。
2、hook的时机最好要早,一般在程序的入口处即可。

六、总结

最后还是想说这个框架本身来说并不是很复杂,但是思想还是很重要,记住这种hook思想对应用开发还是逆向都有很大的帮助,相信未来我们还是有需求需要用到这个优秀的框架。敬请期待!

更多内容:点击这里

关注微信公众号,最新技术干货实时推送

编码美丽技术圈
微信扫一扫进入我的"技术圈"世界

扫一扫加小编微信
添加时请注明:“编码美丽”非常感谢!

Android中免root的hook框架Legend原理解析的更多相关文章

  1. android免root hook框架legend

    一.前言 Android中hook框架已经非常多了,最优秀的当属Xposed和Substrate了,这两个框架我在之前的文章都详细介绍过了,不了解的同学,可以转战这里:http://www.wjdia ...

  2. Android进阶:七、Retrofit2.0原理解析之最简流程【下】

    紧接上文Android进阶:七.Retrofit2.0原理解析之最简流程[上] 一.请求参数整理 我们定义的接口已经被实现,但是我们还是不知道我们注解的请求方式,参数类型等是如何发起网络请求的呢? 这 ...

  3. [置顶] 滴滴插件化框架VirtualAPK原理解析(一)之插件Activity管理

    上周末,滴滴与360都开源了各自的插件化框架,VirtualAPK与RePlugin,作为一个插件化方面的狂热研究者,在周末就迫不及待的下载了Virtualapk框架来进行研究,本篇博客带来的是Vir ...

  4. android黑科技系列——微信抢红包插件原理解析和开发实现

    一.前言 自从几年前微信添加抢红包的功能,微信的电商之旅算是正式开始正式火爆起来.但是作为Android开发者来说,我们在抢红包的同时意识到了很多问题,就是手动去抢红包的速度慢了,当然这些有很多原因导 ...

  5. APP自动化框架-ATX原理解析及JAVA版客户端

    作为网易开源的ATX APP自动化测试框架,对比现有的macaca自动化框架/Appium自动化框架,最大的特别就是在于可远程进行自动化测试 先给大家看一张我自己梳理的框架架构图 框架巧妙点: 1. ...

  6. 分布式服务框架dubbo原理解析(转)

    libaba有好几个分布式框架,主要有:进行远程调用(类似于RMI的这种远程调用)的(dubbo.hsf),jms消息服务(napoli.notify),KV数据库(tair)等.这个框架/工具/产品 ...

  7. 分布式服务框架dubbo原理解析 转

    alibaba有好几个分布式框架,主要有:进行远程调用(类似于RMI的这种远程调用)的(dubbo.hsf),jms消息服务(napoli.notify),KV数据库(tair)等.这个框架/工具/产 ...

  8. Android进阶:七、Retrofit2.0原理解析之最简流程【上】

    retrofit 已经流行很久了,它是Square开源的一款优秀的网络框架,这个框架对okhttp进行了封装,让我们使用okhttp做网路请求更加简单.但是光学会使用只是让我们多了一个技能,学习其源码 ...

  9. 分布式服务框架dubbo原理解析

    alibaba有好几个分布式框架,主要有:进行远程调用(类似于RMI的这种远程调用)的(dubbo.hsf),jms消息服务(napoli.notify),KV数据库(tair)等.这个框架/工具/产 ...

随机推荐

  1. php 与 c++ openssl 加密通信

    $key = '1234567890123456'; $iv = '1234567890123456'; $enc = openssl_encrypt("hello wolrd!" ...

  2. MySQL索引失效的场景

    WHERE字句的查询条件里有不等于号(WHERE column!=-),MYSQL将无法使用索引 类似地,如果WHERE字句的查询条件里使用了函数(如:WHERE DAY(column)=-),MYS ...

  3. mysql数据库建表

    主键的问题: 简单的id递加.不过在实习的时候,因为id递增的问题,导致一个项目最后好像产生了严重的问题.所以递增适合小型项目,对我们的项目来说90%足够可以用的. 一些限制: 一般就非空就行,唯一的 ...

  4. ADC第一次读取

    在ADCCON中,最后0位和1位互斥.如果1位选1的话,0位的值无效.如果1位选0的话,0位的值才有效.当1位选1的话:这是应用层的程序 #if ADSTART==0void niuniu(void) ...

  5. JSP 国际化

    在开始前,需要解释几个重要的概念: 国际化(i18n):表明一个页面根据访问者的语言或国家来呈现不同的翻译版本. 本地化(l10n):向网站添加资源,以使它适应不同的地区和文化.比如网站的印度语版本. ...

  6. pfSense 2.4.3 发布,包含重要的安全修复补丁

    pfSense 2.4.3 已发布,本次更新包含重要的安全修复和 bug 修复,还引入了一些新特性,具体如下. 值得关注的更新 包含一些重要的安全修复补丁: Kernel PTI mitigation ...

  7. kindeditor支持flv视频播放方法

    打开plugins\media下面的media.js,打开,找到下面的代码: var html = K.mediaImg(self.themesPath + ‘common/blank.gif’, { ...

  8. 11.深入理解读写锁ReentrantReadWriteLock

    protected final int tryAcquireShared(int unused) { /* * Walkthrough: * 1. If write lock held by anot ...

  9. jQuery-瀑布流的取巧做法分享

      分析:瀑布流,做法有2种 (1)绝对定位方案:每个单元格设置为绝对定位,通过计算,分别设置 top , left 即可实现 (2)浮动方案:弄N列布局(浮动),然后图片数据,按顺序依次插入,如N为 ...

  10. Struts2异常处理配置

    <package name="lee" extends="struts-default"> <!--定义全局结构映射 --> <g ...