抖音字节系列app的通用抓包方案

默认分类·编程 · 03-08 · 309 人浏览

Frida脚本

来源github

function patch(address) {
    Memory.protect(address, 4, 'rwx');
    Memory.writeByteArray(address, [0x00, 0x00, 0x80, 0x52]);
}

// function onLoad(name, callback) {
//     var Runtime = Java.use('java.lang.Runtime');
//     var System = Java.use('java.lang.System');
//     var VMStack = Java.use('dalvik.system.VMStack');
//     var VERSION = Java.use('android.os.Build$VERSION');
//     System.loadLibrary.overload('java.lang.String').implementation = function (libName) {
//         if (VERSION.SDK_INT.value >= 29) {
//             Runtime.getRuntime().loadLibrary0(Java.use('sun.reflect.Reflection').getCallerClass(), libName);
//         } else if (VERSION.SDK_INT.value >= 24) {
//             Runtime.getRuntime().loadLibrary0(VMStack.getCallingClassLoader(), libName);
//         } else {
//             Runtime.getRuntime().loadLibrary(libName, VMStack.getCallingClassLoader());
//         }
//         if (libName.includes(name)) {
//             callback();//无法执行到这里
//         }
//     };
// }

//参考: https://www.jianshu.com/p/4291ee42c412
function onLoad(name, callback) {
    //void* android_dlopen_ext(const char* filename, int flag, const android_dlextinfo* extinfo);//原型
    const android_dlopen_ext = Module.findExportByName(null, "android_dlopen_ext");
    if (android_dlopen_ext != null) {
        Interceptor.attach(android_dlopen_ext, {
            onEnter: function (args) {
                if (args[0].readCString().indexOf(name) !== -1) {
                    this.hook = true;
                }
            }, onLeave: function (retval) {
                if (this.hook) {
                    callback();
                }
            }
        });
    }
}

function main() {
    Java.perform(function () {
        //28.4.0
        const soName = 'libsscronet.so';
        //方法1, 内存搜索
        // onLoad(soName, function () {
        //     let libsscronet = Process.getModuleByName(soName);
        //     const verifyCertMatches = Memory.scanSync(libsscronet.base, libsscronet.size, "E0 E3 00 91 C1 14 80 12");
        //     verifyCertMatches.forEach(function (result) {
        //         let verifyCert = result.address.add(0xC);
        //         if (Instruction.parse(verifyCert).toString() === "mov w0, #1") {
        //             // 设置可读可写可执行
        //             Memory.protect(verifyCert, 4, 'rwx');
        //             // 修改为 mov w0, #0
        //             Memory.writeByteArray(verifyCert, [0x00, 0x00, 0x80, 0x52]);
        //         }
        //
        //         let handleVerifyInstruction = Instruction.parse(result.address.add(0x1A4));
        //         if (Instruction.parse(result.address.add(0x1A0)).toString() === "mov x0, x19" && handleVerifyInstruction.mnemonic === "bl") {
        //             let handleVerifyResult = new NativePointer(handleVerifyInstruction.opStr.replace('#', ''));
        //             Interceptor.attach(handleVerifyResult, {
        //                 onLeave: function (retval) {
        //                     if (retval > 0x0) retval.replace(0x0);
        //                 }
        //             });
        //         }
        //     });
        // });

        //方法2, 直接patch
        // onLoad(soName, function () {
        //     let libsscronet = Module.getBaseAddress(soName);
        //     let verifyCert = libsscronet.add(0x3700F0);
        //     let handleVerifyResult1 = libsscronet.add(0x370448);
        //     let handleVerifyResult2 = libsscronet.add(0x370494);
        //     console.log("修改前: " + Instruction.parse(verifyCert), Instruction.parse(handleVerifyResult1), Instruction.parse(handleVerifyResult2));
        //     patch(verifyCert);
        //     patch(handleVerifyResult1);
        //     patch(handleVerifyResult2);
        //     console.log("修改后: " + Instruction.parse(verifyCert), Instruction.parse(handleVerifyResult1), Instruction.parse(handleVerifyResult2));
        // })


        //方法3, hook SSL_CTX_set_custom_verify, 基本通杀
        onLoad(soName, () => {
            // void SSL_CTX_set_custom_verify(SSL_CTX *ctx, int mode, enum ssl_verify_result_t (*callback)(SSL *ssl, uint8_t *out_alert)) {
            //     ctx->verify_mode = mode;
            //     ctx->custom_verify_callback = callback;
            // }//原型
            let SSL_CTX_set_custom_verify = Module.getExportByName(soName, 'SSL_CTX_set_custom_verify');
            if (SSL_CTX_set_custom_verify != null) {
                Interceptor.attach(SSL_CTX_set_custom_verify, {
                    onEnter: function (args) {
                        Interceptor.attach(args[2], {
                            onLeave: function (retval) {
                                // enum ssl_verify_result_t BORINGSSL_ENUM_INT {
                                //     ssl_verify_ok,
                                //     ssl_verify_invalid,
                                //     ssl_verify_retry,
                                // };
                                //全部替换成 ssl_verify_ok
                                if (retval > 0x0) retval.replace(0x0);
                            }
                        });
                    }
                });
            }
        });

        //只需要选择其中一种即可, 推荐使用方法3
    });
}

setImmediate(main);
// setTimeout(main, 3000);
// frida -U -f com.ss.android.ugc.aweme -l Android/byteDance.js
Theme Jasmine by Kent Liao