热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用CydiaSubstrateHookAndroidJNINativeInterface.md

HookJNINativeInterfacehttp:bbs.pediy.comshowthread.php?t200398,很早就有大大给出方法了.记得看雪已经有人发过一份源码:

Hook JNINativeInterface

http://bbs.pediy.com/showthread.php?t=200398, 很早就有大大给出方法了.
记得看雪已经有人发过一份源码:用来hook jni 用来打印日志的,http://bbs.pediy.com/showthread.php?t=209914.,使用的是ELF-ARM-HOOK-Library库,
由于个人原因经常使用模拟器测试app,目前比较好用的模拟器都是基于x86的,上面两位提供的都是基于arm的.
Cydia Substrate支持arm和x86 hook
参考上面两位的方法,和dvm源码
JNINativeInterface 具体实现方法,如GetMethodID

static jmethodID GetMethodID(JNIEnv* env, jclass jclazz, const char* name, const char* sig) { ScopedJniThreadState ts(env){ .... }

编译过后没有导出函数.无法通过dlsym拿到函数地址.想要hook这个函数就要拿到这个函数的地址.
查看jni.h 函数头.
JNIEnv结构:

typedef _JNIEnv JNIEnv;

_JNIEnv结构:

struct _JNIEnv { /* do not rename this; it does not seem to be entirely opaque */ const struct JNINativeInterface* functions; #if defined(__cplusplus) jint GetVersion() { return functions->GetVersion(this); } ....

JNINativeInterface结构:

struct JNINativeInterface { void* reserved0; void* reserved1; void* reserved2; void* reserved3; jint (*GetVersion)(JNIEnv *); jclass (*DefineClass)(JNIEnv*, const char*, jobject, const jbyte*, jsize); jclass (*FindClass)(JNIEnv*, const char*); ....

可以看到JNINativeInterfac结构全是函数的指针:拿到这个结构体中函数的指针,就拿到具体函数的指针.
这些结构体中的方法初始化实现,可以参考:JNIEnv*dvmCreateJNIEnv(Thread* self);

实现

关键部分代码:hook RegisterNatives方法

void Jnimethod::startHookJni(JNIEnv * env) { #if defined(__i386__) MSHookFunction((void*)*(unsigned int*)((*(unsigned int*)env) + 0x35C), (void*)&myRegisterNatives, (void**)&oldRegisterNatives); return; #else ....

其中关键部分:

(void*)*(unsigned int*)((*(unsigned int*)env) + 0x35C)

解析:*(unsigned int*)env+ 0x35C 先取JNINativeInterface结构体的地址,0x35C为RegisterNatives在结构体中的偏移.即拿到:

jint (*RegisterNatives)(JNIEnv*, jclass, const JNINativeMethod*, jint);

这个函数指针

*(unsigned int*)((*(unsigned int*)env) + 0x35C)//拿到RegisterNatives函数的地址

拿到函数指针即可实现hook.

示例:

jint(*oldRegisterNatives)(JNIEnv* env, jclass c, const JNINativeMethod* m, jint n); jint myRegisterNatives(JNIEnv* env, jclass c, const JNINativeMethod* m, jint n) { const char*clazzName = getClassName(env, c); __android_log_print(ANDROID_LOG_INFO, "RegisterNatives", "start! jclass[%s] methods[0x%x]%d ", clazzName, (unsigned int)m, n); for (int i = 0; i

总结

以前,打印jni日志总是在手机上打印.现在可以在模拟器上打印了,也可以丢掉:ELF-ARM-HOOK-Library,这个库了(主要是cydia之处arm和x86,个人比较喜欢cydia).

测试

《使用Cydia Substrate Hook Android JNINativeInterface.md》

转:https://www.cnblogs.com/xiaobaiyey/p/5865246.html


推荐阅读
author-avatar
欢姨oi
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有