吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

搜索
查看: 1590|回复: 25
收起左侧

[Android 原创] 实现frida版的JustTrustMe(一)JustTrustMe官方源码学习

[复制链接]
西二旗搬砖仔 发表于 2021-5-6 10:41
前言
对于绕过ssl pinning的产品有很多,其中最著名的当属JustTrustMe。其他的sslUnPinning产品思想很多都是从JustTrustMe那里抄来的,由于JustTrustMe原作者也不更新了但是反sslUnPinning技术一直在前进,所以我决定用1一个月的业余时间来重新打造一款实用的sslUnPinning产品。

JustTrustMe我是很认可他的插桩点位的思路的。但是,本人是不认可xposed的。xposed的hook机制从设计之初就走了一条“不归路”,因为xposed有太多的特征可以被app检测。主要是xposed必须基于替换受精卵进程来实现,并且还要安装对应的app来管理插件,而且插件开发也要是单独的android工程。这个对于被攻击app来讲非常好从多个维度去检测xposed的存在,只是人家不想搞的这么明显大多不会强制退出app罢了。比如微信大家去jadx搜索代码,里面妥妥去检测了xposed,人家早就把你标记了。有些小team拿着官方已经停止更新的xposed改改包名,然后称之为魔改过反检测。其实,我要检测你,你怎么改都反不了。你包名改掉,但是你自定义的包名依然在调用栈里面。通过对比纯净android系统的正常堆栈,你立马被标记为灰度用户。还可以通过扫描已经安装的app列表,发现类似justtrustme之类的应用立马标记。还有你xposed管理本身也是一个app,你怎么隐藏? 改操作系统吗?但是,话又回来了,你都可以改操作系统了那你为什么不直接在framework层直接嵌入hook机制呢?因为,你技术还没到那一步,你只是停留在andorid项目改改包名的阶段,只能靠着这个去收割一些新人的韭菜。不好意思阿,我这人说话就是这么直!你费劲巴拉的搞一个大型项目,完了效果并不是真的全面反检测。我觉得没必要去做。

我想xposed的作者rovo89也是看到了这一点,所以没有再对xposed进行更新了。大庄家都不玩了,我们这些蝼蚁就要认清局势。该废弃的技术废弃,要舍得抛弃陈旧的技术这样你才能不断进步。我要把JustTrustMe用frida实现一版。所以先出一篇JustTrustMe源码分析,等大家熟悉了JustTrustMe源码我再带着大家用frida去搞一个"JustTrustMe":JustTrustMe源码阅读和剖析

请大家先打开JustTrustMe的Main.java,我下面会一一列举JustTrustMe的每个方法,以及它的作用和对应java的伪代码。

1、DefaultHttpClient的3个构造方法hook

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

/* external/apache-http/src/org/apache/http/impl/client/DefaultHttpClient.java */
/* public DefaultHttpClient() */

findAndHookConstructor(DefaultHttpClient.class, new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {

                setObjectField(param.thisObject, "defaultParams", null);
                setObjectField(param.thisObject, "connManager", getSCCM());
            }
        });

/* external/apache-http/src/org/apache/http/impl/client/DefaultHttpClient.java */
/* public DefaultHttpClient(HttpParams params) */
findAndHookConstructor(DefaultHttpClient.class, HttpParams.class, new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {

                setObjectField(param.thisObject, "defaultParams", (HttpParams) param.args[0]);
                setObjectField(param.thisObject, "connManager", getSCCM());
            }
        });

/* external/apache-http/src/org/apache/http/impl/client/DefaultHttpClient.java */
/* public DefaultHttpClient(ClientConnectionManager conman, HttpParams params) */
findAndHookConstructor(DefaultHttpClient.class, ClientConnectionManager.class, HttpParams.class, new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {

                HttpParams params = (HttpParams) param.args[1];

                setObjectField(param.thisObject, "defaultParams", params);
                setObjectField(param.thisObject, "connManager", getCCM(param.args[0], params));
            }
        });

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

//Create a SingleClientConnManager that trusts everyone!
public ClientConnectionManager getSCCM() {

        KeyStore trustStore;
        try {

            trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null, null);

            SSLSocketFactory sf = new TrustAllSSLSocketFactory(trustStore);
            sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

            SchemeRegistry registry = new SchemeRegistry();
            registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
            registry.register(new Scheme("https", sf, 443));

            ClientConnectionManager ccm = new SingleClientConnManager(null, registry);

            return ccm;

        } catch (Exception e) {
            return null;
        }
    }

//This function creates a ThreadSafeClientConnManager that trusts everyone!
public ClientConnectionManager getTSCCM(HttpParams params) {

        KeyStore trustStore;
        try {

            trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null, null);

            SSLSocketFactory sf = new TrustAllSSLSocketFactory(trustStore);
            sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

            SchemeRegistry registry = new SchemeRegistry();
            registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
            registry.register(new Scheme("https", sf, 443));

            ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

            return ccm;

        } catch (Exception e) {
            return null;
        }
    }

//This function determines what object we are dealing with.
public ClientConnectionManager getCCM(Object o, HttpParams params) {

        String className = o.getClass().getSimpleName();

        if (className.equals("SingleClientConnManager")) {
            return getSCCM();
        } else if (className.equals("ThreadSafeClientConnManager")) {
            return getTSCCM(params);
        }

        return null;
    }

那么,由此我们得到经过hook之后三个方法的伪代码逻辑。

1
2
3
4
5
6
7
8
9
10
11
12
13

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);
}
2、X509TrustManagerExtensions的checkServerTrusted方法hook

1
2
3
4
5
6

findAndHookMethod(X509TrustManagerExtensions.class, "checkServerTrusted", X509Certificate[].class, String.class, String.class, new XC_MethodReplacement() {
            @Override
            protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                return param.args[0];
            }
        });

分析:X509TrustManagerExtensions原方法会进行一系列的效应证书和服务器是否可信。这里xposed用了XC_MethodReplacement直接替换方法的执行体。
那么,伪代码逻辑如下:

1
2
3

public List<X509Certificate> checkServerTrusted(X509Certificate[] chain, String authType, String host) throws CertificateException {
        return chain;
}
3、NetworkSecurityTrustManager的checkPins方法hook

1
2
3
4
5
6

findAndHookMethod("android.security.net.config.NetworkSecurityTrustManager", lpparam.classLoader, "checkPins", List.class, new XC_MethodReplacement() {
            @Override
            protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                return null;
            }
        });

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

1
2
3

private void checkPins(List<X509Certificate> chain) throws CertificateException {

}
4. SSLSocketFactory的6参构造方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

/* external/apache-http/src/org/apache/http/conn/ssl/SSLSocketFactory.java */
/* public SSLSocketFactory( ... ) */
findAndHookConstructor(SSLSocketFactory.class, String.class, KeyStore.class, String.class, KeyStore.class,
                SecureRandom.class, HostNameResolver.class, new XC_MethodHook() {
                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {

                        String algorithm = (String) param.args[0];
                        KeyStore keystore = (KeyStore) param.args[1];
                        String keystorePassword = (String) param.args[2];
                        SecureRandom random = (SecureRandom) param.args[4];

                        KeyManager[] keymanagers = null;
                        TrustManager[] trustmanagers = null;

                        if (keystore != null) {
                            keymanagers = (KeyManager[]) callStaticMethod(SSLSocketFactory.class, "createKeyManagers", keystore, keystorePassword);
                        }

                        trustmanagers = new TrustManager[]{new ImSureItsLegitTrustManager()};

                        setObjectField(param.thisObject, "sslcontext", SSLContext.getInstance(algorithm));
                        callMethod(getObjectField(param.thisObject, "sslcontext"), "init", keymanagers, trustmanagers, random);
                        setObjectField(param.thisObject, "socketfactory",
                                callMethod(getObjectField(param.thisObject, "sslcontext"), "getSocketFactory"));
                    }

                });

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

给你看伪代码,那逻辑将一目了然:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

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;
    }
5. SSLSocketFactory的getSocketFactory方法

1
2
3
4
5
6

findAndHookMethod("org.apache.http.conn.ssl.SSLSocketFactory", lpparam.classLoader, "getSocketFactory", new XC_MethodReplacement() {
            @Override
            protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                return (SSLSocketFactory) newInstance(SSLSocketFactory.class);
            }
        });

分析:很好理解
伪代码:

1
2
3
4

public static SSLSocketFactory getSocketFactory() {
    //return NoPreloadHolder.DEFAULT_FACTORY;
    return new SSLSocketFactory();
}
6. SSLSocketFactory的isSecure

1
2
3
4
5
6

findAndHookMethod("org.apache.http.conn.ssl.SSLSocketFactory", lpparam.classLoader, "isSecure", Socket.class, new XC_MethodReplacement() {
            @Override
            protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                return true;
            }
        });

分析:强制让isSecure返回true
伪代码:

1
2
3
4

public boolean isSecure(Socket sock)
        throws IllegalArgumentException {
        return true;
}
7. TrustManagerFactory的getTrustManagers方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

findAndHookMethod("javax.net.ssl.TrustManagerFactory", lpparam.classLoader, "getTrustManagers", new XC_MethodHook() {
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {

                if (hasTrustManagerImpl()) {
                    Class<?> cls = findClass("com.android.org.conscrypt.TrustManagerImpl", lpparam.classLoader);

                    TrustManager[] managers = (TrustManager[]) param.getResult();
                    if (managers.length > 0 && cls.isInstance(managers[0]))
                        return;
                }

                param.setResult(new TrustManager[]{new ImSureItsLegitTrustManager()});
            }
        });

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

伪代码:

1
2
3
4
5
6
7
8
9
10

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()};
}
8. HttpsURLConnection的3个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setDefaultHostnameVerifier",
                HostnameVerifier.class, new XC_MethodReplacement() {
                    @Override
                    protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                        return null;
                    }
                });

findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setSSLSocketFactory", javax.net.ssl.SSLSocketFactory.class,
                new XC_MethodReplacement() {
                    @Override
                    protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                        return null;
                    }
                });

findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setHostnameVerifier", HostnameVerifier.class,
                new XC_MethodReplacement() {
                    @Override
                    protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
                        return null;
                    }
                });

分析:让setDefaultHostnameVerifier方法失效,让setSSLSocketFactory失效,让setHostnameVerifier失效
伪代码:

1
2
3
4
5
6
7
8
9
10
11

public static void setDefaultHostnameVerifier(HostnameVerifier v) {
    //啥都不干
}

public void setSSLSocketFactory(SSLSocketFactory sf) {
    //啥都不干
}

public static void setDefaultHostnameVerifier(HostnameVerifier v) {
    //啥都不干
}
9. javax.net.ssl.SSLContext的init

1
2
3
4
5
6
7
8
9
10
11

findAndHookMethod("javax.net.ssl.SSLContext", lpparam.classLoader, "init", KeyManager[].class, TrustManager[].class, SecureRandom.class, new XC_MethodHook() {

            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {

                param.args[0] = null;
                param.args[1] = new TrustManager[]{new ImSureItsLegitTrustManager()};
                param.args[2] = null;

            }
        });

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

伪代码:

1
2
3
4
5
6

public final void init(KeyManager[] km, TrustManager[] tm,
                                SecureRandom random)
        throws KeyManagementException {
        tm = new TrustManager[]{new ImSureItsLegitTrustManager()};
        contextSpi.engineInit(null, tm, null);
}
10. Application的attach

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

findAndHookMethod("android.app.Application",
                lpparam.classLoader,
                "attach",
                Context.class,
                new XC_MethodHook() {
                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                        // Hook OkHttp or third party libraries.
                        Context context = (Context) param.args[0];
                        processOkHttp(context.getClassLoader());
                        processHttpClientAndroidLib(context.getClassLoader());
                        processXutils(context.getClassLoader());
                    }
                }
        );

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

1
2
3
4
5
6
7
8

final void attach(Context context) {
        attachBaseContext(context);
        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
        ClassLoader appClassLoader = context.getClassLoader();
        processOkHttp(appClassLoader);
        processHttpClientAndroidLib(appClassLoader);
        processXutils(appClassLoader);
    }
11. processOkHttp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

void processOkHttp(ClassLoader classLoader) {
        try {
            classLoader.loadClass("com.squareup.okhttp.CertificatePinner");
            findAndHookMethod("com.squareup.okhttp.CertificatePinner",
                    classLoader,
                    "check",
                    String.class,
                    List.class,
                    new XC_MethodReplacement() {
                        @Override
                        protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
                            return true;
                        }
                    });
        } catch (ClassNotFoundException e) {
            // pass
            Log.d(TAG, "OKHTTP 2.5 not found in " + currentPackageName + "-- not hooking");
        }

try {
    classLoader.loadClass("okhttp3.CertificatePinner");
    findAndHookMethod("okhttp3.CertificatePinner",
                    classLoader,
                    "check",
                    String.class,
                    List.class,
                    new XC_MethodReplacement() {
                        @Override
                        protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
                            return null;
                        }
                    });
    } catch (ClassNotFoundException e) {
            Log.d(TAG, "OKHTTP 3.x not found in " + currentPackageName + " -- not hooking");
    }


try {
    classLoader.loadClass("okhttp3.internal.tls.OkHostnameVerifier");
    findAndHookMethod("okhttp3.internal.tls.OkHostnameVerifier",
                    classLoader,
                    "verify",
                    String.class,
                    javax.net.ssl.SSLSession.class,
                    new XC_MethodReplacement() {
                        @Override
                        protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
                            return true;
                        }
                    });
    } catch (ClassNotFoundException e) {
            Log.d(TAG, "OKHTTP 3.x not found in " + currentPackageName + " -- not hooking OkHostnameVerifier.verify(String, SSLSession)");
    }


try {
    classLoader.loadClass("okhttp3.internal.tls.OkHostnameVerifier");
    findAndHookMethod("okhttp3.internal.tls.OkHostnameVerifier",
                    classLoader,
                    "verify",
                    String.class,
                    java.security.cert.X509Certificate.class,
                    new XC_MethodReplacement() {
                        @Override
                        protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
                            return true;
                        }
                    });
    } catch (ClassNotFoundException e) {
            Log.d(TAG, "OKHTTP 3.x not found in " + currentPackageName + " -- not hooking OkHostnameVerifier.verify(String, X509)(");

    }

分析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异常。
CertificatePinner.check伪代码:

1
2
3
4

public void check(String str, List<Certificate> list) {
    //原代码校验失败会throw new throw new SSLPeerUnverifiedException(sb.toString());
    //hook之后相当于什么都不操作
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

public boolean verify(String str, SSLSession sSLSession) {
    return true;
}

public boolean verify(String str, X509Certificate x509Certificate) {
    return true;
}
``

### 12. processHttpClientAndroidLib
```java
void processHttpClientAndroidLib(ClassLoader classLoader) {
    try {
        classLoader.loadClass("ch.boye.httpclientandroidlib.conn.ssl.AbstractVerifier");
        findAndHookMethod("ch.boye.httpclientandroidlib.conn.ssl.AbstractVerifier", classLoader, "verify",
                    String.class, String[].class, String[].class, boolean.class,
                    new XC_MethodReplacement() {
                        @Override
                        protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
                            return null;
                        }
                    });
        } catch (ClassNotFoundException e) {
            // pass
            Log.d(TAG, "httpclientandroidlib not found in " + currentPackageName + "-- not hooking");
        }
    }

分析:一个冷门http库的hook
伪代码:

1
2
3

public final void verify(String arg1, String[] arg2, boolean arg3){
    //什么都不做
}
13. processXutils

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

private void processXutils(ClassLoader classLoader) {
    try {
        classLoader.loadClass("org.xutils.http.RequestParams");
        findAndHookMethod("org.xutils.http.RequestParams", classLoader, "setSslSocketFactory", javax.net.ssl.SSLSocketFactory.class, new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    super.beforeHookedMethod(param);
                    param.args[0] = getEmptySSLFactory();
                }
            });
        findAndHookMethod("org.xutils.http.RequestParams", classLoader, "setHostnameVerifier", HostnameVerifier.class, new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    super.beforeHookedMethod(param);
                    param.args[0] = new ImSureItsLegitHostnameVerifier();
                }
            });
        } catch (Exception e) {
            Log.d(TAG, "org.xutils.http.RequestParams not found in " + currentPackageName + "-- not hooking");
        }
    }

分析:一个冷门http库的hook
伪代码:

1
2
3
4
5
6
7
8
9
10
11
12
13

package org.xutils.http;
public class RequestParams {

    public void setSslSocketFactory(javax.net.ssl.SSLSocketFactory arg1) {
        arg1 = getEmptySSLFactory();//把参数用getEmptySSLFactory();返回值替代
        //继续下面的代码逻辑
    }

    public void setHostnameVerifier(javax.net.ssl.HostnameVerifier arg1) {
        arg1 = new ImSureItsLegitHostnameVerifier();//把参数用ImSureItsLegitHostnameVerifier对象替代
        //继续下面的代码逻辑
    }
}
总结
到目前为止,我们已经把JustTrustMe所有的hook点位全部分析了一遍。中间如果大家还是有不解的地方可以去查看每个类对应的源码,下列我帮大家找了一些

JustTrustMeMain.java

apache httpDefaultHttpClient.java

android frameworkX509TrustManagerExtensions.java

android frameworkNetworkSecurityTrustManager.java

apache httpSSLSocketFactory.java

javax TrustManagerFactory.java

javax HttpsURLConnection.java

javax SSLContext.java

android frameworkTrustManagerImpl.java

okhttp3 CertificatePinner.java

okhttp3 OkHostnameVerifier.java

免费评分

参与人数 8威望 +1 吾爱币 +30 热心值 +8 收起 理由
朮小凯 + 1 + 1 谢谢@Thanks!
qtfreet00 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
ljs999 + 1 + 1 前排mk
消失的853 + 1 + 1 谢谢@Thanks!
兜兜风f + 4 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
笙若 + 1 + 1 谢谢@Thanks!
★☆CNVIP☆★ + 1 + 1 谢谢@Thanks!
马甲下的蛋 + 1 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

ghq1314258 发表于 2021-5-8 09:39
一脸懵逼 坐等成品直接用  最好出教程啊  看起来好复杂
stilllove88 发表于 2021-5-6 19:26
一脸懵逼 坐等成品直接用  最好出教程啊  看起来好复杂
一傻逼撸 发表于 2021-5-6 10:54
kmzwyong12 发表于 2021-5-6 11:02
支持原创,学无止境。版主辛苦了!!!
那一年的白洁啊 发表于 2021-5-6 11:29
一脸懵逼+1
yangguang60 发表于 2021-5-6 12:27
虽然看不懂,但还是支持一下
First丶云心 发表于 2021-5-6 12:35
谢谢分享,学习学习!
科研资源 发表于 2021-5-6 13:29
6666 关键成品了
wangxd 发表于 2021-5-6 14:51
谢谢分享,学习学习!
xixicoco 发表于 2021-5-6 15:10
大牛都是看源码的
爱锭 发表于 2021-5-6 15:10
本帖最后由 爱锭 于 2021-5-6 15:51 编辑

您这不是爬虫不看学历,是怼人不看学历呀
757977_U62FPB43KK9JP4F.gif
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2021-6-16 23:01

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表