刘新明1989 2024-03-14 08:49 采纳率: 44.4%
浏览 4
已结题

请问这个javascript的值来自哪里?

img


var classesNames = new Array()
var OkhttpClientClassName = ""
var CertificatePinnerClassName = ""
var prefix = ""

function initConsole(){
    var Color = {RESET: "\x1b[39;49;00m", Black: "0;01", Blue: "4;01", Cyan: "6;01", Gray: "7;11", "Green": "2;01", Purple: "5;01", Yellow: "3;01",  Red: "1;01"}
    var LightColor = {RESET: "\x1b[39;49;00m", Black: "0;11", Blue: "4;11", Cyan: "6;11", Gray: "7;01", "Green": "2;11", Purple: "5;11", Red: "1;11", Yellow: "3;11"}
    var colorPrefix = '\x1b[3'
    var colorSuffix = 'm'
    Object.keys(Color).forEach(function(c){
        if (c  == "RESET") 
            return
        console[c] = function(message){
            console.log(colorPrefix + Color[c] + colorSuffix + message + Color.RESET)
        }
        console["Light" + c] = function(message){
            console.log(colorPrefix + LightColor[c] + colorSuffix + message + Color.RESET)
        }
    })
}

function loadOkhttpClient(){
    Java.perform(function (){
        try{
            Java.use("okhttp3.OkHttpClient")
        }catch(e){
            //console.error(e)
        }
    })
    
}

function loadClasses(){
    Java.perform(function (){
        Java.enumerateLoadedClasses({
            onMatch: function(clsName, handle){
                classesNames.push(clsName)
            },
            onComplete: function(){
                console.Green("Search Class Completed!")
            }
        })
    })
}

function findOkhttpClass(){
    Java.perform(function (){
        var Modifier = Java.use("java.lang.reflect.Modifier")
        function isOkhttpClient(clsName){
            if(clsName.split('.').length != 2){
                return false;
            }
            
            try{
                var cls = Java.use(clsName)
                var interfaces = cls.class.getInterfaces()
                const count = interfaces.length
                if(count < 2){
                    return false
                }
                var flag = false
                for(var i = 0; i < count; i++){
                    var interface_ = interfaces[i]
                    var interface_name = interface_.getName()
                    
                    if(interface_name.indexOf("Cloneable") > 0){
                        flag = true
                    }else{
                        if(interface_name.indexOf("$") <= 0){
                            return false
                        }
                    }
                }
                if(!flag) return false;
                
                if(cls.class.getDeclaredClasses().length < 1){
                    return false
                }

                if(cls.class.getSuperclass().getName() != 'java.lang.Object'){
                    return false
                }
                
            }catch(e){
                return false
            }
            return true;
        }


        

        function isCertificatePinner(clsName,prefix){
            
            if(!clsName.startsWith(prefix)){
                return false
            }

            if(clsName.indexOf("$") > 0){
                return false
            }
            
            if(clsName.split('.').length != 2){
                return false;
            }

            var cls = Java.use(clsName)
            if(cls.class.isInterface()){
                return false
            }

            
            if(cls.class.getInterfaces().length > 0){
                return false
            }

         
            if(cls.class.getDeclaredClasses().length < 1){
                return false
            }
            
            if(cls.class.getSuperclass().getName() != "java.lang.Object"){
                return false
            }

            if(!Modifier.isFinal(cls.class.getModifiers())){
                return false
            }
            var flag = false
            var methods = cls.class.getDeclaredMethods()
            for(var i = 0; i < methods.length; i++){
                var method = methods[i]
                if(method.getParameterCount() < 1){
                    continue
                }
                if(method.getParameterTypes()[0].getName() == "java.security.cert.Certificate"){
                    flag = true
                    break
                }
            }
            if(!flag) return false

            flag = false
            var fields = cls.class.getDeclaredFields()
            for(var k = 0; k < fields.length; k++){
                var field = fields[k];
                if(field.getType().getName() == "java.util.Set"){
                    flag = true
                    break
                }
            }
            if(!flag) return false
            return true
        }
    
        for(var i = 0; i < classesNames.length; i++){
            if(isOkhttpClient(classesNames[i])){
                OkhttpClientClassName = classesNames[i]
                var prefix = classesNames[i].split('.')[0]+'.'
            }
        }
        
        for(var i = 0; i < classesNames.length; i++){
            if(isCertificatePinner(classesNames[i],prefix)){
                CertificatePinnerClassName = classesNames[i]
           }
        }

        var printOut
        if(OkhttpClientClassName == "" || CertificatePinnerClassName == "" || prefix == ""){
            printOut = console.Red
            printOut("Can't find the okhttp class")
        }else{
            printOut = console.Green
        }
        printOut("Found Class: "+classesNames.length)
        printOut("Okhttp's package prefix: "+prefix)
        printOut("Found the OkhttpClient: "+OkhttpClientClassName)
        printOut("Found the OkhttpCertificatePinner: "+CertificatePinnerClassName)
    })
}

function hook(){
    Java.perform(function (){
        var Modifier = Java.use("java.lang.reflect.Modifier")
        //TrustAllManager
        var TrustAllManagerClass = Java.registerClass({
            name: "TrustAllManager",
            implements:[Java.use("javax.net.ssl.X509TrustManager")],
            methods: {
                checkClientTrusted(chain, authType) {
                    console.Cyan("checkClientTrusted Called!!")
                },
                checkServerTrusted(chain, authType) {
                    console.Cyan("checkServerTrusted Called!!")
                },
                getAcceptedIssuers() {
                  return [];
                },
              }
        })
        var trustAllManagerHandle = TrustAllManagerClass.$new()

        var sslContext = Java.use("javax.net.ssl.SSLContext").getInstance("TLS")
        sslContext.init(null,Java.array("Ljavax.net.ssl.X509TrustManager;",[trustAllManagerHandle]),null)
        var sslSocketFactory = sslContext.getSocketFactory()

        //HostnameVerify
        var MyHostnameVerify = Java.registerClass({
            name: "MyHostnameVerify",
            implements:[Java.use("javax.net.ssl.HostnameVerifier")],
            methods: {
                verify(hostname, session){
                    console.log(hostname)
                    return true
                }
            }
        })
        var myHostnameVerifyHandle = MyHostnameVerify.$new()

        var internalOkhttpClientClasses = Java.use(OkhttpClientClassName).class.getDeclaredClasses()
        internalOkhttpClientClasses.forEach(function (internalClass) {
            var methods = internalClass.getDeclaredMethods()
            methods.forEach(function(method) {
                 if(method.getParameterCount() < 1){
                    return
                }
                var firstParameterTypeName = method.getParameterTypes()[0].getName()

                if(firstParameterTypeName == "javax.net.ssl.SSLSocketFactory"){
                    var Builder = Java.use(internalClass.getName())
                    var sslSocketFacotryMethodName  = method.getName()
                    Builder[sslSocketFacotryMethodName].overloads.forEach(function(overload){
                        overload.implementation = function(SSLSocketFactory){
                            arguments[0] = sslSocketFactory
                            return this[sslSocketFacotryMethodName].apply(this,arguments)
                        }
                        console.Blue(sslSocketFacotryMethodName+"  Hooked!")
                    });
                    
                }
                if(firstParameterTypeName == "javax.net.ssl.HostnameVerifier"){
                    var Builder = Java.use(internalClass.getName())
                    var hostnameVerifierMethodName = method.getName()
                    Builder[hostnameVerifierMethodName].overloads.forEach(function(overload){
                        overload.implementation = function(hostnameVerifier){
                            arguments[0] = myHostnameVerifyHandle
                            return this[hostnameVerifierMethodName].apply(this,arguments)
                        }
                        console.Yellow(hostnameVerifierMethodName+"  Hooked!")
                    });
                }

                if(firstParameterTypeName == CertificatePinnerClassName){
                    var Builder = Java.use(internalClass.getName())
                    var certificatePinnerMethodName = method.getName()

                    Builder[certificatePinnerMethodName].overloads.forEach(function(overload){
                        overload.implementation = function(certificatePinner){
                            return Java.retain(this)
                        }
                        console.Purple(certificatePinnerMethodName+"  Hooked!")
                    });
                   
                }
            })
        });
        
        var CertificatePinnerClass = Java.use(CertificatePinnerClassName)
        var methods = CertificatePinnerClass.class.getDeclaredMethods()
        methods.forEach(function (method){
            if(method.getReturnType().getName() == 'void'){
                var methodName = method.getName()
                console.Cyan(methodName+" Hooked!")
                CertificatePinnerClass[methodName].overloads.forEach(function (overload){
                    if(overload.returnType.name == 'V'){
                        overload.implementation = function(){
                            console.Cyan("certificatePinner check called!")
                        }   
                    }
                })
            }
        })
    })
}

function main(){
    initConsole()
    loadOkhttpClient()
    loadClasses()
    findOkhttpClass()
    hook()
}
setImmediate(main)
  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-03-14 08:49
    关注

    引自免费微信小程序:皆我百晓生

    在你提供的JavaScript代码中,值的来源主要是在不同的函数和条件判断中动态计算得出的。具体来说:

    1. clsName 是在函数 isOkhttpClient(clsName)isCertificatePinner(clsName, prefix) 中作为参数传入的,它的值来自于对 classesNames 数组的遍历。classesNames 数组中的元素是通过调用 Java.enumerateLoadedClasses 函数获取到的所有已加载的Java类名。

    2. interfaces 变量的值来自于 var cls = Java.use(clsName) 之后的 cls.class.getInterfaces() 调用,它获取了指定类(由 clsName 参数决定)所实现的所有接口列表。

    3. count 变量是根据上述 interfaces 的长度来赋值的,即当前类实现了多少个接口。

    4. flag 变量用来标识是否满足特定条件,在循环中根据接口名称判断后进行赋值。

    5. OkhttpClientClassNameCertificatePinnerClassName 这两个变量在 findOkhttpClass 函数中被赋值,它们分别对应找到的符合条件的 OkHttpClient 类名和 CertificatePinner 类名。

    6. hook 函数中,如 sslContextsslSocketFactorymyHostnameVerifyHandle 等变量的值均来自一系列Java方法的调用及对象实例化操作。

    简而言之,这些值来源于对Java类、方法以及数组元素的操作和判断,并非来自预设的静态值或外部输入。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 3月22日
  • 已采纳回答 3月14日
  • 创建了问题 3月14日