吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2475|回复: 1
收起左侧

[Android 原创] luckfollowme arm 学习篇 08 - dobby function inline hook

  [复制链接]
2016976438 发表于 2023-5-1 12:29

luckfollowme arm 学习篇 08 - dobby function inline hook

接下来才是真正的进入主题,也是最关键的地方。

查看 dobby inline hook 变化

首先,我们得分析 它在我们 sum 方法做了什么,导致跳转到 fake_sumhook 方法。

又能够通过 orig_sum 执行到原方法。

1.首先我们启动下项目,卡在 没有hook 的地方

adb shell "/data/local/tmp/dobby_test"
输入任意键开始hook...

2.然后用ida pro 先分析一遍没有 hook 时候的字节码

</p>

01.png

</p>

摘抄出来是这样的,由于之前是分析过了的,您直接看我的注释就可以了

# 开辟局部变量空间
SUB             SP, SP, #0x40
# 取出 a9 a10
LDR             X9, [SP,#0x40]
LDR             X8, [SP,#0x48]
# 将 a1 - a8 放入局部变量中
STR             W0, [SP,#0x3C]
STR             W1, [SP,#0x38]
STR             W2, [SP,#0x34]
STR             W3, [SP,#0x30]
STR             W4, [SP,#0x2C]
STR             W5, [SP,#0x28]
STR             W6, [SP,#0x24]
STR             W7, [SP,#0x20]
STR             X9, [SP,#0x18]
STR             X8, [SP,#0x10]
# sum = a1 + a2 + a3 + a4 + a5 + a6 + a7+ a8
LDR             W8, [SP,#0x3C]
LDR             W9, [SP,#0x38]
ADD             W8, W8, W9
LDR             W9, [SP,#0x34]
ADD             W8, W8, W9
LDR             W9, [SP,#0x30]
ADD             W8, W8, W9
LDR             W9, [SP,#0x2C]
ADD             W8, W8, W9
LDR             W9, [SP,#0x28]
ADD             W8, W8, W9
LDR             W9, [SP,#0x24]
ADD             W8, W8, W9
LDR             W9, [SP,#0x20]
ADD             W8, W8, W9
# 储存 sum 变量
STR             W8, [SP,#0xC]
# sum2 = a9 + a10
LDR             X8, [SP,#0x18]
LDR             X9, [SP,#0x10]
ADD             X8, X8, X9
STR             X8, [SP]
# if (sum > 10)
LDR             W8, [SP,#0xC]
SUBS            W8, W8, #0xA
# if (sum > 10) 条件不成立
B.LE            loc_753EDCE934

# if (sum > 10) 条件成立
B               loc_753EDCE91C

; ---------------------------------------------------------------------------

loc_753EDCE91C 
# 读取 并 转换 64 位 的 sum
LDRSW           X8, [SP,#0xC]
# 读取 sum2 
LDR             X9, [SP]
# sum + sum2
ADD             X8, X8, X9
# 获取 _global_sum 全局变量
ADRP            X9, #_global_sum@PAGE
# _global_sum = sum + sum2 
STR             X8, [X9,#_global_sum@PAGEOFF]
B               loc_753EDCE934

; ---------------------------------------------------------------------------

loc_753EDCE934                          
# 读取 全局变量
ADRP            X8, #_global_sum@PAGE
LDR             X8, [X8,#_global_sum@PAGEOFF]
# 放入 x0 转换 int32
MOV             W0, W8
# 释放局部变量空间
ADD             SP, SP, #0x40 ; '@'
# 返回 x0
RET

接下来我们输入任意键 完成 hook

输入任意键开始hook...

hook sum:0x753edce888
进入到 hook 方法,参数:1,2,3,4,5,6,7,8,10,20
调用 原方法获取的结果:66
sum:66

您在看 ida pro  可能您并不会看到改变,但是您如果在 sum 方法的 0xC 字节后下个断点

</p>

02.png

</p>

此时您就可以发现到变化了

可以发现它修改了我们的 0XC 个字节。

其余的并没有任何的变化。

所以我们分析下这 12 个字节

11 00 00 90 31 A2 28 91       ADRL            X17, _ZL8fake_sumiiiiiiiimm

20 02 1F D6                   BR              X17

Dobby inline asm 分析

dobby 生成的 ADRL 明显是个伪指令 。 因为他有着 8个 字节的长度 ,ida pro 给我们分析成了符号 _ZL8fake_sumiiiiiiiimm

所以这明显就是将 fake_sum hook 的方法的 地址 赋值给了 X17

后面的BR 是一个绝对跳转。 相较于 B #立即数          绝对跳转指令         BR(branch register)  可以根据寄存器中的地址 跳转到任意地方,寻址更大。

稍微翻译一下就是

# 后期 pc 当前内存对齐的地址
adrp         x17, =当前PC内存对齐地址
# 添加 fake_sum 的偏移 
add         x17, x17, #0xa28
# 绝对跳转
BR          X17

fake_sum arrch64

我们通过 ADRL            X17, _ZL8fake_sumiiiiiiiimm 进去看看 fake_sum 生成的汇编指令:

FF 83 01 D1                   SUB             SP, SP, #0x60
FD 7B 05 A9                   STP             X29, X30, [SP,#0x50]
FD 43 01 91                   ADD             X29, SP, #0x50 ; 'P'
A9 0B 40 F9                   LDR             X9, [X29,#0x10]
A8 0F 40 F9                   LDR             X8, [X29,#0x18]
A0 C3 1F B8                   STUR            W0, [X29,#-4]
A1 83 1F B8                   STUR            W1, [X29,#-8]
A2 43 1F B8                   STUR            W2, [X29,#-0xC]
A3 03 1F B8                   STUR            W3, [X29,#-0x10]
A4 C3 1E B8                   STUR            W4, [X29,#-0x14]
A5 83 1E B8                   STUR            W5, [X29,#-0x18]
A6 43 1E B8                   STUR            W6, [X29,#-0x1C]
A7 03 1E B8                   STUR            W7, [X29,#-0x20]
E9 17 00 F9                   STR             X9, [SP,#0x28]
E8 13 00 F9                   STR             X8, [SP,#0x20]
A1 C3 5F B8                   LDUR            W1, [X29,#-4]
A2 83 5F B8                   LDUR            W2, [X29,#-8]
A3 43 5F B8                   LDUR            W3, [X29,#-0xC]
A4 03 5F B8                   LDUR            W4, [X29,#-0x10]
A5 C3 5E B8                   LDUR            W5, [X29,#-0x14]
A6 83 5E B8                   LDUR            W6, [X29,#-0x18]
A7 43 5E B8                   LDUR            W7, [X29,#-0x1C]
AB 03 5E B8                   LDUR            W11, [X29,#-0x20]
EA 17 40 F9                   LDR             X10, [SP,#0x28]
E8 13 40 F9                   LDR             X8, [SP,#0x20]
E9 03 00 91                   MOV             X9, SP
2B 01 00 B9                   STR             W11, [X9]
2A 05 00 F9                   STR             X10, [X9,#8]
28 09 00 F9                   STR             X8, [X9,#0x10]
C0 FF FF 90 00 08 3B 91       ADRL            X0, unk_753EDC6EC2
8B 79 00 94                   BL              unk_753EDED0D0

08 01 00 F0                   ADRP            X8, #_ZL8orig_sumhome.php?mod=space&uid=1953840  ; orig_sum
08 11 47 F9                   LDR             X8, [X8,#_ZL8orig_sum@PAGEOFF] ; orig_sum
A0 C3 5F B8                   LDUR            W0, [X29,#-4]
A1 83 5F B8                   LDUR            W1, [X29,#-8]
A2 43 5F B8                   LDUR            W2, [X29,#-0xC]
A3 03 5F B8                   LDUR            W3, [X29,#-0x10]
A4 C3 5E B8                   LDUR            W4, [X29,#-0x14]
A5 83 5E B8                   LDUR            W5, [X29,#-0x18]
A6 43 5E B8                   LDUR            W6, [X29,#-0x1C]
A7 03 5E B8                   LDUR            W7, [X29,#-0x20]
EB 17 40 F9                   LDR             X11, [SP,#0x28]
E9 13 40 F9                   LDR             X9, [SP,#0x20]
EA 03 00 91                   MOV             X10, SP
4B 01 00 F9                   STR             X11, [X10]
49 05 00 F9                   STR             X9, [X10,#8]
00 01 3F D6                   BLR             X8

E0 1F 00 B9                   STR             W0, [SP,#0x1C]
E1 1F 40 B9                   LDR             W1, [SP,#0x1C]
C0 FF FF 90 00 EC 27 91       ADRL            X0, unk_753EDC69FB
76 79 00 94                   BL              unk_753EDED0D0

E0 1F 40 B9                   LDR             W0, [SP,#0x1C]
FD 7B 45 A9                   LDP             X29, X30, [SP,#0x50]
FF 83 01 91                   ADD             SP, SP, #0x60 ; '`'
C0 03 5F D6                   RET

代码有点多,我们逐步分析,在此之前你先记住 fake_name 方法体内部是啥样子,到时候我们一一对比。

install_hook_name(sum,int, int a1, int a2,int a3,int a4,int a5,int a6,int a7,int a8,uint64_t a9,uint64_t a10){
    printf("进入到 hook 方法,参数:%d,%d,%d,%d,%d,%d,%d,%d,%llu,%llu \n",a1,a2,a3,a4,a5,a6,a7,a8,a9,a10);
    int ret =   orig_sum(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10);
    printf("调用 原方法获取的结果:%d\n",ret);
    return ret;
}

首先第一行指令是 SUB             SP, SP, #0x60 表示 局部变量使用的空间

|-60                        <=== SP 指针位置
|-5C
|-58
|-54
|-50
|-4C
|-48
|-44
|-40
|-3C
|-38
|-34
|-30
|-2C
|-28
|-24
|-20
|-1C
|-18
|-14
|-10
|-C
|-8
|-4
| 0                

STP

STP (Store Pair) 用于储存一对寄存器到 寄存器中

所以 下面这条指令执行后

STP             X29, X30, [SP,#0x50]

栈应该是这样的:

|-60                        <=== SP 指针位置
|-5C
|-58
|-54
|-50                        
|-4C
|-48                        
|-44
|-40
|-3C
|-38
|-34
|-30
|-2C
|-28
|-24
|-20
|-1C
|-18
|-14
|-10                x29
|-C
|-8                        x30
|-4
| 0                        

x29 和 x30 是两个 关键的寄存器。

它们分别代表着 帧指针 FP  和 链接指针 LR

LR 各位肯定是知道的。 FP 按照网上的意思是说 它代表着栈低  SP 代表着栈顶

参数

下面就是传过来的参数 保存在 栈中,只不过要注意的是,它并不是直接使用 SP 而是从  栈的 -10 的地方开始计算。 这样可以很方便获取栈中 a9-a10 的参数

 # 从 sp -10 的地方开算
 FD 43 01 91                   ADD             X29, SP, #0x50 ; 'P'
 # 根据调用约定 x0-x7 额外的参数放入栈中 
 # 所以 x9 = a10
 A9 0B 40 F9                   LDR             X9, [X29,#0x10]
 # x8 = a9
 A8 0F 40 F9                   LDR             X8, [X29,#0x18]
 # stur 貌似是有符号的 str 指令 
 # 所以下面储存  a1-a8 的参数
 A0 C3 1F B8                   STUR            W0, [X29,#-4]
 A1 83 1F B8                   STUR            W1, [X29,#-8]
 A2 43 1F B8                   STUR            W2, [X29,#-0xC]
 A3 03 1F B8                   STUR            W3, [X29,#-0x10]
 A4 C3 1E B8                   STUR            W4, [X29,#-0x14]
 A5 83 1E B8                   STUR            W5, [X29,#-0x18]
 A6 43 1E B8                   STUR            W6, [X29,#-0x1C]
 A7 03 1E B8                   STUR            W7, [X29,#-0x20]
 # 储存 a10 和 a9
 E9 17 00 F9                   STR             X9, [SP,#0x28]
 E8 13 00 F9                   STR             X8, [SP,#0x20]

那么现在换算栈中的样子:

|-60                        <=== SP 指针位置
|-5C
|-58
|-54
|-50                        
|-4C
|-48                        
|-44
|-40                a10
|-3C
|-38                a9
|-34
|-30                a8
|-2C                a7
|-28                a6
|-24                a5
|-20                a4
|-1C                a3
|-18                a2
|-14                a1
|-10                x29                
|-C
|-8                        x30
|-4
| 0                        a10
| 4
| 8                        a9

调用方法

之前的指令应该都只是对标着传参

int fake_sum(sum,int, int a1, int a2,int a3,int a4,int a5,int a6,int a7,int a8,uint64_t a9,uint64_t a10)

后面的代码是:

printf("进入到 hook 方法,参数:%d,%d,%d,%d,%d,%d,%d,%d,%llu,%llu \n",a1,a2,a3,a4,a5,a6,a7,a8,a9,a10);

来看看对应的 arm

# 首先准备  x1 ~ x7 的参数 也就是 a1,a2,a3,a4,a5,a6,a7
LDUR            W1, [X29,#-4]
LDUR            W2, [X29,#-8]
LDUR            W3, [X29,#-0xC]
LDUR            W4, [X29,#-0x10]
LDUR            W5, [X29,#-0x14]
LDUR            W6, [X29,#-0x18]
LDUR            W7, [X29,#-0x1C]
# x11 = a8
LDUR            W11, [X29,#-0x20]
# 获取 a9 和 a10
LDR             X10, [SP,#0x28]
LDR             X8, [SP,#0x20]
# 获取栈顶 x9 = sp
MOV             X9, SP
# 多余的参数储存在栈中 
# [sp] = a8
STR             W11, [X9]
# [sp + 0x8] = a9
STR             X10, [X9,#8]
# [sp + 0x10] = a10
STR             X8, [X9,#0x10]
# 获取 字符串的地址 (进入到 hook 方法,参数...)
ADRL            X0, aHookDDDDDDDDLl     ; "进入到 hook 方法,参数:%d,%d,%d,%d,%d,%d,%d,%d,"...
# 调用 printf 并 记录 LR 
BL              printf

此时调用后栈应该变成了:

|-60                a8        <=== SP 指针位置
|-5C
|-58                a9
|-54
|-50                a10        
|-4C
|-48                        
|-44
|-40                a10
|-3C
|-38                a9
|-34
|-30                a8
|-2C                a7
|-28                a6
|-24                a5
|-20                a4
|-1C                a3
|-18                a2
|-14                a1
|-10                x29                
|-C
|-8                        x30
|-4
| 0                        a10
| 4
| 8                        a9

orig_sum

接下来是重点。我们分析下 orig_sum 是如何调用原有的方法。

首先我们看下传参调用的过程:

# 获取 orig_sum 方法地址放入到 x8 中
ADRP            X8, #_ZL8orig_sum@PAGE  ; orig_sum
LDR             X8, [X8,#_ZL8orig_sum@PAGEOFF] ; orig_sum
# 准备 x0-x7 的参数
LDUR            W0, [X29,#-4]
LDUR            W1, [X29,#-8]
LDUR            W2, [X29,#-0xC]
LDUR            W3, [X29,#-0x10]
LDUR            W4, [X29,#-0x14]
LDUR            W5, [X29,#-0x18]
LDUR            W6, [X29,#-0x1C]
LDUR            W7, [X29,#-0x20]
# 其余的参数放入到 栈中
# x11 = a9
LDR             X11, [SP,#0x28]
# x9 = a10
LDR             X9, [SP,#0x20]
# x10 = sp
MOV             X10, SP
# [sp] = a9
STR             X11, [X10]
# [sp + 8] = a10
STR             X9, [X10,#8]
# 调用 orig_sum
BLR             X8

接下来我们进入 orig_sum 看看它做了什么:

</p>

03.png

</p>

不知道各位熟悉这个代码么?

如果大伙不记得看下面的图, (只看前12个字节)

</p>

</p>

这个图就是之前 没有hook前 sum方法的图。

由于之前的忘记 按 Q转换 并且没有显示字节码。 但我可以肯定告诉你,它们是一样的

我把 orig_sum 截取出来大伙看看

FF 03 01 D1                   SUB             SP, SP, #0x40 ; '@'
E9 23 40 F9                   LDR             X9, [SP,#0x40]
E8 27 40 F9                   LDR             X8, [SP,#0x48]

                              _753EDCE894
51 00 00 58                   LDR             X17, =0x753EDCE894
20 02 1F D6                   BR              X17

前面12 个字节都好说,就是之前 sum 被替换成 跳转指令之前的样子

下面是目前被替换成的代码:

# 获取 fake_sum 地址 放入 x17
11 00 00 90 31 A2 28 91       ADRL            X17, _ZL8fake_sumiiiiiiiimm
# 绝对地址跳转 到 fake_sum                                        
20 02 1F D6                   BR              X17

那后面的两条指令是跳到哪里呢?

51 00 00 58                   LDR             X17, =0x753EDCE894
20 02 1F D6                   BR              X17

我们在 ida proG 跳转下:

</p>

04.png

</p>

可以很明显的发现  =0x753EDCE894 地址就是 原来 sum  的 12字节 后面的地方。

那么当执行完 sum 方法后,又如何跳到 我们的 fake_sum 接着往下执行呢?

之前说过 , RET 指令会根据 x30(LR) 链接寄存器的值来跳转。

所以这也是为什么 fake_sum 在调用 orig_sum 的时候 选择了 BLR 指令。

orig_sum 则只使用 BR 指令

下面是摘取的 fake_sumorig_sum 的片段:

# fake_sum 调用 orig_sum 的片段
ADRP            X8, #_ZL8orig_sum@PAGE  ; orig_sum
LDR             X8, [X8,#_ZL8orig_sum@PAGEOFF] ; orig_sum
.....
BLR             X8
# orig_sum 跳到 sum 的片段
LDR             X17, =0x753EDCE894
BR              X17

RET

剩余 fake_sum 的返回也没啥好说的。 就是正常返回。

# 将返回值 放入 x0 
E0 1F 00 B9                   STR             W0, [SP,#0x1C]
# 通过 printf 打印下返回值
E1 1F 40 B9                   LDR             W1, [SP,#0x1C]
C0 FF FF 90 00 EC 27 91       ADRL            X0, unk_753EDC69FB
76 79 00 94                   BL              printf

E0 1F 40 B9                   LDR             W0, [SP,#0x1C]
# 还原 x29 x30 寄存器
FD 7B 45 A9                   LDP             X29, X30, [SP,#0x50]
# 还原堆栈
FF 83 01 91                   ADD             SP, SP, #0x60 ; '`'
# 返回 x0
C0 03 5F D6                   RET

总结

基于 dobby 对于 function inline hook 所做的事情简单来说就 2个 步骤

  1. 创建 orig_sum 的内存 储存 sum 前12个 字节 并携带 BR 跳回到后12个字节的地方

  2. 修改 sum 的前 12 个字节 跳到 fake_sum 中

免费评分

参与人数 3吾爱币 +4 热心值 +3 收起 理由
Anonymous、 + 2 + 1 我很赞同!
1MajorTom1 + 1 热心回复!
debug_cat + 2 + 1 用心讨论,共获提升,支持支持

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

debug_cat 发表于 2023-12-11 16:35
这个就是套娃了,通过跳转指令,把入口转移到新函数中,新函数执行原来函数,执行完lr保存了最最开始的位置继续执行。
最近才有时间去细看跳转和返回,不然真的看不懂文章
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-27 11:52

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表