首页
论坛
课程
招聘
[原创]StormHook:Android侵入式Hook框架
2017-8-30 16:45 10484

[原创]StormHook:Android侵入式Hook框架

2017-8-30 16:45
10484
 

https://github.com/woxihuannisja/StormHook

StormHook:Android侵入式Java Hook框架

  • 支持Android Art和Dalvik
  • 支持Andorid 4.0-6.0
  • 支持注入到其他进程Hook
  • 支持public,static,private方法
  • 支持调用原始的Java方法

模块

  • StormHookSample:用来测试Hook效果的例子
  • InjectSo:用来注入到StormHookSample进程的so文件
  • HookCore: 加载到StormHookSample进程的dex

用法

Step1:
编译InjectSo模块 生成libhook.so

adb push libhook.so /data/local/tmp/

Step2:HookCore模块是Android Studio工程,将生成的Apk中的classes.dex提取出来重命名为hook.dex

adb push hook.dex /data/local/tmp/

Step3:
HookCore/Native是jni工程 编译生成libdalvikhook_native.solibarthook_native.so

adb push libdalvikhook_native.so /data/local/tmp/
adb push libarthook_native.so /data/local/tmp/

Step4:
关闭selinux

root@hammerhead:/ # setenforce 0
root@hammerhead:/ # getenforce
Permissive

Step5:
注入libhook.so到StormHookSample App中

root@hammerhead:/data/local/tmp # ps |grep storm
u0_a71    17772 182   923264 41632 ffffffff 400ca73c S com.example.stormhookdemo

root@hammerhead:/data/local/tmp # ./inject /data/local/tmp/libhook.so 17772
target_pid:456c,soPath:/data/local/tmp/libhook.so
library path = /data/local/tmp/libhook.so

hook成功显示的log

adb logcat -s "storm"
V/storm   (17772): g_JavaVM:414cef00
V/storm   (17772): LoadDex optFile path:/data/data/com.example.stormhookdemo/hoo
k.dat
V/storm   (17772): classLoaders size:1
V/storm   (17772): original Element size:1
V/storm   (17772): ClassMethodHook[Can't find class:com/storm/hook/main in bootc
lassloader
V/storm   (17772): loadClass com/storm/hook/main successful clazz:0x1d600059
D/storm   (17772): Inject dex entry is called
D/storm   (17772): After addNativeLibraryDirectory pathLoader is:dalvik.system.P
athClassLoader[DexPathList[[zip file "/data/app/com.example.stormhookdemo-1.apk"
, dex file "dalvik.system.DexFile@425e31c0"],nativeLibraryDirectories=[/data/loc
al/tmp, /data/app-lib/com.example.stormhookdemo-1, /vendor/lib, /system/lib]]]
D/storm   (17772): [+]find original method (getMacAddress_hook)
D/storm   (17772): [+]find original method (test_public_hook)
D/storm   (17772): [+]find original method (currentTimeMillis)
D/storm   (17772): [+]find original method (test_private)
D/storm   (17772): [+]find original method (test_privatestatic)
D/storm   (17772): Inject dex hook success
I/storm   (17772): *-*-*-*-*-*-*- End -*-*-*-*-*-*-*-*-*-*

测试button事件的log输出

adb logcat -s "storm","hook"
D/hook    (19001): getMacAddress is hooked :)
D/storm   (19001): Wifi mac :c4:43:8f:f7:d1:03
D/hook    (19001): test_public is hooked
D/storm   (19001): test_public is called
D/hook    (19001): test_private is hooked
D/storm   (19001): test_private is called
D/storm   (19001): test_private return:10
D/hook    (19001): currentTimeMillis is much better in seconds :)
D/storm   (19001): small Currentime:5885303
D/hook    (19001): test_private is hooked
D/storm   (19001): test_private is called
D/storm   (19001): test_private return:10
D/hook    (19001): test_privatestatic is hooked
D/storm   (19001): test_privatestatic is called

原理

1.如何进入目标进程的native世界

通过注入InjectSo模块中的libhook.so到目标进程,就进入了目标的native世界

2.如何进入目标进程的java世界

使用LoadDex函数加载外部Dex,并执行指定的入口类,对Java函数进行hook操作,这样就进入到目标进程的Java世界

3.如何获取全局的JavaVm

在JNI开发当中,JavaVM参数可以通过JNI_OnLoad参数获取,但是对于我们注入的so ,我们无法通过这种方式获取JavaVm,但是Android提供了另外一种方法可以获取到全局的JavaVm

android::AndroidRuntime::getJavaVM();

4.加载外部Dex

使用反射的方法调用"dalvik/system/DexFile"类中的loadDex来动态加载Dex,获取一个dex对象

jclass DexFile=jenv->FindClass("dalvik/system/DexFile");
if(ClearException(jenv))
{
    ALOG("storm","find DexFile class failed");
    return 0;
}
jmethodID loadDex=jenv->GetStaticMethodID(DexFile,"loadDex","(Ljava/lang/String;Ljava/lang/String;I)Ldalvik/system/DexFile;");

5.获取主dex所对应的PathClassLoader

6.根据MultiDex原理将主Dex和外部加载的Dex合并

7.找到外部Dex的入口类

这里我提供了2种方法:

 

方法一:使用PathClassLoader.loadClass(className);
主Dex对应的是pathClassLoader
由于我们将外部Dex和当前Dex进行MultiDex操作,那么这2个Dex的类都可以通过pathClassLoader来找到外部dex目标类

jstring className=jenv->NewStringUTF(name);
jclass clazzCL = jenv->GetObjectClass(g_classLoader);
jmethodID loadClass = jenv->GetMethodID(clazzCL,"loadClass","(Ljava/lang/String;)Ljava/lang/Class;");
jclass tClazz = (jclass)jenv->CallObjectMethod(g_classLoader,loadClass,className);

方法二:dexFile.loadClass(className);
通过LoadDex加载外部Dex之后,会得到一个dex对象dexObj,也可以使用dexObj.loadClass来找到外部dex目标类

jclass DexFile=jenv->FindClass("dalvik/system/DexFile");
jmethodID loadClass=jenv->GetMethodID(DexFile,"loadClass","(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/Class;");
if(ClearException(jenv))
{
    ALOG("storm","find loadClass methodId failed");
    return 0;
}
//important dexObject.loadClass()
jstring className=jenv->NewStringUTF(name);
jclass tClazz = (jclass)jenv->CallObjectMethod(dexObject,loadClass,className,g_classLoader);

8.执行外部Dex入口类进行Java Hook操作

Dalvik Hook

采用的方法类似AndFix,将origin method对应的DalvikMethod结构替换为replace method的DalvikMethod结构

Art Hook

采用的是mar-v-hook的Art Hook方案

参考


第五届安全开发者峰会(SDC 2021)10月23日上海召开!限时2.5折门票(含自助午餐1份)

收藏
点赞0
打赏
分享
打赏 + 201.00
打赏次数 2 金额 + 201.00
 
赞赏  chinahanwu   +200.00 2017/12/29
赞赏  cvcvxk   +1.00 2017/09/22
最新回复 (26)
雪    币: 563
活跃值: 活跃值 (249)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
Rprop 活跃值 2017-8-30 17:44
2
0
对于Android  N,  自己从文件读取就好,  https://github.com/avs333/Nougat_dlfunctions
雪    币: 37
活跃值: 活跃值 (18)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
nabla 活跃值 2017-8-30 17:53
3
0
学习了

顺便打个广告,art模式做Java方法hook可以用YAHFA,其具有以下优点:
1.  hook方法与原方法无需保持一致签名
2.  原方法是反射调用的,也可以被hook住
3.  支持Android  N
雪    币: 563
活跃值: 活跃值 (249)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
Rprop 活跃值 2017-8-30 18:03
4
0
nabla 学习了 顺便打个广告[em_19],art模式做Java方法hook可以用YAHFA,其具有以下优点: 1. hook方法与原方法无需保持一致签名 2. 原方法是反射调用的,也可以被hook ...
不过YAHFA的方案似乎和mar-v-in的ArtHook是一致的?
雪    币: 37
活跃值: 活跃值 (18)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
nabla 活跃值 2017-8-31 08:57
5
0
rrrfff [em_27]不过YAHFA的方案似乎和mar-v-in的ArtHook是一致的?
噢噢,这个还真不清楚,ArtHook还一直没来得及去看。。
雪    币: 85
活跃值: 活跃值 (1078)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
龙飞雪 活跃值 2017-8-31 17:07
6
0
顶,谢谢楼主的分享
雪    币: 4
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
myeanngg 活跃值 2017-9-3 13:29
7
0
YAHFA不错,  要是加入

<span>Dalvik  hook就好了</span>
雪    币: 4
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
myeanngg 活跃值 2017-9-3 13:32
8
0
nabla 噢噢,这个还真不清楚,ArtHook还一直没来得及去看。。
雪    币: 75
活跃值: 活跃值 (55)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
liuganchao 活跃值 2017-9-12 17:09
9
0
代码呢,大虾,再发一次呗。
雪    币: 181
活跃值: 活跃值 (634)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
寒号鸟二代 活跃值 3 2017-9-15 17:02
10
0
liuganchao 代码呢,大虾,再发一次呗。
https://github.com/woxihuannisja/StormHook
在github上把使用方法更新了一下
雪    币: 75
活跃值: 活跃值 (55)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
liuganchao 活跃值 2017-9-18 10:22
11
0
寒号鸟二代 https://github.com/woxihuannisja/StormHook 在github上把使用方法更新了一下
3Q
雪    币: 75
活跃值: 活跃值 (55)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
liuganchao 活跃值 2017-9-22 16:48
12
0
call  loadDex  method  failed    仁兄  这是什么原因?android  5.1
雪    币: 8670
活跃值: 活跃值 (770)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
cvcvxk 活跃值 10 2017-9-22 16:55
13
0
送上1块..
收藏了
雪    币: 181
活跃值: 活跃值 (634)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
寒号鸟二代 活跃值 3 2017-9-22 17:23
14
0
cvcvxk 送上1块.. 收藏了
谢谢老V
雪    币: 75
活跃值: 活跃值 (55)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
liuganchao 活跃值 2017-9-22 17:26
15
0
寒号鸟二代 谢谢老V[em_13]
怎么会加载失败?  android  5.1.1
雪    币: 181
活跃值: 活跃值 (634)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
寒号鸟二代 活跃值 3 2017-9-22 17:28
16
0
liuganchao 怎么会加载失败? android 5.1.1
看下路径或者权限的问题
雪    币: 75
活跃值: 活跃值 (55)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
liuganchao 活跃值 2017-9-22 18:04
17
0
寒号鸟二代 看下路径或者权限的问题
没有问题呀,我把你清理异常的代码去掉,抛出这个:  JNI  FindClass  called  with  pending  exception  'java.lang.StackOverflowError'  thrown  in  long  android.os.SystemClock.uptimeMillis():-2
雪    币: 200
活跃值: 活跃值 (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
最强的男人 活跃值 2017-9-23 03:31
18
0
能给个联系方式吗。
雪    币: 75
活跃值: 活跃值 (55)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
liuganchao 活跃值 2017-9-25 15:35
19
0
能给个联系方式吗。
雪    币: 181
活跃值: 活跃值 (634)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
寒号鸟二代 活跃值 3 2017-9-25 16:14
20
0
qq:1483943306
雪    币: 75
活跃值: 活跃值 (55)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
liuganchao 活跃值 2017-9-25 16:31
21
0
Can't  find  original  method  (getMacAddress_hook)java.lang.NoSuchMethodException
雪    币: 75
活跃值: 活跃值 (55)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
liuganchao 活跃值 2017-9-26 17:44
22
0
完美测试通过,谢谢二鸟哥。
雪    币: 3496
活跃值: 活跃值 (509)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
smartdon 活跃值 1 2017-10-8 17:00
23
0
谢谢楼主
雪    币: 3
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
小菜鸟de 活跃值 2017-10-17 22:35
24
0
多谢,试下
雪    币: 133
活跃值: 活跃值 (306)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
koflfy 活跃值 1 2017-12-16 15:35
25
0
mark
游客
登录 | 注册 方可回帖
返回