首页 > 其他分享 >通过主动调用脱函数抽取类壳

通过主动调用脱函数抽取类壳

时间:2022-10-29 15:44:44浏览次数:51  
标签:类壳 抽取 Java 函数 dump 调用 var 加载

被动调用

以自实现的抽取壳为例,对Test01.proc1函数进行抽空,但这次不同的是此Test01类在apk加载的过程中并不会被加载。通过之前被动调用的方式dump dex发现此函数还是被抽空的状态。

总结:单单通过在LoadMethod调用后进行dump dex是一种被动调用的脱壳手段。因为APK在执行过程中只有加载此类时才会调用LoadMethod,然后壳进行抽取函数的回填,在调用LoadMethod函数后我们进行dump dex就可以得到回填后的dex文件。但是如果此类需要在执行过程中还没有加载此类的话就不会调用LoadMethod,壳也就暂时不会对抽取的函数进行回填,这样我们dump的dex中此函数就还是被抽空的状态。

主动调用的优点

由于只有一个类在被加载的时候才会调用LoadMethod进行函数的加载,这样壳代码才会对抽取的函数进行回填,我们的dump代码才有执行的时机。所以就可以通过遍历加载apk的所有类来实现主动调用,从而让我们的dump代码得到执行时机。这里使用寒冰大佬的frida_fart中的脚本,其是通过枚举所有的classloader并获取每一个classloader加载的dex文件,以及每一个dex文件中的类信息。这样得到类名后就可以利用classloader对其进行主动加载。

function dealwithClassLoader(classloaderobj) {
    if (Java.available) {
        Java.perform(function () {
            try {
                var dexfileclass = Java.use("dalvik.system.DexFile");
                var BaseDexClassLoaderclass = Java.use("dalvik.system.BaseDexClassLoader");
                var DexPathListclass = Java.use("dalvik.system.DexPathList");
                var Elementclass = Java.use("dalvik.system.DexPathList$Element");
                var basedexclassloaderobj = Java.cast(classloaderobj, BaseDexClassLoaderclass);
                var tmpobj = basedexclassloaderobj.pathList.value;
                var pathlistobj = Java.cast(tmpobj, DexPathListclass);
                var dexElementsobj = pathlistobj.dexElements.value;
                if (dexElementsobj != null) {
                    for (var i in dexElementsobj) {
                        var obj = dexElementsobj[i];
                        var elementobj = Java.cast(obj, Elementclass);
                        tmpobj = elementobj.dexFile.value;
                        var dexfileobj = Java.cast(tmpobj, dexfileclass);
                        const enumeratorClassNames = dexfileobj.entries();
                        while (enumeratorClassNames.hasMoreElements()) {
                            var className = enumeratorClassNames.nextElement().toString();
                            if(-1 != className.indexOf("com.reverccqin")){
                                console.log("start loadclass->", className);
                                var loadclass = classloaderobj.loadClass(className);
                                console.log("after loadclass->", loadclass);
                            }
                        }
                    }
                }
            } catch (e) {
                console.log(e)
            }

        });
    }

}

通过执行此脚本可以发现被抽空的Test01.proc1函数对应的Test01类已经被主动加载了。

然后再次查看dump文件就可以发现Test01.proc1函数已经被成功回填。

标签:类壳,抽取,Java,函数,dump,调用,var,加载
From: https://www.cnblogs.com/revercc/p/16838859.html

相关文章