Cydia Substrate框架Android so hook分析

最近需要用到Android so hook,于是分析了一下比较流行的Cydia Substrate框架

CydiaSubstrate框架的核心函数是MSHOOKFunction,官方使用说明如下:

现在Android 默认编译出来的都是thumb指令集的,就分析一下这个模式下的HOOK吧。

在使用MSHOOKFunction HOOK前,先用IDA attach到进程先看下准备HOOK的函数,前面18个字节的二进制指令如下:

52ABF480 30 B5       PUSH            {R4,R5,LR}

52ABF482 8D B0       SUB             SP, SP, #0x34

52ABF484 05 1E       SUBS            R5, R0, #0

52ABF486 10 D1       BNE             loc_52ABF4AA

52ABF488 0C 1E       SUBS            R4, R1, #0

52ABF48A 28 D0       BEQ             loc_52ABF4DE

52ABF48C 15 49       LDR             R1, =(aSign - 0x52ABF496)

52ABF48E 02 23       MOVS            R3, #2

52ABF490 5B 42       NEGS            R3, R3

HOOK后的指令如下:

52ABF480 78 47       BX              PC

52ABF480             ;---------------------------------------------------------------------------

52ABF482 C0          DCB 0xC0 ;

52ABF483 46          DCB 0x46 ; F

52ABF484             ; ---------------------------------------------------------------------------

52ABF484             CODE32

52ABF484

52ABF484             loc_52ABF484                            ; CODE XREF:_F14700dj

52ABF484 04 F0 1F E5 LDR             PC, =(sub_58F7C000+1)

52ABF484             ; ---------------------------------------------------------------------------

52ABF488 01 C0 F7 58 off_52ABF488 DCDsub_58F7C000+1         ; DATA XREF:_F14700d:loc_52ABF484r

52ABF488             ; End of function _F14700d

52ABF488

52ABF48C             ; ---------------------------------------------------------------------------

52ABF48C             ; START OF FUNCTION CHUNK FORsub_58F7D000

52ABF48C             CODE16

52ABF48C

52ABF48C             loc_52ABF48C       ;CODE XREF: sub_58F7D000:loc_58F7D010j

52ABF48C                                                 ; DATA XREF: sub_58F7D000:loc_58F7D010o ...

52ABF48C 15 49       LDR             R1, =(aSign - 0x52ABF496)

52ABF48E 02 23       MOVS            R3, #2

52ABF490 5B 42       NEGS            R3, R3

HOOK前后对比,发现函数的前面12个字节的指令被替换了,这12个字节指令就是实现了一个跳转功能,跳转到过滤函数sub_58F7C000。仔细看一下,还是觉得有点奇怪的地方,LDR     PC,=(sub_58F7C000+1)这个指令比较明显就是跳转的功能,那为前面的BX PC只是为了跳转到这条指令,为什么要这样用?而不是直接使用LDR     PC,=(sub_58F7C000+1)进行跳转呢,BX PC是不是多此一举呢?

后来经过手动patch测试后发现,这条指令不可缺少的,因为LDR     PC,=(sub_58F7C000+1)指令是arm指令集的,而我们的原始函数使用的是thumb指令集,直接在函数开头放上arm指令集的指令,CPU不会把它识别为arm指令,仍然把它做为thumb指令,这样就会执行出错了。这里的BX PC可进行指令集切换,这样就可以正常执行了。

另外这里的LDR     PC,=(sub_58F7C000+1)指令使用sub_58F7C000+1做为跳转地址,而不是sub_58F7C000,也是因为指令集的原因,尾巴上带1的指令告诉CPU,sub_58F7C000函数是thumb指令集的,不带1的话,就被认为是arm指令集了

MSHookFunction会返回一个old地址,old地址指向的函数,需要实现原函数相同的功能,但是这里的前面12个字节已经被覆盖掉了,是不是old可以直接执行原来的12个字节后跳转回0x52ABF48C就可以了呢?

我们直接来看下old指向的地址(在IDA里转成CODE的时候有的时候会失败,是因为它默认把指令当成arm指令集来识别,按Alt+G,value设为1改成thumb模式再转就可以)

debug141:58F7D000 30 B5       PUSH            {R4,R5,LR}

debug141:58F7D002 8D B0       SUB             SP, SP, #0x34

debug141:58F7D004 05 1E       SUBS            R5, R0, #0

debug141:58F7D006 0D D1       BNE             sub_58F7D024

debug141:58F7D008 0C 1E       SUBS            R4, R1, #0

debug141:58F7D00A 05 D0       BEQ             sub_58F7D018

debug141:58F7D00C 78 47       BX              PC

debug141:58F7D00C             ;---------------------------------------------------------------------------

debug141:58F7D00E C0          DCB 0xC0 ;

debug141:58F7D00F 46          DCB 0x46 ; F

debug141:58F7D010             ;---------------------------------------------------------------------------

debug141:58F7D010             CODE32

debug141:58F7D010

debug141:58F7D010             loc_58F7D010                            ; CODE XREF:sub_58F7D000+Cj

debug141:58F7D010 04 F0 1F E5 LDR             PC, =(loc_52ABF48C+1)

debug141:58F7D010             ; End of function sub_58F7D000

debug141:58F7D010

debug141:58F7D010             ;---------------------------------------------------------------------------

debug141:58F7D014 8D F4 AB 52 off_58F7D014 DCDloc_52ABF48C+1         ; DATA XREF:sub_58F7D000:loc_58F7D010r

debug141:58F7D018             CODE16

debug141:58F7D018

debug141:58F7D018             ; =============== S U B R O U T IN E =======================================

debug141:58F7D018

debug141:58F7D018             ; Attributes: thunk

debug141:58F7D018

debug141:58F7D018             sub_58F7D018                            ; CODE XREF: sub_58F7D000+Aj

debug141:58F7D018 78 47       BX              PC

debug141:58F7D018             ;---------------------------------------------------------------------------

debug141:58F7D01A C0          DCB 0xC0 ;

debug141:58F7D01B 46          DCB 0x46 ; F

debug141:58F7D01C             ;---------------------------------------------------------------------------

debug141:58F7D01C             CODE32

debug141:58F7D01C

debug141:58F7D01C             loc_58F7D01C                            ; CODE XREF:sub_58F7D018j

debug141:58F7D01C 04 F0 1F E5 LDR             PC, =(loc_52ABF4DE+1)

debug141:58F7D01C             ;---------------------------------------------------------------------------

debug141:58F7D020 DF F4 AB 52 off_58F7D020 DCD loc_52ABF4DE+1         ; DATA XREF:sub_58F7D018:loc_58F7D01Cr

debug141:58F7D020             ; End of function sub_58F7D018

debug141:58F7D020

debug141:58F7D024             CODE16

debug141:58F7D024

debug141:58F7D024             ; =============== S U B R O U T IN E =======================================

debug141:58F7D024

debug141:58F7D024             ; Attributes: thunk

debug141:58F7D024

debug141:58F7D024             sub_58F7D024                            ; CODE XREF:sub_58F7D000+6j

debug141:58F7D024 78 47       BX              PC

debug141:58F7D024             ;---------------------------------------------------------------------------

debug141:58F7D026 C0          DCB 0xC0 ;

debug141:58F7D027 46          DCB 0x46 ; F

debug141:58F7D028             ; ---------------------------------------------------------------------------

debug141:58F7D028             CODE32

debug141:58F7D028

debug141:58F7D028             loc_58F7D028                            ; CODE XREF:sub_58F7D024j

debug141:58F7D028 04 F0 1F E5 LDR             PC, =(sub_52ABF4AA+1)

debug141:58F7D028             ;---------------------------------------------------------------------------

debug141:58F7D02C AB F4 AB 52 off_58F7D02C DCDsub_52ABF4AA+1         ; DATA XREF:sub_58F7D024:loc_58F7D028r

debug141:58F7D02C             ; End of function sub_58F7D024

这段内存是新分配的内存,整个指令比原来长很多,除了后面增加了很多指令,第4条指令和第6条指令也跟原来不一样了。

分析可知,第4和第6条指令都为条件短跳指令,这里要从0x58F7D006跳到0x52ABF4AA仅通过一个字节的偏移已经跳不回去了,所以需要把这里的短跳转换为长跳,这里先跳转到0x58F7D024近处的指令,再使用远跳指令跳到0x52ABF4AA除了跳转指令,BL,BLX这样的CALL指令,还有涉及到PC值的指令,也需要经过类似的转换才行。如果前面12个字节不需要转换的话,直接使用原来的12字节指令就可以了。

总结:

Cydia Substrate框架的

优点:

相比调用不停重写函数前面一些指令的框架,更为稳定,支持多线程并发运行。old函数处理较好,基本上需要替换的指令都能比较好的支持

缺点:

arm代码编译后比较紧凑,函数之间不留有空隙,thumb指令集在不影响其它寄存器的条件下,12个字节的跳转指令长度已经到达极限,太短的函数是无法做inline hook的。

即使长度够的话,也并不是完美的,举个会发生异常的例子:如果12个字节之后的指令有往最前面12字节内回跳的话,这样就会挂掉

时间: 2024-08-28 10:13:10

Cydia Substrate框架Android so hook分析的相关文章

改造 Cydia Substrate 框架用于函数内代码的HOOK

上一次分析了Cydia Substrate so hook 框架的实现,实际使用中,发现这样的框架并不能满足我的一些需求,比如我要知道一个函数内部某处代码的运行时的寄存器值,用原始的框架就无法做到. 想实现的功能是只要指定一个地址,就可以打印该处代码执行时的寄存器环境.HOOK的地址以及线程的TID,同时支持多个地址的添加. 先实现一个通用的消息打印函数  void printAllReg(int Reg_R0,int Reg_R1,int Reg_R2,int Reg_R3,int Stack

使用Cydia Substrate实现Android Hook

使用Cydia Substrate来实现Android hook,文章来自于官方提供的教程. 1.安装Cydia Substrate框架apk,手机必须root. 2.代码编写: 在manifest文件中声明如下: <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" andr

利用Cydia Substrate进行Android HOOK

Cydia Substrate是一个代码修改平台.它可以修改任何主进程的代码,不管是用Java还是C/C++(native代码)编写的.而Xposed只支持HOOK app_process中的java函数,因此Cydia Substrate是一款强大而实用的HOOK工具. 官网地址:http://www.cydiasubstrate.com/ Demo地址:https://github.com/zencodex/cydia-android-hook 官方教程:http://www.cydiasu

Android上玩玩Hook:Cydia Substrate实战

作者简介:周圣韬,百度高级Android开发工程师,博客地址:http://blog.csdn.net/yzzst 了解Hook 还没有接触过Hook技术读者一定会对Hook一词感觉到特别的陌生,Hook英文翻译过来就是“钩子”的意思,那我们在什么时候使用这个“钩子”呢? 我们知道,在Android操作系统中系统维护着自己的一套事件分发机制.应用程序,包括应用触发事件和后台逻辑处理,也是根据事件流程一步步的向下执行.而“钩子”的意思,就是在事件传送到终点前截获并监控事件的传输,像个钩子勾上事件一

Android Hook工具Cydia Substrate使用

Hook简介: Hook就是钩子,在安卓中,就是在事件传送到终点前截获并监控事件的传输,像个钩子勾上事件一样,并且能够在勾上事件时,处理一些自己特定的事件. Cydia Substrate的官网定义:The powerful code modification platform behind Cydia. Cydia Substrate是一个代码修改平台,它可以修改任何主进程的代码,不管是用Java还是C/C++(native代码)编写的. 注:Cydia Substrate框架对于inline

Cydia Substrate based DexDumper&#39;s weakness

得益于Cydia Substrate框架,HOOK Native函数变得简单,也给脱壳带来方便. 像ijiami免费版,360,classes.dex被加密到so文件并运行时释放到内存,因此针对相关函数的HOOK脱壳就比较简单了. 但也有一些容易被针对的缺点: 1.代码可以在类加载时被修改.hook dexFileParse.__mmap2或memcmp 等可能dump出是修复前的dex 2.修改了odex的标志dey\n036,dumper在内存中搜索不到,将漏掉真正的odex 3.packe

(4.2.33)Android上玩玩Hook(1):Cydia Substrate初识

选自: Android上玩玩Hook? 跟着鬼哥学Android java hook (一) 摘要:Hook的出现为开发者希望通过一个程序改变其他程序的某些行为的想法开拓了解决道路,而作为一款基于Hook的代码修改框架,Cydia Substrate可以修改任何主进程的代码,本文作者以广告注入的实战详细介绍了Hook的过程. 了解Hook 还没有接触过Hook技术读者一定会对Hook一词感觉到特别的陌生,Hook英文翻译过来就是"钩子"的意思,那我们在什么时候使用这个"钩子&

使用cydia substrate 来进行android native hook

? cydia不仅可以hook java代码,同样可以hook native代码,下面举一个例子来进行android native hook 我是在网上找到的supermathhook这个项目,在他基础上修改的,本来是为了仓促应对阿里的ctf 这个项目位置: 这个项目是用来hook jni 代码的,而我是用来hook dvmDexFileOpenPartial这个函数的,所以必须使用 Mshookfunction这个函数,这个函数在libsubstrate.so中,自己去官网下载就可以了. 接下

Android HOOK工具Cydia Substrate使用详解

目录(?)[+] Substrate几个重要API介绍 MShookClassLoad MShookMethod 使用方法 短信监控实例 Cydia Substrate是一个代码修改平台.它可以修改任何主进程的代码,不管是用Java还是C/C++(native代码)编写的.而Xposed只支持HOOK app_process中的java函数,因此Cydia Substrate是一款强大而实用的HOOK工具. 官网地址:http://www.cydiasubstrate.com/ Demo地址:h