双向校验案例

测试Apk

NCSearch.apk

服务端校验客户端

现象

  1. 配置好Charles抓包环境并完成浏览器百度访问测试.
  2. 对App进行抓包.

服务端校验客户端标志

观察上述response数据,发现有"400 No required SSL certificate was sent"提示信息,是说服务端未接收到所需要的SSL证书信息,也就是说服务端对客户端进行了证书校验.

寻找服务端信任证书

当App未使用VPN代理时对服务器进行访问,服务器是能够正常返回数据的,说明App在与服务器进行通信的过程中是使用服务器端信任的证书与服务器进行数据交互的,因此服务器端信任的证书一定会在App发起通信之前从资源文件中加载进来,那么只需将Apk进行解包使用下述命令进行搜索.

1
2
//通常来搜索 .p12 .bks .truststore
tree -NCfhl |grep -i .p12

当前也有一些App,会通过改名、加密等方式将证书隐藏起来,遇到这种情况,可以通过Hook的手段快速定位(这里可以参考下r0capture的代码).

需要注意的是,执行下述Hook代码前,需要先将手机中的VPN代理关掉.因为该App还有客户端校验服务端的代码.

 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
function uuid(len, radix) {
    var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
    var uuid = [], i;
    radix = radix || chars.length;
  
    if (len) {
      // Compact form
      for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
    } else {
      // rfc4122, version 4 form
      var r;
  
      // rfc4122 requires these characters
      uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
      uuid[14] = '4';
  
      // Fill in random data. At i==19 set the high bits of clock sequence as
      // per rfc4122, sec. 4.1.5
      for (i = 0; i < 36; i++) {
        if (!uuid[i]) {
          r = 0 | Math.random() * 16;
          uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
        }
      }
    }
  
    return uuid.join('');
  }

function main(){
    Java.perform(function(){
        function storeP12(pri, p7, p12Path, p12Password) {
            var X509Certificate = Java.use("java.security.cert.X509Certificate")
            var p7X509 = Java.cast(p7, X509Certificate);
            var chain = Java.array("java.security.cert.X509Certificate", [p7X509])
            var ks = Java.use("java.security.KeyStore").getInstance("PKCS12", "BC");
            ks.load(null, null);
            ks.setKeyEntry("client", pri, Java.use('java.lang.String').$new(p12Password).toCharArray(), chain);
            try {
              var out = Java.use("java.io.FileOutputStream").$new(p12Path);
              ks.store(out, Java.use('java.lang.String').$new(p12Password).toCharArray())
              console.log("dump success!")
            } catch (exp) {
              console.log(exp)
            }
        }
          //在服务器校验客户端的情形下,帮助dump客户端证书,并保存为p12的格式,证书密码为LuoHun
          Java.use("java.security.KeyStore$PrivateKeyEntry").getPrivateKey.implementation = function () {
            var result = this.getPrivateKey()
            var packageName = Java.use("android.app.ActivityThread").currentApplication().getApplicationContext().getPackageName();
            storeP12(this.getPrivateKey(), this.getCertificate(), '/sdcard/Download/' + packageName + uuid(10, 16) + '.p12', 'LuoHun');
            return result;
          }
          Java.use("java.security.KeyStore$PrivateKeyEntry").getCertificateChain.implementation = function () {
            var result = this.getCertificateChain()
            var packageName = Java.use("android.app.ActivityThread").currentApplication().getApplicationContext().getPackageName();
            storeP12(this.getPrivateKey(), this.getCertificate(), '/sdcard/Download/' + packageName + uuid(10, 16) + '.p12', 'LuoHun');
            return result;
          }
    })
}

setImmediate(main)

证书Dump

导出证书

当Frida Hook显示dump success!时,就去手机的/sdcard/Download/将证书导出.

1
2
3
4
5
6
7
adb shell
su
cd /sdcard/Download/
mkdir luo
mv *.p12 luo

adb pull /sdcard/Download/luo

Charles导入证书

Charles导入证书

Charles导入证书1

Import P12证书时,选择上述导出到PC端上的任一证书文件即可,输入密码 LuoHun

这样配置的话,就可将服务端信任的证书导入到Charles中,从而达到了"欺骗"服务器的目的.

非标转端口添加

非标准端口添加

这里可以看到,该App使用了非标准端口,在Charles中依次点击 Proxy->SSL Proxying Settings,在弹出窗口中输入端口号即可.

非标准端口添加1

客户端校验服务端

对于客户端校验服务端的Hook代码,可参考下述github仓库.

https://github.com/CreditTone/hooker/blob/master/js/just_trust_me.js

  1. 将radar.dex 放到手机/data/local/tmp目录中,并设置可执行权限.

radar.dex

  1. 执行下述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
 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
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
function classExists(className) {
    var exists = false;
    try {
        var clz = Java.use(className);
        exists = true;
    } catch(err) {
        //console.log(err);
    }
    return exists;
};

function loadDexfile(dexfile) {
    Java.perform(function() {
        Java.openClassFile(dexfile).load();
        //console.log("load " + dexfile);
    });
};

var loadedXRadar = false;
function loadXRadarDexfile() {
    loadedXRadar = true;
    loadDexfile('/data/local/tmp/radar.dex');
};


loadXRadarDexfile();

function hasTrustManagerImpl() {
    return classExists("com.android.org.conscrypt.TrustManagerImpl");
}

function newArrayList() {
    var ArrayListClz = Java.use('java.util.ArrayList');
    return ArrayListClz.$new();
}


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反编译下还原回来!");
    }

    if (classExists("okhttp3.OkHttpClient$Builder")) {
        try{
            var okhttp3_OkHttpClient_Builder_clz = Java.use('okhttp3.OkHttpClient$Builder');
            var okhttp3_OkHttpClient_Builder_clz_sslSocketFactory_one = okhttp3_OkHttpClient_Builder_clz.sslSocketFactory.overload('javax.net.ssl.SSLSocketFactory');
            okhttp3_OkHttpClient_Builder_clz_sslSocketFactory_one.implementation = function(sSLSocketFactory) {
                //把参数替换成EmptySSLFactory
                var ret = okhttp3_OkHttpClient_Builder_clz_sslSocketFactory_one.call(this, Java.use("gz.justtrustme.Helper").getEmptySSLFactory());
                return ret;
            };
            var okhttp3_OkHttpClient_Builder_clz_sslSocketFactory_two = okhttp3_OkHttpClient_Builder_clz.sslSocketFactory.overload('javax.net.ssl.SSLSocketFactory', 'javax.net.ssl.X509TrustManager');
            okhttp3_OkHttpClient_Builder_clz_sslSocketFactory_two.implementation = function(sSLSocketFactory, x509TrustManager) {
                //把参数替换成EmptySSLFactory
                var ret = okhttp3_OkHttpClient_Builder_clz_sslSocketFactory_two.call(this, Java.use("gz.justtrustme.Helper").getEmptySSLFactory(), x509TrustManager);
                return ret;
            };
        } catch(error) {
            console.error("okhttp3.OkHttpClient$Builder的sslSocketFactory方法可能被混淆了。你可以jadx反编译下还原回来!");
        }
    }else{
        console.error("没找到okhttp3.OkHttpClient$Builder类,可能被混淆了。你可以jadx反编译下还原回来!");
    }
}


function processXutils() {
    if (classExists("org.xutils.http.RequestParams")) {
        var RequestParamsClass = Java.use("org.xutils.http.RequestParams");
        var RequestParamsClassSetSslSocketFactory = RequestParamsClass.setSslSocketFactory.overload('javax.net.ssl.SSLSocketFactory');
        RequestParamsClassSetSslSocketFactory.implementation = function(v0) {
            console.log("org.xutils.http.RequestParams.setSslSocketFactory('javax.net.ssl.SSLSocketFactory') was hooked!");
            var Helper = Java.use("gz.justtrustme.Helper");
            //替换javax.net.ssl.SSLSocketFactory参数为我们的EmptySSLFactory
            RequestParamsClassSetSslSocketFactory.call(this, Helper.getEmptySSLFactory());
        };
        var RequestParamsClassSetHostnameVerifier = RequestParamsClass.setHostnameVerifier.overload('javax.net.ssl.HostnameVerifier');
        RequestParamsClassSetHostnameVerifier.implementation = function(v0) {
            console.log("org.xutils.http.RequestParams.setHostnameVerifier('javax.net.ssl.HostnameVerifier') was hooked!");
            var ImSureItsLegitHostnameVerifier = Java.use("gz.justtrustme.ImSureItsLegitHostnameVerifier");
            //替换javax.net.ssl.HostnameVerifier参数为我们的ImSureItsLegitHostnameVerifier
            RequestParamsClassSetHostnameVerifier.call(this, ImSureItsLegitHostnameVerifier.$new());
        };
    }
}

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类,但是这个类用的少。不用找了!");
    }
}

//这是hooker添加的hook点,原JustTrustMe中没有的
function processConscryptPlatform() {
    if (!classExists("com.android.org.conscrypt.Platform")) {
        return;
    }
    var com_android_org_conscrypt_Platform_clz = Java.use('com.android.org.conscrypt.Platform');
    var com_android_org_conscrypt_Platform_clz_method_checkServerTrusted_9565 = com_android_org_conscrypt_Platform_clz.checkServerTrusted.overload('javax.net.ssl.X509TrustManager', '[Ljava.security.cert.X509Certificate;', 'java.lang.String', 'com.android.org.conscrypt.ConscryptEngine');
    com_android_org_conscrypt_Platform_clz_method_checkServerTrusted_9565.implementation = function(v0, v1, v2, v3) {
        //什么都不做
    };
    var com_android_org_conscrypt_Platform_clz_method_checkServerTrusted_6928 = com_android_org_conscrypt_Platform_clz.checkServerTrusted.overload('javax.net.ssl.X509TrustManager', '[Ljava.security.cert.X509Certificate;', 'java.lang.String', 'com.android.org.conscrypt.AbstractConscryptSocket');
    com_android_org_conscrypt_Platform_clz_method_checkServerTrusted_6928.implementation = function(v0, v1, v2, v3) {
        //什么都不做
    };
}


//这是hooker添加的hook点,原JustTrustMe中没有的
function processPinningTrustManager() {
    if (!classExists("appcelerator.https.PinningTrustManager")) {
        return;
    }
    var pinningTrustManagerClass = Java.use('appcelerator.https.PinningTrustManager');
    var pinningTrustManagerClass_checkServerTrusted = pinningTrustManagerClass.checkServerTrusted.overload();
    pinningTrustManagerClass_checkServerTrusted.implementation = function() {
        //什么都不做
    };
}


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的三个构造方法逻辑全部被我们替换了
    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 Java.use('java.util.Arrays$ArrayList').$new(certsArr);
    };
    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!");
    };

    //替换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;
    };

    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);
    };

    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;
    };

    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);
    };

    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!");
    };

    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!");
    };

    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();

    };

    if (hasTrustManagerImpl()) {
        var TrustManagerImplClz = Java.use('com.android.org.conscrypt.TrustManagerImpl');
        var TrustManagerImplCheckServerTrusted_8813 = TrustManagerImplClz.checkServerTrusted.overload('[Ljava.security.cert.X509Certificate;', 'java.lang.String', 'java.lang.String');
        TrustManagerImplCheckServerTrusted_8813.implementation = function(v0, v1, v2) {
            console.log("com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted('[Ljava.security.cert.X509Certificate;', 'java.lang.String', 'java.lang.String') was hooked!");
            return newArrayList();
        };
        var TrustManagerImplCheckServerTrusted_7015 = TrustManagerImplClz.checkServerTrusted.overload('[Ljava.security.cert.X509Certificate;', 'java.lang.String', 'javax.net.ssl.SSLSession');
        TrustManagerImplCheckServerTrusted_7015.implementation = function(v0, v1, v2) {
            console.log("com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted('[Ljava.security.cert.X509Certificate;', 'java.lang.String', 'javax.net.ssl.SSLSession') was hooked!");
            return newArrayList();
        };
        var TrustManagerImplCheckTrusted_5587 = TrustManagerImplClz.checkTrusted.overload('[Ljava.security.cert.X509Certificate;', '[B', '[B', 'java.lang.String', 'java.lang.String', 'boolean');
        TrustManagerImplCheckTrusted_5587.implementation = function(v0, v1, v2, v3) {
            console.log("com.android.org.conscrypt.TrustManagerImpl.checkTrusted('[Ljava.security.cert.X509Certificate;', 'java.lang.String', 'java.lang.String', 'boolean') was hooked!");
            return newArrayList();
        };
        var TrustManagerImplCheckTrusted_9999 = TrustManagerImplClz.checkTrusted.overload('[Ljava.security.cert.X509Certificate;', 'java.lang.String', 'javax.net.ssl.SSLSession', 'javax.net.ssl.SSLParameters', 'boolean');
        TrustManagerImplCheckTrusted_9999.implementation = function(v0, v1, v2, v3, v4) {
            console.log("com.android.org.conscrypt.TrustManagerImpl.checkTrusted('[Ljava.security.cert.X509Certificate;', 'java.lang.String', 'javax.net.ssl.SSLSession', 'javax.net.ssl.SSLParameters', 'boolean') was hooked!");
            return newArrayList();
        };
    }

    processOkHttp();
    processXutils();
    processHttpClientAndroidLib();
    //hooker添加的hook点
    processConscryptPlatform();
    processPinningTrustManager();
})

参考链接

<安卓Frida逆向与抓包实战>


相关内容

0%