首页
社区
课程
招聘
[原创]实现frida版的JustTrustMe(二)用frida实现JustTrustMe
发表于: 2021-5-7 10:53 13190

[原创]实现frida版的JustTrustMe(二)用frida实现JustTrustMe

2021-5-7 10:53
13190

有了上一篇JustTrustMe源码解读作铺垫,下面我讲解用frida实现JustTrustMe就很容易了。但是还是有些难点,比如JustTrustMe中有一些自定义的类和方法。那到底如何用frida的方式来实现自定义的类和方法?

自定义类虽然在frida语法中可以用registerClass的方式实现,但是由于类太复杂。我们可以把实现好的java代码打包成dex然后inject到目标进程中再跑hook脚本。

梳理JustTrustMe Main.java中内部类有如下3个:

同学们要对技术要有自己的判断力,虽然frida有registerClass让你用js语法定义一个类这样的功能。但是,这只是frida的附属价值。你看到这样的技术,了解一下就得了。不用学它,浪费精力!frida的openClassFile摆在那里让你可以注入dex,你居然还用registerClass。那你跟放弃用计算器,手动算数有什么区别?有什么本质的提高吗?并没有,还JB浪费时间。别人在进步,你在原地踏步!
IDA和GDB都说自己反汇编,哪个更好你没点B数吗?
Java和C++都说自己是面向对象,面向对象封装性哪个更好你没点B数吗?

除了以上3个类,JustTrustMe还有几个静态方法需要我们实现。可以说上面几个类,最终都是通过这几个方法使用的。比如getSCCM()、getEmptySSLFactory()、getCCM()等
我们还是用Java直接实现,那么这些方法。

关于怎么打包涉及到一些技术细节,暂时不便透露。感兴趣的朋友可以去https://github.com/CreditTone/hooker看我的radar.dex里面有所有打包好的代码。

现在JustTrustMe除hook逻辑之外的所有自定义类和方法我们现在全部搞定了。我们可以正式开始用frida来实现JustTrustMe所有hook点了。

我们还是按上一篇《实现frida版的JustTrustMe(一)JustTrustMe官方源码学习》的源码解读顺序来逐一实现。为了让大家更容易理解,我不贴JustTrustMe的代码了。我贴每个hook点的伪代码,然后跟上frida的实现。这样大家会理解的清晰一点。

上节分析:三个构造方法的目的都是在new DefaultHttpClient之后替换connManager参数。而getSCCM()方法就是返回一个不安全的ClientConnectionManager。

上节分析:X509TrustManagerExtensions原方法会进行一系列的效应证书和服务器是否可信。这里xposed用了XC_MethodReplacement直接替换方法的执行体。

上节分析:原NetworkSecurityTrustManager类的checkPins方法List参数原型是List<X509Certificate>。校验X509Certificate集合是否合法,如果不合法就会抛CertificateException。这里xposed用了XC_MethodReplacement直接替换方法的执行体,并且什么都没做。

上节分析:这个稍微有点复杂,但目的很简单。就是为了替换TrustManager,而TrustManager不可以直接传进来,是内部创建一个sslcontext来包装一个TrustManager[]。所以要new一个自定义的sslcontext然后把ImSureItsLegitTrustManager传进去。sslcontext对象要进行init()所以整个代码看起来比较多。

分析:逻辑过于简单,不解释了

上节分析:强制让isSecure返回true

上节分析: 如果存在com.android.org.conscrypt.TrustManagerImpl这个类的,并且返回的TrustManager[]的长度大于0,并且TrustManager[]第0个是com.android.org.conscrypt.TrustManagerImpl实例,则什么都不操作。否则直接把返回值改成TrustManager[]{new ImSureItsLegitTrustManager()}

上节分析:让setDefaultHostnameVerifier方法失效,让setSSLSocketFactory失效,让setHostnameVerifier失效

上节分析:不用第0和低2个参数,而第1个参数使用TrustManager[]{new ImSureItsLegitTrustManager()}

上节分析:由于xposed基于zygote进程孵化app进程,hook非常早。所以如果它想对应用层的类进行hook的话,必须等Application的attach调用之后才能拿到应用级的ClassLoader。那么在attach之后他又进行了processOkHttp、processHttpClientAndroidLib、processXutils方法的调用,分别对应okhttp库的hook、httpclientandroidlib库的hook、org.xutils.http的hook。这三个是应用喜欢用的三方http库。

上节分析okhttp包名不统一问题:由于okhttp 2.x和3.x包名相差比较大。所以这里第一个hook你可以看到justTrustMe试图去找com.squareup.okhttp.CertificatePinner类,这是为了尽量兼容老安卓项目。

上节分析CertificatePinner.check:无论是okhttp2.x还是3.x、4.x都是有CertificatePinner.check(String str, List<Certificate> list)这个方法的。可以上面第一二个hook做的是XC_MethodReplacement,并且什么都不操作。对比原check方法,我们知道这个目的是为了阻止check抛SSLPeerUnverifiedException异常。

上节分析:第三四个hook OkHostnameVerifier.verify(),校验hostname是否合法最终会调用verify(str, (X509Certificate) sSLSession.getPeerCertificates()[0]);说明还是对远程服务证书进行了校验,这里直接用return true替代了原来的逻辑。

上节分析:一个冷门http库的hook

上节分析:一个冷门http库的hook

到此为止,JustTrustMe所有的hook点除了webviewclient之外全部用frida实现了。我们merge一下。

JustTrustMe的官方源码hook点虽然全部实现,但是由于Android一直在更新和app的混淆不断变强使得我们hook点经常hook不到。那么下一篇我们就来看看如何添加这些新的hook点和对抗混淆frida版本的JustTrustMe

 
 
 
public DefaultHttpClient(final ClientConnectionManager conman, final HttpParams params) {
    super(getCCM(conman, params), params);
}
 
 
public DefaultHttpClient(final HttpParams params) {
    super(getSCCM(), params);
}
 
 
public DefaultHttpClient() {
    super(getSCCM(), null);
}
public DefaultHttpClient(final ClientConnectionManager conman, final HttpParams params) {
    super(getCCM(conman, params), params);
}
 
 
public DefaultHttpClient(final HttpParams params) {
    super(getSCCM(), params);
}
 
 
public DefaultHttpClient() {
    super(getSCCM(), null);
}
Java.perform(function() {
    var Helper = Java.use("gz.justtrustme.Helper");
    var DefaultHttpClientClass = Java.use("org.apache.http.impl.client.DefaultHttpClient");
    //被强奸的构造方法
    var DefaultHttpClientClassRapeConstructor = DefaultHttpClientClass.$init.overload('org.apache.http.conn.ClientConnectionManager', 'org.apache.http.params.HttpParams');
    DefaultHttpClientClassRapeConstructor.implementation = function(v0, v1) {
        //被强奸的构造方法被调用的话,我们替换调ClientConnectionManager参数为我们的
        var returnObj = DefaultHttpClientClassRapeConstructor.call(this, Helper.getCCM(v0, v1), v1);
        console.log("org.apache.http.impl.client.DefaultHttpClient.$init('org.apache.http.conn.ClientConnectionManager', 'org.apache.http.params.HttpParams') was hooked!");
        return returnObj;
    };
    var DefaultHttpClientClassInit_1602 = DefaultHttpClientClass.$init.overload();
    DefaultHttpClientClassInit_1602.implementation = function() {
        //使用DefaultHttpClientClassRapeConstructor强奸它
        var returnObj = DefaultHttpClientClassRapeConstructor.call(this, Helper.getSCCM(), null);
        console.log("org.apache.http.impl.client.DefaultHttpClient.$init() was hooked!");
        return returnObj;
    };
    var DefaultHttpClientClassInit_1603 = DefaultHttpClientClass.$init.overload('org.apache.http.params.HttpParams');
    DefaultHttpClientClassInit_1603.implementation = function(v0) {
        //使用DefaultHttpClientClassRapeConstructor强奸它
        var returnObj = DefaultHttpClientClassRapeConstructor.call(this, Helper.getSCCM(), v0);
        console.log("org.apache.http.impl.client.DefaultHttpClient.$init('org.apache.http.params.HttpParams') was hooked!");
        return returnObj;
    };
    //以上DefaultHttpClient的三个构造方法逻辑全部被我们用frida的方式替换了
}
Java.perform(function() {
    var Helper = Java.use("gz.justtrustme.Helper");
    var DefaultHttpClientClass = Java.use("org.apache.http.impl.client.DefaultHttpClient");
    //被强奸的构造方法
    var DefaultHttpClientClassRapeConstructor = DefaultHttpClientClass.$init.overload('org.apache.http.conn.ClientConnectionManager', 'org.apache.http.params.HttpParams');
    DefaultHttpClientClassRapeConstructor.implementation = function(v0, v1) {
        //被强奸的构造方法被调用的话,我们替换调ClientConnectionManager参数为我们的
        var returnObj = DefaultHttpClientClassRapeConstructor.call(this, Helper.getCCM(v0, v1), v1);
        console.log("org.apache.http.impl.client.DefaultHttpClient.$init('org.apache.http.conn.ClientConnectionManager', 'org.apache.http.params.HttpParams') was hooked!");
        return returnObj;
    };
    var DefaultHttpClientClassInit_1602 = DefaultHttpClientClass.$init.overload();
    DefaultHttpClientClassInit_1602.implementation = function() {
        //使用DefaultHttpClientClassRapeConstructor强奸它
        var returnObj = DefaultHttpClientClassRapeConstructor.call(this, Helper.getSCCM(), null);
        console.log("org.apache.http.impl.client.DefaultHttpClient.$init() was hooked!");
        return returnObj;
    };
    var DefaultHttpClientClassInit_1603 = DefaultHttpClientClass.$init.overload('org.apache.http.params.HttpParams');
    DefaultHttpClientClassInit_1603.implementation = function(v0) {
        //使用DefaultHttpClientClassRapeConstructor强奸它
        var returnObj = DefaultHttpClientClassRapeConstructor.call(this, Helper.getSCCM(), v0);
        console.log("org.apache.http.impl.client.DefaultHttpClient.$init('org.apache.http.params.HttpParams') was hooked!");
        return returnObj;
    };
    //以上DefaultHttpClient的三个构造方法逻辑全部被我们用frida的方式替换了
}
public List<X509Certificate> checkServerTrusted(X509Certificate[] chain, String authType, String host) throws CertificateException {
        return chain;
}
public List<X509Certificate> checkServerTrusted(X509Certificate[] chain, String authType, String host) throws CertificateException {
        return chain;
}
Java.perform(function() {
    var X509TrustManagerExtensionsClass = Java.use('android.net.http.X509TrustManagerExtensions');
    var X509TrustManagerExtensionsClassCheckServerTrusted = X509TrustManagerExtensionsClass.checkServerTrusted.overload('[Ljava.security.cert.X509Certificate;', 'java.lang.String', 'java.lang.String');
    X509TrustManagerExtensionsClassCheckServerTrusted.implementation = function(certsArr, v1, v2) {
        console.log("android.net.http.X509TrustManagerExtensions.checkServerTrusted('[Ljava.security.cert.X509Certificate;', 'java.lang.String', 'java.lang.String') was hooked!");
        return certsArr;
    };
}
Java.perform(function() {
    var X509TrustManagerExtensionsClass = Java.use('android.net.http.X509TrustManagerExtensions');
    var X509TrustManagerExtensionsClassCheckServerTrusted = X509TrustManagerExtensionsClass.checkServerTrusted.overload('[Ljava.security.cert.X509Certificate;', 'java.lang.String', 'java.lang.String');
    X509TrustManagerExtensionsClassCheckServerTrusted.implementation = function(certsArr, v1, v2) {
        console.log("android.net.http.X509TrustManagerExtensions.checkServerTrusted('[Ljava.security.cert.X509Certificate;', 'java.lang.String', 'java.lang.String') was hooked!");
        return certsArr;
    };
}
private void checkPins(List<X509Certificate> chain) throws CertificateException {
    //什么都不做
}
private void checkPins(List<X509Certificate> chain) throws CertificateException {
    //什么都不做
}
Java.perform(function() {
    var NetworkSecurityTrustManagerClass = Java.use('android.security.net.config.NetworkSecurityTrustManager');
    var NetworkSecurityTrustManagerClassCheckPins = NetworkSecurityTrustManagerClass.checkPins.overload('java.util.List');
    NetworkSecurityTrustManagerClassCheckPins.implementation = function(v0) {
        //什么都不做
        console.log("android.security.net.config.NetworkSecurityTrustManager.checkPins('java.util.List') was hooked!");
    };
}
Java.perform(function() {
    var NetworkSecurityTrustManagerClass = Java.use('android.security.net.config.NetworkSecurityTrustManager');
    var NetworkSecurityTrustManagerClassCheckPins = NetworkSecurityTrustManagerClass.checkPins.overload('java.util.List');
    NetworkSecurityTrustManagerClassCheckPins.implementation = function(v0) {
        //什么都不做
        console.log("android.security.net.config.NetworkSecurityTrustManager.checkPins('java.util.List') was hooked!");
    };
}
public SSLSocketFactory(
        String algorithm,
        final KeyStore keystore,
        final String keystorePassword,
        final KeyStore truststore,
        final SecureRandom random,
        final HostNameResolver nameResolver)
        throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException
    {
        super();
        if (algorithm == null) {
            algorithm = TLS;
        }
        KeyManager[] keymanagers = null;
        if (keystore != null) {
            keymanagers = createKeyManagers(keystore, keystorePassword);
        }
        TrustManager[] trustmanagers = new TrustManager[]{new ImSureItsLegitTrustManager()};;//这里被替换了,就这么简单
        this.sslcontext = SSLContext.getInstance(algorithm);
        this.sslcontext.init(keymanagers, trustmanagers, random);
        this.socketfactory = this.sslcontext.getSocketFactory();
        this.nameResolver = nameResolver;
    }
public SSLSocketFactory(
        String algorithm,
        final KeyStore keystore,
        final String keystorePassword,
        final KeyStore truststore,
        final SecureRandom random,
        final HostNameResolver nameResolver)
        throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException
    {
        super();
        if (algorithm == null) {
            algorithm = TLS;
        }
        KeyManager[] keymanagers = null;
        if (keystore != null) {
            keymanagers = createKeyManagers(keystore, keystorePassword);
        }
        TrustManager[] trustmanagers = new TrustManager[]{new ImSureItsLegitTrustManager()};;//这里被替换了,就这么简单
        this.sslcontext = SSLContext.getInstance(algorithm);
        this.sslcontext.init(keymanagers, trustmanagers, random);
        this.socketfactory = this.sslcontext.getSocketFactory();
        this.nameResolver = nameResolver;
    }
Java.perform(function() {
    var Helper = Java.use("gz.justtrustme.Helper");
    //替换trustmanagers参数
    var SSLSocketFactory = Java.use('org.apache.http.conn.ssl.SSLSocketFactory');
    var SSLSocketFactoryRapeConstructor = SSLSocketFactory.$init.overload('java.lang.String', 'java.security.KeyStore', 'java.lang.String', 'java.security.KeyStore', 'java.security.SecureRandom', 'org.apache.http.conn.scheme.HostNameResolver');
    SSLSocketFactoryRapeConstructor.implementation = function(v0, v1, v2, v3, v4, v5) {
        var returnObj = SSLSocketFactoryRapeConstructor.call(this, v0, v1, v2, v3, v4, v5);
        console.log("org.apache.http.conn.ssl.SSLSocketFactory.$init('java.lang.String', 'java.security.KeyStore', 'java.lang.String', 'java.security.KeyStore', 'java.security.SecureRandom', 'org.apache.http.conn.scheme.HostNameResolver') was hooked!");
        if (Helper.reInitSSLSocketFactory(returnObj, v0, v1, v2, v3, v4, v5)) {
            console.log("替换trustmanagers参数成功!");
        }else{
            console.log("替换trustmanagers参数失败!");
        }
        return returnObj;
    };
}
Java.perform(function() {
    var Helper = Java.use("gz.justtrustme.Helper");
    //替换trustmanagers参数
    var SSLSocketFactory = Java.use('org.apache.http.conn.ssl.SSLSocketFactory');
    var SSLSocketFactoryRapeConstructor = SSLSocketFactory.$init.overload('java.lang.String', 'java.security.KeyStore', 'java.lang.String', 'java.security.KeyStore', 'java.security.SecureRandom', 'org.apache.http.conn.scheme.HostNameResolver');
    SSLSocketFactoryRapeConstructor.implementation = function(v0, v1, v2, v3, v4, v5) {
        var returnObj = SSLSocketFactoryRapeConstructor.call(this, v0, v1, v2, v3, v4, v5);
        console.log("org.apache.http.conn.ssl.SSLSocketFactory.$init('java.lang.String', 'java.security.KeyStore', 'java.lang.String', 'java.security.KeyStore', 'java.security.SecureRandom', 'org.apache.http.conn.scheme.HostNameResolver') was hooked!");
        if (Helper.reInitSSLSocketFactory(returnObj, v0, v1, v2, v3, v4, v5)) {
            console.log("替换trustmanagers参数成功!");
        }else{
            console.log("替换trustmanagers参数失败!");
        }
        return returnObj;
    };
}
public static SSLSocketFactory getSocketFactory() {
    //return NoPreloadHolder.DEFAULT_FACTORY;
    return new SSLSocketFactory();
}
public static SSLSocketFactory getSocketFactory() {
    //return NoPreloadHolder.DEFAULT_FACTORY;
    return new SSLSocketFactory();
}
Java.perform(function() {
    var SSLSocketFactory = Java.use('org.apache.http.conn.ssl.SSLSocketFactory');
    var SSLSocketFactoryGetSocketFactoryMethod = SSLSocketFactory.getSocketFactory.overload();
    var SSLSocketFactoryEmptyConstructor = SSLSocketFactory.$init.overload();
    SSLSocketFactoryGetSocketFactoryMethod.implementation = function() {
        //强制用空的构造方法
        console.log("org.apache.http.conn.ssl.SSLSocketFactory.getSocketFactory() was hooked!");
        return SSLSocketFactoryEmptyConstructor.call(this);
    };
}
Java.perform(function() {
    var SSLSocketFactory = Java.use('org.apache.http.conn.ssl.SSLSocketFactory');
    var SSLSocketFactoryGetSocketFactoryMethod = SSLSocketFactory.getSocketFactory.overload();
    var SSLSocketFactoryEmptyConstructor = SSLSocketFactory.$init.overload();
    SSLSocketFactoryGetSocketFactoryMethod.implementation = function() {
        //强制用空的构造方法
        console.log("org.apache.http.conn.ssl.SSLSocketFactory.getSocketFactory() was hooked!");
        return SSLSocketFactoryEmptyConstructor.call(this);
    };
}
public boolean isSecure(Socket sock)
        throws IllegalArgumentException {
        return true;
}
public boolean isSecure(Socket sock)
        throws IllegalArgumentException {
        return true;
}
Java.perform(function() {
    var SSLSocketFactory = Java.use('org.apache.http.conn.ssl.SSLSocketFactory');
    var SSLSocketFactoryIsSecure = SSLSocketFactory.isSecure.overload('java.net.Socket');
    SSLSocketFactoryIsSecure.implementation = function(v0) {
        //强制返回true
        console.log("org.apache.http.conn.ssl.SSLSocketFactory.isSecure('java.net.Socket') was hooked!");
        return true;
    };
}
Java.perform(function() {
    var SSLSocketFactory = Java.use('org.apache.http.conn.ssl.SSLSocketFactory');
    var SSLSocketFactoryIsSecure = SSLSocketFactory.isSecure.overload('java.net.Socket');
    SSLSocketFactoryIsSecure.implementation = function(v0) {
        //强制返回true
        console.log("org.apache.http.conn.ssl.SSLSocketFactory.isSecure('java.net.Socket') was hooked!");
        return true;
    };
}
public final TrustManager[] getTrustManagers() {
     TrustManager[] originResult = factorySpi.engineGetTrustManagers();//原代码是直接return factorySpi.engineGetTrustManagers()
    if (hasTrustManagerImpl()) {
        Class<?> cls = Class.from("com.android.org.conscrypt.TrustManagerImpl");
        if (originResult.length > 0 && cls.isInstance(originResult[0])) {
            return originResult;
        }
    }
    return new TrustManager[]{new ImSureItsLegitTrustManager()};
}
public final TrustManager[] getTrustManagers() {
     TrustManager[] originResult = factorySpi.engineGetTrustManagers();//原代码是直接return factorySpi.engineGetTrustManagers()
    if (hasTrustManagerImpl()) {
        Class<?> cls = Class.from("com.android.org.conscrypt.TrustManagerImpl");
        if (originResult.length > 0 && cls.isInstance(originResult[0])) {
            return originResult;
        }
    }
    return new TrustManager[]{new ImSureItsLegitTrustManager()};
}
Java.perform(function() {
    var Helper = Java.use("gz.justtrustme.Helper");
    var TrustManagerFactory = Java.use('javax.net.ssl.TrustManagerFactory');
    var TrustManagerFactoryGetTrustManagers = TrustManagerFactory.getTrustManagers.overload();
    TrustManagerFactoryGetTrustManagers.implementation = function() {
        var ret = TrustManagerFactoryGetTrustManagers.call(this);
        //替换getTrustManagers方法逻辑
        console.log("javax.net.ssl.TrustManagerFactory.getTrustManagers() was hooked!");
        return Helper.replaceGetTrustManagers(this, ret);
    };
}
Java.perform(function() {
    var Helper = Java.use("gz.justtrustme.Helper");
    var TrustManagerFactory = Java.use('javax.net.ssl.TrustManagerFactory');
    var TrustManagerFactoryGetTrustManagers = TrustManagerFactory.getTrustManagers.overload();
    TrustManagerFactoryGetTrustManagers.implementation = function() {
        var ret = TrustManagerFactoryGetTrustManagers.call(this);
        //替换getTrustManagers方法逻辑
        console.log("javax.net.ssl.TrustManagerFactory.getTrustManagers() was hooked!");
        return Helper.replaceGetTrustManagers(this, ret);
    };
}
public static void setDefaultHostnameVerifier(HostnameVerifier v) {
    //啥都不干
}
 
public void setSSLSocketFactory(SSLSocketFactory sf) {
    //啥都不干
}
 
public static void setDefaultHostnameVerifier(HostnameVerifier v) {
    //啥都不干
}
public static void setDefaultHostnameVerifier(HostnameVerifier v) {
    //啥都不干
}
 
public void setSSLSocketFactory(SSLSocketFactory sf) {
    //啥都不干
}
 
public static void setDefaultHostnameVerifier(HostnameVerifier v) {
    //啥都不干
}
Java.perform(function() {
    var HttpsURLConnection = Java.use("javax.net.ssl.HttpsURLConnection");
    var HttpsURLConnectionSetDefaultHostnameVerifier = HttpsURLConnection.setDefaultHostnameVerifier.overload('javax.net.ssl.HostnameVerifier');
    HttpsURLConnectionSetDefaultHostnameVerifier.implementation = function(v0) {
        //什么都不做
        console.log("javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier('javax.net.ssl.HostnameVerifier') was hooked!");
    };
 
    var HttpsURLConnectionSetHostnameVerifier = HttpsURLConnection.setHostnameVerifier.overload('javax.net.ssl.HostnameVerifier');
    HttpsURLConnectionSetHostnameVerifier.implementation = function(v0) {
        //什么都不做
        console.log("javax.net.ssl.HttpsURLConnection.setHostnameVerifier('javax.net.ssl.HostnameVerifier') was hooked!");
    };
 
    var HttpsURLConnectionSetSSLSocketFactory = HttpsURLConnection.setSSLSocketFactory.overload('javax.net.ssl.SSLSocketFactory');
    HttpsURLConnectionSetSSLSocketFactory.implementation = function(v0) {
        //什么都不做
        console.log("javax.net.ssl.SSLSocketFactory.setSSLSocketFactory('javax.net.ssl.SSLSocketFactory') was hooked!");
    };
}
Java.perform(function() {
    var HttpsURLConnection = Java.use("javax.net.ssl.HttpsURLConnection");
    var HttpsURLConnectionSetDefaultHostnameVerifier = HttpsURLConnection.setDefaultHostnameVerifier.overload('javax.net.ssl.HostnameVerifier');
    HttpsURLConnectionSetDefaultHostnameVerifier.implementation = function(v0) {
        //什么都不做
        console.log("javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier('javax.net.ssl.HostnameVerifier') was hooked!");
    };
 
    var HttpsURLConnectionSetHostnameVerifier = HttpsURLConnection.setHostnameVerifier.overload('javax.net.ssl.HostnameVerifier');
    HttpsURLConnectionSetHostnameVerifier.implementation = function(v0) {
        //什么都不做
        console.log("javax.net.ssl.HttpsURLConnection.setHostnameVerifier('javax.net.ssl.HostnameVerifier') was hooked!");
    };
 
    var HttpsURLConnectionSetSSLSocketFactory = HttpsURLConnection.setSSLSocketFactory.overload('javax.net.ssl.SSLSocketFactory');
    HttpsURLConnectionSetSSLSocketFactory.implementation = function(v0) {
        //什么都不做
        console.log("javax.net.ssl.SSLSocketFactory.setSSLSocketFactory('javax.net.ssl.SSLSocketFactory') was hooked!");
    };
}
public final void init(KeyManager[] km, TrustManager[] tm,
                                SecureRandom random)
        throws KeyManagementException {
        tm = new TrustManager[]{new ImSureItsLegitTrustManager()};
        contextSpi.engineInit(null, tm, null);
}
public final void init(KeyManager[] km, TrustManager[] tm,
                                SecureRandom random)
        throws KeyManagementException {
        tm = new TrustManager[]{new ImSureItsLegitTrustManager()};
        contextSpi.engineInit(null, tm, null);
}
Java.perform(function() {
    var SSLContextClz = Java.use('javax.net.ssl.SSLContext');
    var SSLContextClzInit = SSLContextClz.init.overload('[Ljavax.net.ssl.KeyManager;', '[Ljavax.net.ssl.TrustManager;', 'java.security.SecureRandom');
    SSLContextClzInit.implementation = function(v0, v1, v2) {
        //将第二个参数强制替换为我们自己构造的不安全的TrustManagers
        SSLContextClzInit.call(this, v0, Helper.getImSureTrustManagers(), v2);
        console.log("javax.net.ssl.SSLContext.init('[Ljavax.net.ssl.KeyManager;', '[Ljavax.net.ssl.TrustManager;', 'java.security.SecureRandom') was hooked!");
    };
}
Java.perform(function() {
    var SSLContextClz = Java.use('javax.net.ssl.SSLContext');
    var SSLContextClzInit = SSLContextClz.init.overload('[Ljavax.net.ssl.KeyManager;', '[Ljavax.net.ssl.TrustManager;', 'java.security.SecureRandom');
    SSLContextClzInit.implementation = function(v0, v1, v2) {
        //将第二个参数强制替换为我们自己构造的不安全的TrustManagers
        SSLContextClzInit.call(this, v0, Helper.getImSureTrustManagers(), v2);
        console.log("javax.net.ssl.SSLContext.init('[Ljavax.net.ssl.KeyManager;', '[Ljavax.net.ssl.TrustManager;', 'java.security.SecureRandom') was hooked!");
    };
}
final void attach(Context context) {
        attachBaseContext(context);
        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
        ClassLoader appClassLoader = context.getClassLoader();
        processOkHttp(appClassLoader);
        processHttpClientAndroidLib(appClassLoader);
        processXutils(appClassLoader);
    }
final void attach(Context context) {
        attachBaseContext(context);
        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
        ClassLoader appClassLoader = context.getClassLoader();
        processOkHttp(appClassLoader);
        processHttpClientAndroidLib(appClassLoader);
        processXutils(appClassLoader);
    }
Java.perform(function() {
     var ApplicationClz = Java.use('android.app.Application');
    var ApplicationClzAttach = ApplicationClz.attach.overload('android.content.Context');
    ApplicationClzAttach.implementation = function(context) {
        ApplicationClzAttach.call(this, context);
        //注意justTrustMe使用的是afterHookedMethod,所以我们用frida也必须在原方法call完之后执行我们的代码
        var classLoader = context.getClassLoader();
 
    };
}
Java.perform(function() {
     var ApplicationClz = Java.use('android.app.Application');
    var ApplicationClzAttach = ApplicationClz.attach.overload('android.content.Context');
    ApplicationClzAttach.implementation = function(context) {
        ApplicationClzAttach.call(this, context);
        //注意justTrustMe使用的是afterHookedMethod,所以我们用frida也必须在原方法call完之后执行我们的代码
        var classLoader = context.getClassLoader();
 
    };
}
 
public void check(String str, List<Certificate> list) {
    //原代码校验失败会throw new throw new SSLPeerUnverifiedException(sb.toString());
    //hook之后相当于什么都不操作
}
public void check(String str, List<Certificate> list) {
    //原代码校验失败会throw new throw new SSLPeerUnverifiedException(sb.toString());
    //hook之后相当于什么都不操作
}
public boolean verify(String str, SSLSession sSLSession) {
    return true;
}
 
public boolean verify(String str, X509Certificate x509Certificate) {
    return true;
}
public boolean verify(String str, SSLSession sSLSession) {
    return true;
}
 
public boolean verify(String str, X509Certificate x509Certificate) {
    return true;
}
function processOkHttp() {
    //知道你为什么有时候用JustTrustMe失败吗,因为app代码混淆了下面这些类你改到对应的类和方法就行啦
    if (classExists("com.squareup.okhttp.CertificatePinner")) {
        var squareupOkhttp3CertificatePinnerClz = Java.use('com.squareup.okhttp.CertificatePinner');
        var squareupOkhttp3CertificatePinnerClzCheck = squareupOkhttp3CertificatePinnerClz.check.overload('java.lang.String', 'java.util.List');
        squareupOkhttp3CertificatePinnerClzCheck.implementation = function(v0, v1) {
            //什么都不做
            console.log("com.squareup.okhttp.CertificatePinner.check('java.lang.String', 'java.util.List') was hooked!");
        };
    }else{
        console.error("没找到com.squareup.okhttp.CertificatePinner类,这是android系统自带的类没找到就算求了。不同系统不一样,不用找了!!!");
    }
 
    if (classExists("okhttp3.CertificatePinner")) {
        try {
            var okhttp3CertificatePinnerClz = Java.use('okhttp3.CertificatePinner');
            var okhttp3CertificatePinnerClzCheck = okhttp3CertificatePinnerClz.check.overload('java.lang.String', 'java.util.List');
            okhttp3CertificatePinnerClzCheck.implementation = function(v0, v1) {
                //什么都不做
                console.log("okhttp3.CertificatePinner.check('java.lang.String', 'java.util.List') was hooked!");
            };
        } catch (error) {
            console.error("okhttp3.CertificatePinner的check方法可能被混淆了。你可以jadx反编译下还原回来!");
        }
    }else{
        console.error("没找到okhttp3.CertificatePinner类,可能被混淆了。你可以jadx反编译下还原回来!");
    }
 
    if (classExists("okhttp3.internal.tls.OkHostnameVerifier")) {
        try {
            var OkHostnameVerifierClz = Java.use('okhttp3.internal.tls.OkHostnameVerifier');
            var OkHostnameVerifierClzVerify_5791 = OkHostnameVerifierClz.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession');
            OkHostnameVerifierClzVerify_5791.implementation = function(v0, v1) {
                //强制返回true
                console.log("okhttp3.internal.tls.OkHostnameVerifier.verify('java.lang.String', 'javax.net.ssl.SSLSession') was hooked!");
                return true;
            };
            var OkHostnameVerifierVerify_8978 = OkHostnameVerifierClz.verify.overload('java.lang.String', 'java.security.cert.X509Certificate');
            OkHostnameVerifierVerify_8978.implementation = function(v0, v1) {
                //强制返回true
                console.log("okhttp3.internal.tls.OkHostnameVerifier.verify('java.lang.String', 'java.security.cert.X509Certificate') was hooked!");
                return true;
            };
        } catch (error) {
            console.error("okhttp3.internal.tls.OkHostnameVerifier的verify方法可能被混淆了。你可以jadx反编译下还原回来!");
        }
    }else{
        console.error("没找到okhttp3.internal.tls.OkHostnameVerifier类,可能被混淆了。你可以jadx反编译下还原回来!");
    }
 
}
function processOkHttp() {
    //知道你为什么有时候用JustTrustMe失败吗,因为app代码混淆了下面这些类你改到对应的类和方法就行啦
    if (classExists("com.squareup.okhttp.CertificatePinner")) {
        var squareupOkhttp3CertificatePinnerClz = Java.use('com.squareup.okhttp.CertificatePinner');
        var squareupOkhttp3CertificatePinnerClzCheck = squareupOkhttp3CertificatePinnerClz.check.overload('java.lang.String', 'java.util.List');
        squareupOkhttp3CertificatePinnerClzCheck.implementation = function(v0, v1) {
            //什么都不做
            console.log("com.squareup.okhttp.CertificatePinner.check('java.lang.String', 'java.util.List') was hooked!");
        };
    }else{
        console.error("没找到com.squareup.okhttp.CertificatePinner类,这是android系统自带的类没找到就算求了。不同系统不一样,不用找了!!!");
    }
 
    if (classExists("okhttp3.CertificatePinner")) {
        try {
            var okhttp3CertificatePinnerClz = Java.use('okhttp3.CertificatePinner');
            var okhttp3CertificatePinnerClzCheck = okhttp3CertificatePinnerClz.check.overload('java.lang.String', 'java.util.List');
            okhttp3CertificatePinnerClzCheck.implementation = function(v0, v1) {
                //什么都不做
                console.log("okhttp3.CertificatePinner.check('java.lang.String', 'java.util.List') was hooked!");
            };
        } catch (error) {
            console.error("okhttp3.CertificatePinner的check方法可能被混淆了。你可以jadx反编译下还原回来!");
        }
    }else{
        console.error("没找到okhttp3.CertificatePinner类,可能被混淆了。你可以jadx反编译下还原回来!");
    }
 
    if (classExists("okhttp3.internal.tls.OkHostnameVerifier")) {
        try {
            var OkHostnameVerifierClz = Java.use('okhttp3.internal.tls.OkHostnameVerifier');
            var OkHostnameVerifierClzVerify_5791 = OkHostnameVerifierClz.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession');
            OkHostnameVerifierClzVerify_5791.implementation = function(v0, v1) {
                //强制返回true
                console.log("okhttp3.internal.tls.OkHostnameVerifier.verify('java.lang.String', 'javax.net.ssl.SSLSession') was hooked!");
                return true;
            };
            var OkHostnameVerifierVerify_8978 = OkHostnameVerifierClz.verify.overload('java.lang.String', 'java.security.cert.X509Certificate');
            OkHostnameVerifierVerify_8978.implementation = function(v0, v1) {
                //强制返回true
                console.log("okhttp3.internal.tls.OkHostnameVerifier.verify('java.lang.String', 'java.security.cert.X509Certificate') was hooked!");
                return true;
            };
        } catch (error) {
            console.error("okhttp3.internal.tls.OkHostnameVerifier的verify方法可能被混淆了。你可以jadx反编译下还原回来!");
        }
    }else{
        console.error("没找到okhttp3.internal.tls.OkHostnameVerifier类,可能被混淆了。你可以jadx反编译下还原回来!");
    }
 
}
public final void verify(String arg1, String[] arg2, boolean arg3){
    //什么都不做
}
public final void verify(String arg1, String[] arg2, boolean arg3){
    //什么都不做
}
function processHttpClientAndroidLib() {
    if (classExists("ch.boye.httpclientandroidlib.conn.ssl.AbstractVerifier")) {
        var AbstractVerifierClass = Java.use("ch.boye.httpclientandroidlib.conn.ssl.AbstractVerifier");
        var OkHostnameVerifierClzVerify_5791 = AbstractVerifierClass.verify.overload('java.lang.String', '[Ljava.lang.String;', '[Ljava.lang.String;', 'boolean');
        OkHostnameVerifierClzVerify_5791.implementation = function(v0, v1, v2, v3) {
            //什么都不做
            console.log("ch.boye.httpclientandroidlib.conn.ssl.AbstractVerifier.verify('java.lang.String', '[Ljava.lang.String;', '[Ljava.lang.String;', 'boolean') was hooked!");
        };
    }else{
        console.error("没找到ch.boye.httpclientandroidlib.conn.ssl.AbstractVerifier类,但是这个类用的少。不用找了!");
    }
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2021-5-7 10:54 被爬虫不看学历编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (12)
雪    币: 142
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
期待大佬新作,逆向武功打穿看雪。
2021-5-7 11:01
1
雪    币: 268
活跃值: (786)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
期待大佬新作,逆向武功打穿看雪。
2021-5-7 11:09
0
雪    币: 831
活跃值: (2830)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4

************

最后于 2021-5-7 11:54 被kanxue编辑 ,原因: 就事论事,勿人身攻击!
2021-5-7 11:25
0
雪    币: 638
活跃值: (1772)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
5


有威胁、恐吓行为的,尚未构成犯罪的,会被公安机关处五日以下拘留或者五百元以下罚款;情节较重的,处五日以上十日以下拘留,可以并处五百元以下罚款。

最后于 2021-5-7 11:35 被ogli324编辑 ,原因:
2021-5-7 11:29
0
雪    币: 2909
活跃值: (1323)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
https://blog.csdn.net/tl3shi/article/details/112001225 这个自述就是大佬吗?
2021-5-7 11:31
0
雪    币: 853
活跃值: (488)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
期待大佬新作,逆向武功打穿看雪。
2021-5-7 11:40
0
雪    币: 3071
活跃值: (4152)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8

2021-5-7 11:47
0
雪    币: 831
活跃值: (2830)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
丶咖啡猫丶 https://blog.csdn.net/tl3shi/article/details/112001225 这个自述就是大佬吗?
@咖啡猫 不是
2021-5-7 11:48
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
爬虫不看学历 有一天我看见他,我一定会卸他几个手指头
届时务必直播
2021-5-7 11:53
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
11
2021-5-7 12:11
0
雪    币: 13
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12

恭喜大佬炒作成功

最后于 2021-5-7 13:31 被网络小男孩编辑 ,原因:
2021-5-7 13:30
0
雪    币: 1122
活跃值: (1928)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
13
郭钟哥哥yyds
2021-5-7 16:12
0
游客
登录 | 注册 方可回帖
返回
//