so函数Hook(上)
Xposed插件开发之对so中函数的处理
对so中函数的hook跟对java层函数的hook不同,Xposed无法完成对so层函数的hook。需要使用其它的框架编写so层的hook代码,然后通过xposed进行主动调用的方式来完成hook。
这里我们先以32位为例,使用inlineHook框架 ,不过这个框架只能hook 32位的app
先来创建一个包含有so库的native C++项目,作为目标app
这里
strstr方法
默认返回的是false,如果我们想通过hook让它的返回结果为true,有几个hook点- hook
strstr()
让其在遇到hookso的时候返回的结果为非空 - 修改
testhook()
的参数、或者直接修改返回值
- hook
对libC函数的hook要注意一点,hook时机要在目标函数调用前
hook strstr()
对于native-lib.cpp的加载是通过System.loadLibrary()
来进行加载的
- 就是说当这个函数返回的时候这个文件生成的so文件就已经加载进入到内存里面了,但是此时还没有执行到
stringFromJNI()
,自然也就还没有执行到我们写的方法。 - 那么我们就可以使用Xposed框架首先完成对
System.loadLibrary()
的hook,然后再写一个so文件对目标so进行hook - 在我们hook到
System.loadLibrary()
函数执行,但是目标函数还没有执行到的时候加载我们的so文件对目标so中的函数进行hook
hookSystem.loadLibrary()
,加载so
这个脚本大体上跟之前差不多
public class XposedHookSo implements IXposedHookLoadPackage {
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable{
Log.i("XposedHookSo", loadPackageParam.packageName);
XposedBridge.log("XposedHookSo->app packagename" + loadPackageParam.packageName);
if (loadPackageParam.packageName.equals("com.xiaoeryu.xposedhookso")){
XposedBridge.log("XposedHookSo" + loadPackageParam.packageName);
XposedHelpers.findAndHookMethod("java.lang.Runtime", loadPackageParam.classLoader, "loadLibrary0", ClassLoader.class, String.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
String soname = (String) param.args[1];
XposedBridge.log("beforeHookedMethod Runtime.loadLibrary0(" + soname + "," + param.args[0] + ")");
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
String soname = (String) param.args[1];
XposedBridge.log("afterHookedMethod Runtime.loadLibrary0("+soname+")");
// 在loadLibrary0执行完成后,主动调用我们的so文件
if (soname.contains("native-lib")){
// System.loadLibrary("native-lib");
System.load("/data/data/com.xiaoeryu.xposedhookso/files/hookso.so");
}
}
});
}
}
}
通过xposedhook
loadLibrary0
监测到目标so被加载进内存之后,就主动调用我们的hooksoloadLibrary函数在6.1之后的版本中变为了loadLibrary0,参数顺序也有变化
6.0.1 public static void loadLibrary(String libName) { Runtime.getRuntime().loadLibrary(libName, VMStack.getCallingClassLoader()); } 8.1 public static void loadLibrary(String libname) { Runtime.getRuntime().loadLibrary0(VMStack.getCallingClassLoader(), libname); }
编写so hook插件
将框架的源码下载下来解压,把源码拷贝到cpp项目的cpp目录下方便调用
修改CMakeLists.txt文件,把要使用的文件添加进去
接下来我们需要编写so层的hook代码
可以按照框架给的示例来稍微修改一下就可以了
- 这里先创建一个指针来保存原来的函数,然后再创建一个指针来保存替换的函数,可以在替换函数中调用原函数的指针
创建一个新的native C++项目在native-lib.cpp中写入hookstrstr方法
的代码
写完之后调试一下看看是否能拿到目标函数地址
- 可以看到成功的拿到了so的地址和目标函数的地址
运行让它跑起来
结果显示成功的hook了
strstr
然后编译成apk
解压apk,拿出里面编译好的so文件
将刚刚写好的目标app安装在设备上
此时,我们对它进行hook之前它的运行结果
将编译好的libhookso.so文件pull到Xposed主动加载的目录下
- 修改libhookso.so文件的名字为hookso.so
- 修改后将其pull到此设备的这个目录下
- 然后使用命令
chmod 777 hookso.so
给予文件执行权限
然后安装Xposed插件,重启设备运行目标app
运行后如果hook成功就会改变我们目标app中so文件的执行结果
总结:对32位低版本安卓进行so hook还是比较简单的,直接写Xposed加载我们使用inlineHook框架编写的so文件去hook目标app中的so函数就可以了
- 标题: so函数Hook(上)
- 作者: xiaoeryu
- 创建于 : 2023-12-25 00:37:44
- 更新于 : 2024-01-13 20:56:27
- 链接: https://github.com/xiaoeryu/2023/12/25/so函数Hook(上)/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。