首页
社区
课程
招聘
[原创]如何写一个Android inline hook框架_新增功能或修复bug_浮点相关的问题
发表于: 2020-1-8 12:24 7285

[原创]如何写一个Android inline hook框架_新增功能或修复bug_浮点相关的问题

2020-1-8 12:24
7285

之前的hook框架已经可以满足绝大多数需求,但是设计之初未详细的看完arm64下浮点相关的部分,以为和arm一样也是通过通用寄存器、栈传递,现在修复这一部分,这个bug只对dump读写寄存器相关的部分有影响,对replace部分(采用定义一个和被hook函数原型一致的函数)无影响。

目前来看arm浮点参数,float参数占用一个寄存器或者栈,double占用相邻的两个寄存器或栈;返回值float还是占用寄存器r0,double占用寄存器r0和r1。所以可以不考虑保存浮点寄存器s0-s31/d0-d31/q0-q15。如果有例外情况请告诉我,这些寄存器应该是NEON相关的,所以armv7-a/r以下的应该是不存在这些寄存器和指令的(好像有的资料说armv6也有类似的浮点指令)?
图片描述
如上图,传参通过r0、r1,返回通过r0。

但是arm64传参使用的是float从s0开始为第一个浮点参数,double从d0开始为第一个浮点参数,返回值float为s0,double为d0,所以应该保存浮点寄存器和提供接口。
图片描述
如上图,传参通过D0、D1,返回通过D0。

图片描述
如上图,传参通过S0、S1,返回通过S0。

图片描述
如上图,传参通过W0、S0、S1,返回通过S0。

图片描述

按说把浮点寄存器存储在栈的最底部比较好,但是代码改动稍微有点大(其实是偏移都要改一遍),所以放在最顶层吧。

编译器貌似并不支持存储V0-V31,还是像armv7的neon一样使用Q0-Q31(armv7只有Q0-Q15,16个128位的寄存器)。Q0-Q31可以拆成D0-D31,D0占Q0的低64位,D1占Q1的低64位;同时也可以拆成S0-S31,S0占Q0的低32位,S1占Q1的低32位。不清楚为什么这么设计,感觉有些浪费。

为了方便这里定义一个联合体,qregs就是128位的Q0-Q31,dregs为了方便解析double,同理fregs为了方便解析float。

通过这样的方式操作浮点相关的寄存器,完成对double、float参数、返回值的读写。

例如这样操作。
图片描述

图片描述

在arm64下很多框架都是采用X16、X17,多是X17寄存器完成跳转,那么简单分析下这个流程:
1、跳板/shellcode类似如下:

2、hook函数内调用原函数,那么执行完备份/修复的几条指令后,还要使用X17跳回被hook的函数。

x16、x17一般只在plt中使用,那么x17一般都是保存的一个函数的地址。

但是上面的步骤2肯定不是跳到函数的起始地址,而是函数起始地址+16(或者更大,看修复指令的情况)。那么根据自身的业务场景在容易被hook的函数内检测X17寄存器的值是不是就是当前函数的地址+(16到32),如果在这个范围内,那么就可以认为当前函数被hook了。实现方式多种多样,例如内嵌汇编获取X17寄存器的值。


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 4
支持
分享
最新回复 (4)
雪    币: 6737
活跃值: (796)
能力值: ( LV13,RANK:393 )
在线值:
发帖
回帖
粉丝
2
我对arm64指令集的了解不如arm32,如果还有哪些错误,请大佬们多多提出
2020-1-8 12:33
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
感谢分享
2020-1-8 14:48
0
雪    币: 26245
活跃值: (63297)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
4
感谢分享!
2020-1-11 15:55
0
雪    币: 200
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5

mprotect有时候会返回Permission denied错误,在调用RebuildHookTarget的时候

最后于 2020-6-12 12:17 被liro编辑 ,原因:
2020-6-12 12:15
0
游客
登录 | 注册 方可回帖
返回
//