2019独角兽企业重金招聘Python工程师标准>>>

许久没搞安全方面的东西了。最近有些时间看了看android下面的开发,看去看来总是想往内深入,结果又往Native和内核挖过去了……

研究了一下ARM架构下面的inline实现,网上搜了搜似乎没有找到多少资料。想了想还是写出来吧,当作笔记。由于时间不多,也不是为工作而看, 仅仅是做了粗略的实现和研究,并没有深入下去。这篇手记的目的不在于详细描述整个HOOK实现的过程,而仅仅对一些关键点作一些描述。

说到Inline hook,了解这个词的同志们都应该知道,无非是修改目标函数处的指令,跳转到自己的函数,并且提供调用原函数的stub,即可完成整个流程。但是在 ARM下面情况和我们熟悉的x86有所不同。ARM芯片的运行状态分为arm和thumb两种模式,分别有不同的指令集,arm指令为定长32 位,thumb指令为定长16位(thumb-2中进行了扩展,可以使用32位thumb指令)。同一段代码中可以混用两套指令集,通过一些带有 interworking功能的跳转或者load指令可以在两种模式间切换。做ARM下的inline,首先遇到的就是指令模式的问题。另外,ARM架构 下,CPU也具有分开的指令缓存和数据缓存,类似x86下的DTLB和ITLB。但是在实现过程中发现,arm的缓存作用非常明显,而且刷新机制不太确 定,因此自修改代码需要经常主动控制缓存的刷新。这一点,可以通过NDK的API cacheflush实现。

下面简单说说一些主要问题:

  • 关于页保护

    这一点对于熟悉Linux编程的同志们应该不是问题,mprotect修改为PROT_READ | PROT_WRITE | PROT_EXEC即可。页面大小可以通过包含ndk下面<asm/page.h>文件,里面定义的一系列宏用于获得页面大小和进行对齐运 算。

  • 关于模式转换和跳转

    Arm下主要的分支指令如BX,BLX等,都可以切换指令模式。详见arm的用户手册。这里主要讨论模式的选择和切换时机。只有一个问题需要注 意,arm处理器执行时,由于流水线的关系,会预取两条指令,因此当前指令取到的pc值,始终是之后第三条指令的地址。比如当前指令地址是0×8000, 那么当前pc的值,在thumb下面是0×8000 + 2 * 2, 在arm下面是0×8000 + 4 * 2。

    由于运行时我没有找到简便的办法能够确切知道被hook的目标函数指令集,所以这个问题留给了hook的使用者来决定。Hook之前应通过逆向工具获知所有目标函数是arm还是thumb指令。

    如果要根据目标函数指令集的不同而对hook函数采用不同的 编译选项,显然是一件麻烦的事情。而arm模式的指令由于单条指令包含的语义更多,是我们的首选。因此可以考虑主仅使用arm指令编译hook函数,而在跳转的同时切换到arm模式。

    关于跳转插入的指令方面,由于arm指令带立即数的跳转范围只有4M,thumb的跳转范围只有256字节。所以首选ldr pc,xxxx指令来实现。对于arm指令的目标,这个指令很容易选择。如下:

    ldr pc, [pc,#-4]

    32位跳转绝对地址

    指令为单个32位数字:0xE51FF004。

    但是thumb模式下的16位ldr指令没有办法向pc中load,选择就很成问题。如果单纯使用16位thumb指令的话,跳转部分需要占用大量 字节数,而因为arm下面编译器常常使用pc的值作为基址来计算地址,被搬动过的指令中就极有可能存在这种指令。搬动过后的代码中就必须对这部分指令进行 修正,而又由于thumb所能够支持的立即数很小,跳转范围也很小,这种修正往往非常麻烦,需要用几条同等指令来替换一条指令。经过考虑,还是决定放弃对 ARMv5的支持,直接使用ARMv6T2之后支持的thumb-2指令集。thumb-2支持32位thumb指令,也支持ldr以pc为目标寄存器:

    ldr.w pc,[pc,#0]

    32位跳转绝对地址

    指令为单个32位数字:0x00F0DFF8

    所有需要跳转的地址,需要注意的是bit0的处理。如果bit0为1,跳转后会切换到thumb指令模式,如果bit0为0,会切换至arm模式。 当目标为arm的时候,我们不需要特殊处理,编译器会处理地址的计算。但是当目标为thumb的时候,从hook指令跳转到hook函数,以及调用原始函 数的时候,都需要注意地址bit0的处理。

  • 关于搬出来的原始指令

    按照win32下Detours库的实现方式,被HOOK函数的前面几条指令,会搬到一个trampoline中,并在这些指令后添加跳转至原代码 后续部分的指令。在搬动过程中,需要对被移动的指令进行地址修正。在处理ARM平台inline的过程中也需要作这样的工作。但是实际上在处理的时候会发 现,要做到这一点是非常困难的。ARM下常常会生成下面这种将pc作为地址参照的指令块

    而由于arm平台寻址范围较小,编译器通常选择将数据和指令在内存中的存放混杂在一起。thumb模式下,由于指令中能包含的立即数非常小,这种问 题会表现得异常突出,修正的时候也常常一条指令被拉长为数条。因此代码修正会有非常大的工作量。这部分问题由于太消耗时间,我也仅仅是对arm下的 inline进行研究性实现,也就没有管这个问题了。实际项目如果要用到hook,这个部分花费的时间应该比单纯hook跳转的实现要大得多。在不考虑并 发和效率的情况下,当hook函数中要调用原函数时,可以考虑临时恢复hook,并在调用完成后再次hook来解决。但是始终是相当不优雅的实现。

  • 关于线程处理

    修改hook目标的指令时,和x86平台下一样,也需要注意有可能某些线程刚好执行到被修改的指令中的问题。Win32下可以枚举线程并修改 context到被搬迁的指令中去。但是Linux内核系统下很难进行线程的控制。估计可以采用接管信号处理,并向进程内所有线程调用 pthread_kill来实现。

转载于:https://my.oschina.net/zhuzihasablog/blog/141872

Android inline hook手记相关推荐

  1. 如何写一个Android inline hook框架

    Android_Inline_Hook https://github.com/GToad/Android_Inline_Hook_ARM64 有32和64的实现,但是是分离的,要用的话还要自己把两份代 ...

  2. Android Native Hook工具

    前言 在目前的安卓APP测试中对于Native Hook的需求越来越大,越来越多的APP开始逐渐使用NDK来开发核心或者敏感代码逻辑.个人认为原因如下: 安全的考虑.各大APP越来越注重安全性,NDK ...

  3. android hook 实例,代码实例分析android中inline hook

    以下内容通过1.实现目标注入程序,2.实现主程序,3.实现注入函数,4.thumb指令集实现等4个方面详细分析了android中inline hook的用法,以下是全部内容: 最近终于沉下心来对着书把 ...

  4. android socket_盘点Android常用Hook技术

    Android平台开发测试过程中,Hook技术是每个开发人员都常用的技术.可以用于绕过系统限制.修改别人发布的代码.动态化.调用隐藏API.插件化.组件化.自动化测试.沙箱等等. Hook如果要跨进程 ...

  5. Android Art Hook 技术方案

    Android Art Hook 技术方案 by 低端码农 at 2015.4.13 www.im-boy.net 0x1 开始 Anddroid上的ART从5.0之后变成默认的选择,可见ART的重要 ...

  6. PLT hook与Inline hook

    前言 在目前的安卓APP测试中对于Native Hook的需求越来越大,越来越多的APP开始逐渐使用NDK来开发核心或者敏感代码逻辑. 个人认为原因如下: 安全的考虑.各大APP越来越注重安全性,ND ...

  7. 关于LD_PRELOAD在Android API HOOK中的应用

    原址 受xposed启发,有了一些想法. 我以前都是通过注入的形式,拦截目标进程的API,从而达到一些目的.这个方法相对笨拙,每次都需要注入(启动时):关键问题是,除非做成INLINE HOOK,否则 ...

  8. Android安全 Hook技术,AndroidHook技术分析.pdf-北京理工大学信息系统及安全对抗实验中心.PDF...

    AndroidHook技术分析.pdf-北京理工大学信息系统及安全对抗实验中心.PDF The name of the DepartmentBeijing Forest Studio 北京理工大学信息 ...

  9. Android Native Hook

    Hook 直译过来就是"钩子"的意思,是指截获进程对某个 API 函数的调用,使得 API 的执行流程转向我们实现的代码片段,从而实现我们所需要得功能,这里的功能可以是监控.修复系 ...

最新文章

  1. Markdown编辑表格时如何输入竖线('|', pipe,vertical bar)
  2. Linux重启命令reboot
  3. mysql数据库备份出错_mysql数据库备份成功,再还原却失败,什么原
  4. vue实现两个数组的合并
  5. 漏洞发布平台-安百科技
  6. react不同环境不同配置angular_叫雨山斗鸡优势在哪里,环境不同,价值不同
  7. 基于.Net + SqlServer的分库分表设计方案
  8. python中command是什么意思_python 设计模式之命令(Command)模式
  9. 怎么学好MYSQL的查和改_mysql学习【第3篇】:数据库之增删改查操作
  10. 集五福开奖啦!六年累计7亿人参加 今年你中了多少?
  11. c语言程序的基本规范是什么,C语言编程规范——3 命名规则
  12. 2012浙大878计算机专业基础综合大题答案解析
  13. tde数据库加密_在其他服务器上还原启用了透明数据加密(TDE)的数据库
  14. js 与||的妙用
  15. 设备树与驱动的关系_9 Linux设备树的原理与应用实例(一)—— 什么是设备树...
  16. (11) python 使用baostock获取历史A股K线数据
  17. AI计算机视觉产品中长尾用户,基于长尾理论的AI写作具体分析
  18. 年纪大的程序员慢慢都流向什么地方去了?
  19. 团队作业第二次—项目选题报告
  20. 常用视频质量评价库以及下载地址

热门文章

  1. ArcGIS Server 10.2 安装教程
  2. 计算机视觉与深度学习 | K-means聚类算法在计算机视觉中的应用之图像分割
  3. 数据结构学习笔记(一):链表(linked list)
  4. 增强型的for循环linkedlist_Java: 增强for循环针对list的时候,是严格按照list的顺序依次遍历的吗?...
  5. php7 参数类型限定,PHP参数类型限制 - Corwien的博客 - OSCHINA - 中文开源技术交流社区...
  6. windows编程一日一练(2)
  7. 计算机设备全年销量excel,计算机二级MS-OFFICE考试EXCEL题型汇总附答案.pdf
  8. iphone屏幕录制_如何将iPhone投屏到Mac上?iphone投屏到苹果电脑方法
  9. bai的字怎么写_教师节贺卡祝福语怎么写?教师节贺卡贺词祝福语精简20个字
  10. PyQt5 参考文档