YAHFA--ART环境下的Hook框架(代码详解)
来源:互联网 发布:51单片机指令集 编辑:程序博客网 时间:2024/06/06 01:17
上文转载YAHFA作者的原文熟悉了YAHFA的原理,但是由于比较笼统,所以本文针对代码细节,从流程上更加简明的介绍一下YAHFA的做了什么和怎么起效。
开篇前我们区分下方法的命名,防止文中被绕晕:
originMethod:文中指将要hook的方法,即target。
hookMethod:我们自定义的方法,用来替换originMethod,当调用originMethod时,执行我们的hookMethod。
backupMethod:用来备份originMethod的方法,这样一来hookMethod可以通过调用backupMethod来简介调用了originMethod。
一、YAHFA的主要代码实现
3.originMethod的entry_point_from_quick_compiled_code_指向一段汇编指令,汇编指令负责从originMethod的entry_point_from_quick_compiled_code_跳转到hookMethod的entry_point_from_quick_compiled_code_,
本部分只讲做了什么改变,下部分再讲为什么这么做。
1.把originMethod备份到backupMethod
void *dexCacheResolvedMethods = (void *)readAddr((void *)((char *)backupMethod+OFFSET_dex_cache_resolved_methods_in_ArtMethod));int methodIndex = read32((void *)((char *)backupMethod+OFFSET_dex_method_index_in_ArtMethod)); //first update the cached method manuallymemcpy((char *)dexCacheResolvedMethods+OFFSET_array_in_PointerArray+pointer_size*methodIndex, (&backupMethod), pointer_size); //then replace the placeholder with original methodmemcpy((void *)((char *)backupMethod+OFFSET_ArtMehod_in_Object), (void *)((char *)originMethod+OFFSET_ArtMehod_in_Object), ArtMethodSize-OFFSET_ArtMehod_in_Object);
首先要保证backupMethod
方法已经解析完成。在备份之前,手工更新dex_cache_resolved_methods_
数组对应项,确保hookMethod在调用backupMethod
时无需再进行方法解析。什么意思呢,就是如果backupMethod还没有装载到dex_cache_resolved_methods_,此时即使我们用backupMethod替换掉了originMethod,到时候调用backupMethod的时候,还会重新装载backupMethod,所以我们修改过的backupMethod会被覆盖掉而丢失备份的originMethod,因此需要先装载backupMethod,然后再进行覆盖。
2.originMethod的entry_point_from_jni_指向hookMethod的首地址
//save the hook method at entry_point_from_jni_ memcpy((char *)originMethod+OFFSET_entry_point_from_jni_in_ArtMethod, &hookMethod, pointer_size);
这段代码直接通过originMethod的首地址偏移,找到entry_point_from_jni_的内存地址,然后把hookMethod的首地址赋给了entry_point_from_jni_所在内存上。为什么这样做在接下来第二部分讲。
3.originMethod的entry_point_from_quick_compiled_code_指向一段汇编指令
汇编指令的定义在entrypoints_x86.S文件中:
BEGIN_ENTRY hook_new_entry_21 mov 32(%eax), %eax push 40(%eax) retEND_ENTRY hook_new_entry_21
然后在HookMain.c中被引用,定义了一个hook_new_entry,指向这段汇编指令: case 21: LOGI("init to SDK %d", sdkVersion); OFFSET_dex_cache_resolved_methods_in_ArtMethod = 12; OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod = 40; OFFSET_entry_point_from_jni_in_ArtMethod = 32; OFFSET_entry_point_from_interpreter_in_ArtMethod = 24; OFFSET_dex_method_index_in_ArtMethod = 64; OFFSET_array_in_PointerArray = 12; OFFSET_ArtMehod_in_Object = 8; pointer_size = sizeof(void *); ArtMethodSize = 72; hook_new_entry = (void *)hook_new_entry_21; break;
接着在HookMain.c中用这段汇编指令地址替换掉originMethod的entry_point_from_quick_compiled_code_: //update the entrypoints memcpy((char *)originMethod+OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod, &hook_new_entry, pointer_size);
这样一来,originMethod被调用的时候,就会执行这段汇编指令。二、YAHFA的工作原理
例如,我们有如下Java代码:
Log.e("tag", "msg");
编译为dalvik字节码,对应如下:
invoke-static {v0, v1}, Landroid/util/Log;.e:(Ljava/lang/String;Ljava/lang/String;)I // method@0000
而经过dex2oat,将其编译为机器码,则得到如下内容:
mov 0x10(%esp),%ecx ; 设置第1个参数mov 0x14(%esp),%edx ; 设置第2个参数mov (%esp),%eax ; 栈顶保存了当前方法ArtMethod结构体的地址mov 0x4(%eax),%eax ; 获取当前方法的dex_cache_resolved_methods_(偏移为4)mov 0xc(%eax),%eax ; 获取dex_cache_resolved_methods_中的第一项,即method index为0的方法Log.e,call *0x24(%eax) ; 调用Log.e的entry_point_from_quick_compiled_code_(偏移为36)
BEGIN_ENTRY hook_new_entry_21 mov 32(%eax), %eax push 40(%eax) ret END_ENTRY hook_new_entry_21
- YAHFA--ART环境下的Hook框架(代码详解)
- YAHFA--ART环境下的Hook框架
- NDIS Hook的框架代码
- NDIS Hook的框架代码
- 【转帖】 NDIS Hook的框架代码
- 真正的.NET环境下的全局键盘鼠标Hook代码
- windows下基于tensorflow框架的neural art论文实现
- 全能HOOK框架 JNI NATIVE JAVA ART DALVIK
- ART模式下基于Xposed Hook开发脱壳工具
- Android平台下hook框架adbi的研究(下)
- Android平台下hook框架adbi的研究(下)
- 改造 Cydia Substrate 框架用于函数内代码的HOOK
- Android Hook框架Xposed详解
- Android Hook 框架 Cydia_substrate 详解
- android ART hook
- android ART hook
- SSDT HOOK的框架
- Android平台下hook框架adbi的研究(上)
- 如何添加或删除ubuntu用户和组
- Android端恶意锁屏勒索应用分析
- CENTOS 6下ANDROID SDK碰到提示”LIBC.SO.6: VERSION `GLIBC_2.14′ NOT FOUND”的解决方法
- android7.0打开相册报FileUriExposedException异常
- Android自定义控件三部曲
- YAHFA--ART环境下的Hook框架(代码详解)
- XBlog博客系统1.0版
- android JSON解析:官方&GSON方式
- 如何用命令行的方式将项目的文件打成jar包
- pycurl-7.43.0安装时遇到的错误
- Github网页版完成版本控制使用说明
- Uiautomator的日常使用笔记
- 极乐小程序榜单(第一期)
- .NET事务、分布式事务