首页 > android > 破解教程 > 如何为xposed添加native hook
2016
07-13

如何为xposed添加native hook

前言

目前一直在用这个方法,一直没有时间发出来。
目前比较流行的android hook框架 有xposed 和cydia substrate这两个框架各有各得优点。下面总结下
xposed优点:

  • 容易上手

  • 版本一直在维护,兼容性相对cydia比较好

xposed缺点:

  • 最大的遗憾不支持natvie函数hook

  • 其他的缺点都不是问题

cydia优点:

  • 支持native函数hook

cydia缺点:

  • 基本上不更新了,目前还是android4.4

二者之间各有优缺点,如果二者之间可以结合对于我们来说还是很方便的。

正文

如何结合二者?实现java层和native层同时hook?(使用ide:vs2015)
用到cydia的两个动态库libsubstrate.so和libsubstrate-dvm.so
同时和linux下有两个函数dlopendlsym具体用法可以参看百科。
下面定义一个c++头文件substrate.h

#ifndef SUBSTRATE_H
#define SUBSTRATE_H
#include <fcntl.h>
#include <dlfcn.h>
/*定义一些类型和hook相关函数的指针*/
typedef const void *MSImageRef;
/*MSGetImageByName 函数指针*/
extern MSImageRef(*MSGetImageByName)(const char *file);
/*查找符号函数指针*/
extern void *(*MSFindSymbol)(MSImageRef image, const char *name);
/*hook java 函数指针*/
extern void(*MSJavaHookMethod)(JNIEnv *jni, jclass _class, jmethodID methodID, void *function, void **result);
/*hook 函数指针*/
extern void(*MSHookFunction)(void *symbol, void *replace, void **result);
/*hook classload 函数指针*/
extern void(*MSJavaHookClassLoad)(JNIEnv *jni, const char *name, void(*callback)(JNIEnv *, jclass, void *), void *data);
#endif

和对应的cpp文件substrate.cpp

#include "pch.h"
#include "substrate.h"
void *(*MSFindSymbol)(MSImageRef image, const char *name);
MSImageRef(*MSGetImageByName)(const char *file);
void(*MSJavaHookMethod)(JNIEnv *jni, jclass _class, jmethodID methodID, void *function, void **result);
void(*MSHookFunction)(void *symbol, void *replace, void **result);
void(*MSJavaHookClassLoad)(JNIEnv *jni, const char *name, void(*callback)(JNIEnv *, jclass, void *), void *data);
__attribute__((__constructor__)) static void _MSInitialize()
{
	void* handlesubdsub = dlopen("/system/lib/libsubstrate.so", RTLD_NOW);
	void* handlesubdvm = dlopen("/system/lib/libsubstrate-dvm.so", RTLD_NOW);
	if (handlesubdsub != NULL)
	{
		LOGD("***start dlsym methond***");
		MSGetImageByName = (MSImageRef(*)(const char *file))dlsym(handlesubdsub, "MSGetImageByName");
		MSFindSymbol = (void*(*)(MSImageRef image, const char *name))dlsym(handlesubdsub, "MSFindSymbol");
		MSHookFunction = (void(*)(void *symbol, void *replace, void **result))dlsym(handlesubdsub, "MSHookFunction");
		MSJavaHookClassLoad = (void(*)(JNIEnv *jni, const char *name, void(*callback)(JNIEnv *, jclass, void *), void *data))dlsym(handlesubdvm, "MSJavaHookClassLoad");
		MSJavaHookMethod = (void(*)(JNIEnv *jni, jclass _class, jmethodID methodID, void *function, void **result)) dlsym(handlesubdvm, "MSJavaHookMethod");
		LOGD("***end dlsym methond***");
	}
	else
	{
		LOGE("***open so file fail or can't find file!***");
	}

}

在substrate.cpp中可以看到

	void* handlesubdsub = dlopen("/system/lib/libsubstrate.so", RTLD_NOW);
	void* handlesubdvm = dlopen("/system/lib/libsubstrate-dvm.so", RTLD_NOW);

打开/system/lib/下两个动态库文件并拿到指针(在这之前要将cydia的两个动态库文件复制到system/lib文件夹下或者自己定义的路径下),然后通过dlsym函数拿到各个函数的指针,拿到函数的指针后就可以直接调用函数了。

例子:(使用前提要熟悉xposed和cydia)

c++部分代码。

MSImageRef libdvm = MSGetImageByName("/system/lib/libdvm.so");
	if (libdvm != NULL)
	{
 
		JNINativeMethod * dvm_dalvik_system_DexFile = (JNINativeMethod*)dlsym((void*)libdvm, "dvm_dalvik_system_DexFile");
		int i = 0;
		while (dvm_dalvik_system_DexFile[i].name != NULL)
		{
			if (!strcmp("defineClassNative", dvm_dalvik_system_DexFile[i].name) && (!strcmp("(Ljava/lang/String;Ljava/lang/ClassLoader;I)Ljava/lang/Class;", dvm_dalvik_system_DexFile[i].signature)))
			{
				MSHookFunction((void*)dvm_dalvik_system_DexFile[i].fnPtr, (void*)&new_Dalvik_dalvik_system_DexFile_openDexFile, (void**)&Dalvik_dalvik_system_DexFile_openDexFile);
			}
			i++;
		}
		dvmFindClass = (ClassObject*(*)(const char* descriptor, Object* loader))dlsym((void*)libdvm, "_Z12dvmFindClassPKcP6Object");
		dvmDotToDescriptor = (char*(*)(const char* str))dlsym((void*)libdvm, "_Z18dvmDotToDescriptorPKc");
		dvmCreateCstrFromString = (char*(*)(const StringObject* jstr))dlsym((void*)libdvm, "_Z23dvmCreateCstrFromStringPK12StringObject");
		dvmCreateInternalThread = (bool(*)(pthread_t*, const char*, InternalThreadStart, void*))dlsym((void*)libdvm, "_Z23dvmCreateInternalThreadPlPKcPFPvS2_ES2_");
	}

java层面需要用到xposed,

public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
        String name = loadPackageParam.packageName;
		if (name.equals("包名")) {
		System.loadLibrary("hooktest");
		}
		}

这样就可以添加native方法hook了,如果看不懂,那我没办法
说白了,就是自己通过dlopen和dlsym函数调用cydia的函数,通过这些函数进行native hook 至于cydia 的 native 和平台无关,对于4.0以上的平台应该是没问题的。

最后编辑:
作者:xiaobai
这个作者貌似有点懒,什么都没有留下。

如何为xposed添加native hook》有 1 条评论

  1. bin 说:

    博主,你的这篇文章非常实用,能分享一下已完成的项目源码吗?麻烦发我邮箱

留下一个回复

你的email不会被公开。