关于多classloader的hook和一点分享
本文最后更新于 2024年7月31日 上午
问题提出
群里有朋友问“我枚举出那个类了,但是用java.use的时候就报错找不到,这是这个app做保护了吗”。很早的时候我用frida也遇到过同样的问题。
问题现象
当我使用enumerateClassLoaders时,在onMatch里可以找到我想找的类,但是我在外部直接Java.use时则报错找不到指定类。
原因及解决
该APP本身有多个classloader,我想Java.use的类并不在frida的默认的classFactory.loader的classloader里面,这个时候怎么办呢,一个办法就是我们把默认的classloader改为我们能找到指定类的classloader,改法如下。

这样通过枚举找到所有classloader,再挨个找到这个类,找到的时候将这个classloader改为默认的classloader就好了。那为什么这么改呢?我们就得看看源码啦。
深入研究
在firda-java的源码文件lib/class-factory.js#L143可以找到Java.use的方法原型。

其中loader的初始化来自firda-java的源码文件/index.js#L549

那我们现在知道了,如果默认的getClassloader()不包含我们想要的类,我们就需要修改factory.loader切换classloader就可以指定classloader进行Java.use了。如果你想理清楚这部分逻辑,可以从index.js的perform函数开始看就很容易梳理清楚了。
frida能这么枚举出所有classloader,那在java层具体体现在哪里呢?
举例说明
我们以阿里系的APP为例,全局搜索classloader之后,定位到这两行代码。

这里就是多个classloader生成的地方了(类: com.alibaba.wireless.security.framework.d),他通过加载特定dex到新的classloader,自己实现了相关的管理。我们如果想调用该loader下相关类的方法(如x-signature等)就需要hook了上述第一个函数将返回结果作为loadClass的对象,就可以找到具体的类和方法了。
感兴趣的可以自己实现一下~
可以参考下述代码:

以上。