一、知识回顾
在之前一篇文章中,已经介绍了Android中如何修改内存指令改变方法执行逻辑,当时那篇文章的大致流程很简单,在程序运行起来,dex文件被加载到内存中之后,通过读取maps文件,获取dex文件的内存其实地址,然后通过文件头信息找到指定dex在内存中的数据结构,这里还需要详细了解Dex文件的格式,不了解的同学可以看这篇文章:Android中Dex文件格式解析,然后使用系统函数修改内存读写属性,在通过指定方法名找到该方法在内存的指令地址,然后替换即可。我们可以简单看一下dex文件被映射到内存之后的地址:
二、免root进行native层hook
上面的这种方案有一点不好就是,需要熟悉dex文件格式,然后通过方法名通过地址转化获取其内存对应的指令,操作有点繁琐,而本文将介绍一种简便的方式,修改起来非常简单。就是通过hook系统函数来做到这一点。而这种hook功能是免root的,所以只能hook应用内部逻辑。对其他应用程序没有任何效果,不过这个就已经满足本文操作的需求了,关于hook系统函数网上已经有现成的框架:https://github.com/ele7enxxh/Android-Inline-Hook,这个框架用法也非常简单。自己下载之后导入工程即可。下面来看看它的具体用法:
新建一个NDK工程,这个不多多说了,然后把这几个框架中的文件拷贝到jni目录下,hook代码主要在InlineHook.cpp中:
这里看到我们会用到两个函数进行hook:
第一个是注册函数:registerInlineHook
参数:1、原始函数地址,2、hook的新函数地址,3、原始函数的二级指针
第二个是hook函数:inlineHook
参数:1、原始函数地址
这里为了演示效果,我们先Hook系统函数puts,我们需要在hook之前定义新函数以及旧函数的函数指针类型,这里一定要注意,新函数定义类型要和原始函数保持一致。不然hook失败的:
接下来,我们需要出发这个hook操作,我们可以在java层定义一个native方法,然后加载出发即可:
这里定义一个native方法了,然后用ja