全能HOOK框架 JNI NATIVE JAVA ART DALVIK
OneHook
目前比较流行的几个安卓HOOK方案,都有功能上的欠缺,有的不支持art模式,有的不支持jni层,有的不支持侵入HOOK。
所以OneHook诞生了!
这是一个同时支持ART和Dalvik两种模式,理论上支持安卓4.0.3以上所有版本,同时支持JAVA和NATIVE层,使用全局注入技术的侵入式HOOK框架。
本框架不需要额外的安装,可以静态编译到自己的APP中。
首先感谢看雪论坛中很多大牛提供的技术资料,没有你们的分享,就没有目前的这个OneHook的诞生。
感谢ele7enxxh提供的Android Inline Hook模块
项目地址:https://github.com/ele7enxxh/Android-Inline-Hook
项目博客: http://ele7enxxh.com/Android-Arm-Inline-Hook.html
讨论帖: http://bbs.pediy.com/thread-205741.htm
感谢asLody提供的Legend模块
项目地址:https://github.com/aslody/legend
还感谢其他贡献知识的同学们。
功能实现:
0x01
首先考虑如何进入系统,如何在合适的位置和时间启动我的模块。之前做WIN32的时候就有人说过,如果在WINDOWS启动前前运行我的代码,那么我无所不能。理论上,这句话是成立的。
所以在安卓系统,我也需要找一个相对足够早的位置来启动我的模块,这个位置我没有选择init进程,而是libc.so。
为什么?
因为安卓的底层是LINUX构建的,LINUX的底层就是C语言,而libc.so就是C语言的具体实现库,在这个位置上插入代码显然是合适的。而且在libc.so中去执行我们的代码,就不需要去考虑如何注入模块,因为安卓的所有进程都会主动加载libc.so。这是一个一举两得的方案,首先解决了启动代码,其次解决了注入问题。
原理/过程:
so文件的初始化工作 是在init_array段中定义的
.init_array段的起始位置为:0X000683C0
初始化时 会按照顺序去执行初始化函数
_ZL14....
_ZL30....
_ZL29....
_ZL31....
那么如果把_ZL14__libc_preinitv的指针重定向到一个物理地址,使之dlopen我们自己的so,就可以实现我们想要的功能。
修改init_array的段的第一个指针 _ZL14__libc_preinitv ---> 0x55D24
指向位置的机器码
机器码对应的C语言代码
1
2
3
4
5
|
int _fun()
{
dlopen(( const char *) "libckis.so" , 0);
return __libc_preinit();
}
|
这样就可以顺利的在每个进程中加载libckis.so文件
关于如何修改libc.so文件使之加载自定义库文件的方法 可以参考我的另外一篇文章
http://bbs.pediy.com/thread-213043.htm
需要注意的是
1 在不同安卓版本中,libc.so是不一样的。
2 自定义的代码位置不一定必须在.text段中,在很多情况下.text段没有足够的空间让你去插入代码,我的解决方案是把这段代码放在.rodata段,如果放在rodata段,在运算地址偏移时,需要+0x10000
3 libc.so修改后需要妥善的push到手机的/system/lib目录下,要注意权限问题,否则手机会死机
0x02
现在我们已经进入了安卓的Native层,在这里,我们可以做很多事情,比如HOOK fopen来控制底层文件的访问 也可以HOOK __system_property_get来修改ro属性 等等....
文档可以参考 https://github.com/ele7enxxh/Android-Inline-Hook
附一个简单的例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#include <stdio.h>
#include <stdint.h>
#include <dlfcn.h>
#include "inlineHook.h"
void my_init( void ) __attribute__((constructor));
typedef int (*t_system_property_get)( const char *name, char *value);
t_system_property_get __system_property_get=NULL;
int (*old__system_property_get)( const char *name, char *value)=NULL;
int new__system_property_get( const char *name, char *value)
{
if ( strstr (name, "ro.serialno" )) return strlen ( strcpy (value, "AABBCC" ));
else return old__system_property_get(name,value);
}
int my_init( void )
{
void * libc=dlopen( "/system/lib/libc.so" ,0);
__system_property_get=(t_system_property_get)dlsym(libc, "__system_property_get" );
if (registerInlineHook((uint32_t)__system_property_get,(uint32_t) new__system_property_get,(uint32_t **) &old__system_property_get)!= ELE7EN_OK) printf ( "error find __system_property_get " );
else if (inlineHook((uint32_t) __system_property_get) != ELE7EN_OK) printf ( "error hook __system_property_get " );
return 0;
}
|
那么,我们现在已经可以完整的实现Native/JNI层的HOOK了。
在adb shell下 输入getprop ro.serialno 会得到返回值 AABBCC 如图:
并且我们已经完成了了进入JAVA层的先决条件。
0x03
进入JAVA世界
论坛中如何从native层进入java层有很多种方案吗,在这里 我使用了ADBI的解决方案,在libc.so库中的epoll_wait函数挂钩,进而跳转到APP进程中去,然后使用DexClassLoader加载自己的dex文件,达到JAVA HOOK的目的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
bool IsInToJava= false ;
int (*oldepoll_wait)( int epfd, int events, int maxevents, int timeout)=NULL;
int newepoll_wait( int epfd, int events, int maxevents, int timeout)
{
if (!IsInToJava)
{
IsInToJava= true ;
invoke_dex_method( "/data/local/tmp/xxx.dex" ,path, "com.xxx.xxx.inject" , "main" ,AppName);
return oldepoll_wait(epfd,events,maxevents,timeout);
}
}
void my_init( void )
{
void * libc = dlopen( "/system/lib/libc.so" , 0);
void *hookepoll_wait = dlsym(libc, "epoll_wait" );
if (registerInlineHook((uint32_t)hookepoll_wait, (uint32_t)newepoll_wait, (uint32_t **)&oldepoll_wait) != ELE7EN_OK) printf ( "error find epoll_wait\n" );
else if (inlineHook((uint32_t)hookepoll_wait) != ELE7EN_OK) printf ( "error hook epoll_wait " );
}
|
在APP进程调用epoll_wait函数时 就会加载指定的dex文件,并且执行HOOK的初始化方法。
注意epoll_wait可能会被多次调用,我们只需要执行一次即可。
0x04
JAVA层HOOK
JAVA层的HOOK我使用了Legend的方案,因为已经进入了APP进程内,就和热补丁的流程是一样的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public class inject{
public static final String TAG = "CKIS_INJECT" ;
public static Context context;
public static void main(String packageName)
{
Log.e(TAG, "Dex Inject in by: " +packageName);
HookManager.getDefault().applyHooks(inject. class );
Log.e(TAG, "DEX called success:" +packageName);
}
@Hook ( "android.telephony.TelephonyManager::getDeviceId" )
public static String TelephonyManager_getDeviceId(TelephonyManager thiz)
{
return "123456789012345" ;
}
}
|
在这里 我们HOOK了TelephonyManager.getDeviceId方法,实现了系统的IMEI的修改。
在执行IMEI获取操作时 调用getDeviceID会获得123456789012345
具体HOOK方案 也可以参考我另外一篇基于XPOSED框架的文章
http://bbs.pediy.com/thread-213042.htm
0x05
环境部署
本框架需要ROOT权限
1 首先读取/system/lib/libs.so 并在本地解析elf文件格式 添加加载自定义库的代码 然后再回写到/system/lib/libc.so目录下
2 释放DEXPOSED的运行库 libdexposed.so libdexposed_l.so libdexposed_l51.so 到\system\lib\或\vendor\lib目录下
3 释放libckis.so、libjava.so到/system/lib目录下
4 释放DEX文件到指定的目录下 本例为 /data/local/tmp/xxx.dex
5 重启生效
目前该框架的完成度已经接近90%,支持ART、DALVIK,支持JAVA、JNI/NATIVE
理论上此方案支持安卓4.0.3以上所有版本 但是Legend的HOOK模块支持
- Dalvik & Android 4.2
- Dalvik & Android 4.3
- Art & Android 5.0
- Art & Android 5.0.1
- Art & Android 5.1
- Art & Android 6.0
- Art & Android 6.0.1
目前已测试的版本有
4.0.3
4.4.2
4.4.4
5.0
5.1
欢迎有兴趣的朋友一起交流
QQ:586593 迟到 by 2017 05 13
原文地址:http://bbs.pediy.com/thread-217587.htm
全能HOOK框架 JNI NATIVE JAVA ART DALVIK相关推荐
- 全能Android HOOK框架 JNI NATIVE JAVA ART DALVIK
OneHook 目前比较流行的几个安卓HOOK方案,都有功能上的欠缺,有的不支持art模式,有的不支持jni层,有的不支持侵入HOOK. 所以OneHook诞生了! 这是一个同时支持ART和Dalvi ...
- Jni native java.lang.UnsatisfiedLinkError:No implementation found for boolean com.xxx.xxx.jni.init()
项目中使用到so库,编译apk出来安装运行正常,但是直接run运行报错,提示找不到native方法的实现,确认了几次没发现有什么问题,so包确实存在 在log中看到一个关键信息 运行报错时是在找64位 ...
- Android平台dalvik模式下java Hook框架ddi的分析(1)
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/75710411 一.前 言 在前面的博客中已经学习了作者crmulliner编写的, ...
- java上传ddi_Android平台dalvik模式下java Hook框架ddi的分析(2)--dex文件的注入和调用...
前面的博客<Android平台dalvik模式下java Hook框架 ddi 的分析(1)>中,已经分析了dalvik模式下 ddi 框架Hook java方法的原理和流程,这里来学习一 ...
- Android平台dalvik模式下java Hook框架ddi的分析(2)--dex文件的注入和调用
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/77942585 前面的博客<Android平台dalvik模式下java Ho ...
- Android平台下Dalvik层hook框架ddi的研究
通过adbi,可以对native层的所有代码进行hook.但对于Android系统来说,这还远远不够,因为很多应用都还是在Dalvik虚拟机中运行的. 那么,有没有什么办法可以对Dalvik虚拟机中跑 ...
- 安卓逆向_24( 一 ) --- Hook 框架 frida( Hook Java层 和 so层) )
From:Hook 神器家族的 Frida 工具使用详解:https://blog.csdn.net/FlyPigYe/article/details/90258758 详解 Hook 框架 frid ...
- 【转】JNI(Java Native Interface)的简介
因为刚刚接触android和java平台,对JNI到底是什么,还不是很了解,所以从CSDN转载了一篇文章,以便自己对JNI有一个认识,也跟大家分享一下. JNI是Java Native Interfa ...
- Android JNI(Java Native Interface)技术介绍
Android平台上的JNI技术介绍 JUL 15TH, 2013 | COMMENTS NDK简介 Android是由Google领导开发的操作系统,Android依靠其开放性,迅速普及,成为目前最 ...
最新文章
- RandomForest随机森林总结
- 平方剩余(二次剩余)
- 打CALL APP 项目进展 总体计划
- [转载] Java反射是什么?看这篇绝对会了!
- Asp.net MVC4 与 Web Form 并存
- 形态学操作之提取水平与垂直直线
- 仿微信图片上传,带加号,且超过最大数隐藏
- adc 测试软件,ADC芯片参数测试技术解析
- Android MVP架构手绘图
- JUCE 中的音频编解码
- Redundant Paths
- axios 的responseType 类型动态设置
- 中外文献图书网址汇总
- [转]我的IT学习生活(搜藏)
- Mac 更新系统后无法正常启动
- 苹果手机经常开低电量模式,对电池会有影响吗?
- 华硕笔记本r414u怎么安装键盘_华硕r414uv7200笔记本安装win7系统操作教程
- 拐点检测常用算法总结
- python怎么调用另一个py文件的变量,Python中py文件引用另一个py文件变量的方法
- 如何为成品主机检验制定抽样检索表
热门文章
- 各种Camera,总有一款适合你(二)
- 求指定范围内的所有素数C++代码实现
- Python学习笔记:Day 6 配置文件
- Python学习笔记:错误,测试,调试(转)
- mount and fstab的使用(整理)
- 用pytorch加载训练模型
- C++ string清空并释放内存空间的两种方法(shrink_to_fit()、swap())
- 【编程】为什么不能直接对链表头head进行操作?
- [云炬创业管理笔记]第九章为创业成败而准备测试2
- 科大星云诗社动态20201223