├── .gitattributes
├── .gitignore
├── Readme.md
├── app
├── .gitignore
├── build.gradle
├── libs
│ └── XposedBridgeApi.jar
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── me
│ │ └── trust
│ │ └── just
│ │ └── justtrustme
│ │ └── ApplicationTest.java
│ └── main
│ ├── AndroidManifest.xml
│ ├── assets
│ └── xposed_init
│ ├── java
│ └── just
│ │ └── trust
│ │ └── me
│ │ └── Main.java
│ └── res
│ ├── values-w820dp
│ └── dimens.xml
│ └── values
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── build.gradle
├── build.sh
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | /bin/
3 | app/build/
4 | app/src/main/bin/
5 | app/src/main/gen/
6 | build/
7 | .idea/
8 | .gradle
9 | /local.properties
10 | /.idea/workspace.xml
11 | .DS_Store
12 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # JustTrustMe-master
2 | 默认的JustTrustMe只会应用启动后Hook一次,因此在这基础上修改了log日志打印位置,使得每一次Hook函数调用都会输出实时日志,便于追踪SSL函数
3 |
4 | 
5 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 24
5 | buildToolsVersion '28.0.1'
6 | useLibrary 'org.apache.http.legacy'
7 | defaultConfig {
8 | applicationId 'just.trust.me'
9 | minSdkVersion 16
10 | targetSdkVersion 22
11 | versionCode 3
12 | versionName '.3'
13 | }
14 |
15 | buildTypes {
16 | release {
17 | minifyEnabled false
18 | }
19 | }
20 | productFlavors {
21 | }
22 | }
23 |
24 | dependencies {
25 | provided fileTree(dir: 'libs', include: ['*.jar'])
26 | }
27 |
--------------------------------------------------------------------------------
/app/libs/XposedBridgeApi.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/la0s/JustTrustMe-master/d0072cf6f1ccae0c7dec020840c1e46c84bfb0e3/app/libs/XposedBridgeApi.jar
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /home/fuzion24/bin/android_sdk_home/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/me/trust/just/justtrustme/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package me.trust.just.justtrustme;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
12 |
15 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/assets/xposed_init:
--------------------------------------------------------------------------------
1 | just.trust.me.Main
--------------------------------------------------------------------------------
/app/src/main/java/just/trust/me/Main.java:
--------------------------------------------------------------------------------
1 | package just.trust.me;
2 |
3 | import android.content.Context;
4 | import android.net.http.SslError;
5 | import android.util.Log;
6 | import android.webkit.SslErrorHandler;
7 | import android.webkit.WebView;
8 |
9 | import org.apache.http.conn.ClientConnectionManager;
10 | import org.apache.http.conn.scheme.HostNameResolver;
11 | import org.apache.http.conn.scheme.PlainSocketFactory;
12 | import org.apache.http.conn.scheme.Scheme;
13 | import org.apache.http.conn.scheme.SchemeRegistry;
14 | import org.apache.http.conn.ssl.SSLSocketFactory;
15 | import org.apache.http.impl.client.DefaultHttpClient;
16 | import org.apache.http.impl.conn.SingleClientConnManager;
17 | import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
18 | import org.apache.http.params.HttpParams;
19 |
20 | import java.io.IOException;
21 | import java.net.Socket;
22 | import java.net.UnknownHostException;
23 | import java.security.KeyManagementException;
24 | import java.security.KeyStore;
25 | import java.security.KeyStoreException;
26 | import java.security.NoSuchAlgorithmException;
27 | import java.security.SecureRandom;
28 | import java.security.UnrecoverableKeyException;
29 | import java.security.cert.CertificateException;
30 | import java.security.cert.X509Certificate;
31 | import java.util.ArrayList;
32 | import java.util.List;
33 |
34 | import javax.net.ssl.HostnameVerifier;
35 | import javax.net.ssl.KeyManager;
36 | import javax.net.ssl.SSLContext;
37 | import javax.net.ssl.SSLSession;
38 | import javax.net.ssl.TrustManager;
39 | import javax.net.ssl.X509TrustManager;
40 |
41 | import de.robv.android.xposed.IXposedHookLoadPackage;
42 | import de.robv.android.xposed.XC_MethodHook;
43 | import de.robv.android.xposed.XC_MethodReplacement;
44 | import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
45 |
46 | import static de.robv.android.xposed.XposedHelpers.callMethod;
47 | import static de.robv.android.xposed.XposedHelpers.callStaticMethod;
48 | import static de.robv.android.xposed.XposedHelpers.findAndHookConstructor;
49 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
50 | import static de.robv.android.xposed.XposedHelpers.findClass;
51 | import static de.robv.android.xposed.XposedHelpers.getObjectField;
52 | import static de.robv.android.xposed.XposedHelpers.newInstance;
53 | import static de.robv.android.xposed.XposedHelpers.setObjectField;
54 |
55 | public class Main implements IXposedHookLoadPackage {
56 |
57 | private static final String TAG = "JustTrustMe";
58 | String currentPackageName = "";
59 |
60 | public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
61 |
62 | currentPackageName = lpparam.packageName;
63 |
64 |
65 |
66 | /* Apache Hooks */
67 | /* external/apache-http/src/org/apache/http/impl/client/DefaultHttpClient.java */
68 | /* public DefaultHttpClient() */
69 |
70 | findAndHookConstructor(DefaultHttpClient.class, new XC_MethodHook() {
71 | @Override
72 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
73 | Log.d(TAG, "Hooking DefaultHTTPClient for: " + currentPackageName);
74 |
75 | setObjectField(param.thisObject, "defaultParams", null);
76 | setObjectField(param.thisObject, "connManager", getSCCM());
77 | }
78 | });
79 |
80 | /* external/apache-http/src/org/apache/http/impl/client/DefaultHttpClient.java */
81 | /* public DefaultHttpClient(HttpParams params) */
82 |
83 | findAndHookConstructor(DefaultHttpClient.class, HttpParams.class, new XC_MethodHook() {
84 | @Override
85 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
86 | Log.d(TAG, "Hooking DefaultHTTPClient(HttpParams) for: " + currentPackageName);
87 |
88 | setObjectField(param.thisObject, "defaultParams", (HttpParams) param.args[0]);
89 | setObjectField(param.thisObject, "connManager", getSCCM());
90 | }
91 | });
92 |
93 | /* external/apache-http/src/org/apache/http/impl/client/DefaultHttpClient.java */
94 | /* public DefaultHttpClient(ClientConnectionManager conman, HttpParams params) */
95 |
96 | findAndHookConstructor(DefaultHttpClient.class, ClientConnectionManager.class, HttpParams.class, new XC_MethodHook() {
97 | @Override
98 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
99 | Log.d(TAG, "Hooking DefaultHTTPClient(ClientConnectionManager, HttpParams) for: " + currentPackageName);
100 |
101 | HttpParams params = (HttpParams) param.args[1];
102 |
103 | setObjectField(param.thisObject, "defaultParams", params);
104 | setObjectField(param.thisObject, "connManager", getCCM(param.args[0], params));
105 | }
106 | });
107 |
108 | /* external/apache-http/src/org/apache/http/conn/ssl/SSLSocketFactory.java */
109 | /* public SSLSocketFactory( ... ) */
110 |
111 | findAndHookConstructor(SSLSocketFactory.class, String.class, KeyStore.class, String.class, KeyStore.class,
112 | SecureRandom.class, HostNameResolver.class, new XC_MethodHook() {
113 | @Override
114 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
115 | Log.d(TAG, "Hooking SSLSocketFactory(String, KeyStore, String, KeyStore) for: " + currentPackageName);
116 |
117 | String algorithm = (String) param.args[0];
118 | KeyStore keystore = (KeyStore) param.args[1];
119 | String keystorePassword = (String) param.args[2];
120 | SecureRandom random = (SecureRandom) param.args[4];
121 |
122 | KeyManager[] keymanagers = null;
123 | TrustManager[] trustmanagers = null;
124 |
125 | if (keystore != null) {
126 | keymanagers = (KeyManager[]) callStaticMethod(SSLSocketFactory.class, "createKeyManagers", keystore, keystorePassword);
127 | }
128 |
129 | trustmanagers = new TrustManager[]{new ImSureItsLegitTrustManager()};
130 |
131 | setObjectField(param.thisObject, "sslcontext", SSLContext.getInstance(algorithm));
132 | callMethod(getObjectField(param.thisObject, "sslcontext"), "init", keymanagers, trustmanagers, random);
133 | setObjectField(param.thisObject, "socketfactory",
134 | callMethod(getObjectField(param.thisObject, "sslcontext"), "getSocketFactory"));
135 | }
136 |
137 | });
138 |
139 |
140 | /* external/apache-http/src/org/apache/http/conn/ssl/SSLSocketFactory.java */
141 | /* public static SSLSocketFactory getSocketFactory() */
142 |
143 | findAndHookMethod("org.apache.http.conn.ssl.SSLSocketFactory", lpparam.classLoader, "getSocketFactory", new XC_MethodReplacement() {
144 | @Override
145 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
146 | Log.d(TAG, "Hooking static SSLSocketFactory(String, KeyStore, String, KeyStore) for: " + currentPackageName);
147 | return (SSLSocketFactory) newInstance(SSLSocketFactory.class);
148 | }
149 | });
150 |
151 | /* external/apache-http/src/org/apache/http/conn/ssl/SSLSocketFactory.java */
152 | /* public boolean isSecure(Socket) */
153 |
154 | findAndHookMethod("org.apache.http.conn.ssl.SSLSocketFactory", lpparam.classLoader, "isSecure", Socket.class, new XC_MethodReplacement() {
155 | @Override
156 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
157 | Log.d(TAG, "Hooking SSLSocketFactory(Socket) for: " + currentPackageName);
158 | return true;
159 | }
160 | });
161 |
162 | /* JSSE Hooks */
163 | /* libcore/luni/src/main/java/javax/net/ssl/TrustManagerFactory.java */
164 | /* public final TrustManager[] getTrustManager() */
165 |
166 | findAndHookMethod("javax.net.ssl.TrustManagerFactory", lpparam.classLoader, "getTrustManagers", new XC_MethodHook() {
167 | @Override
168 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
169 | Log.d(TAG, "Hooking TrustManagerFactory.getTrustManagers() for: " + currentPackageName);
170 |
171 | if (hasTrustManagerImpl()) {
172 | Class> cls = findClass("com.android.org.conscrypt.TrustManagerImpl", lpparam.classLoader);
173 |
174 | TrustManager[] managers = (TrustManager[]) param.getResult();
175 | if (managers.length > 0 && cls.isInstance(managers[0]))
176 | return;
177 | }
178 |
179 | param.setResult(new TrustManager[]{new ImSureItsLegitTrustManager()});
180 | }
181 | });
182 |
183 | /* libcore/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java */
184 | /* public void setDefaultHostnameVerifier(HostnameVerifier) */
185 |
186 | findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setDefaultHostnameVerifier",
187 | HostnameVerifier.class, new XC_MethodReplacement() {
188 | @Override
189 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
190 | Log.d(TAG, "Hooking HttpsURLConnection.setDefaultHostnameVerifier for: " + currentPackageName);
191 | return null;
192 | }
193 | });
194 |
195 | /* libcore/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java */
196 | /* public void setSSLSocketFactory(SSLSocketFactory) */
197 |
198 | findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setSSLSocketFactory", javax.net.ssl.SSLSocketFactory.class,
199 | new XC_MethodReplacement() {
200 | @Override
201 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
202 | Log.d(TAG, "Hooking HttpsURLConnection.setDefaultHostnameVerifier for: " + currentPackageName);
203 | return null;
204 | }
205 | });
206 |
207 | /* libcore/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java */
208 | /* public void setHostnameVerifier(HostNameVerifier) */
209 |
210 | findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setHostnameVerifier", HostnameVerifier.class,
211 | new XC_MethodReplacement() {
212 | @Override
213 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
214 | Log.d(TAG, "Hooking HttpsURLConnection.setHostnameVerifier for: " + currentPackageName);
215 | return null;
216 | }
217 | });
218 |
219 |
220 | /* WebView Hooks */
221 | /* frameworks/base/core/java/android/webkit/WebViewClient.java */
222 | /* public void onReceivedSslError(Webview, SslErrorHandler, SslError) */
223 |
224 |
225 | findAndHookMethod("android.webkit.WebViewClient", lpparam.classLoader, "onReceivedSslError",
226 | WebView.class, SslErrorHandler.class, SslError.class, new XC_MethodReplacement() {
227 | @Override
228 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
229 | Log.d(TAG, "Hooking WebViewClient.onReceivedSslError(WebView, SslErrorHandler, SslError) for: " + currentPackageName);
230 | ((android.webkit.SslErrorHandler) param.args[1]).proceed();
231 | return null;
232 | }
233 | });
234 |
235 | /* frameworks/base/core/java/android/webkit/WebViewClient.java */
236 | /* public void onReceivedError(WebView, int, String, String) */
237 |
238 |
239 | findAndHookMethod("android.webkit.WebViewClient", lpparam.classLoader, "onReceivedError",
240 | WebView.class, int.class, String.class, String.class, new XC_MethodReplacement() {
241 | @Override
242 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
243 | Log.d(TAG, "Hooking WebViewClient.onReceivedSslError(WebView, int, string, string) for: " + currentPackageName);
244 | return null;
245 | }
246 | });
247 |
248 | //SSLContext.init >> (null,ImSureItsLegitTrustManager,null)
249 | findAndHookMethod("javax.net.ssl.SSLContext", lpparam.classLoader, "init", KeyManager[].class, TrustManager[].class, SecureRandom.class, new XC_MethodHook() {
250 |
251 | @Override
252 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
253 | Log.d(TAG, "Hooking javax.net.ssl.SSLContext.init for: " + currentPackageName);
254 |
255 | param.args[0] = null;
256 | param.args[1] = new TrustManager[]{new ImSureItsLegitTrustManager()};
257 | param.args[2] = null;
258 |
259 | }
260 | });
261 |
262 | // Multi-dex support: https://github.com/rovo89/XposedBridge/issues/30#issuecomment-68486449
263 | findAndHookMethod("android.app.Application",
264 | lpparam.classLoader,
265 | "attach",
266 | Context.class,
267 | new XC_MethodHook() {
268 | @Override
269 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
270 | // Hook OkHttp or third party libraries.
271 | Context context = (Context) param.args[0];
272 | processOkHttp(context.getClassLoader());
273 | processHttpClientAndroidLib(context.getClassLoader());
274 | processXutils(context.getClassLoader());
275 | }
276 | }
277 | );
278 |
279 | /* Only for newer devices should we try to hook TrustManagerImpl */
280 | if (hasTrustManagerImpl()) {
281 | /* TrustManagerImpl Hooks */
282 | /* external/conscrypt/src/platform/java/org/conscrypt/TrustManagerImpl.java */
283 |
284 |
285 | /* public void checkServerTrusted(X509Certificate[] chain, String authType) */
286 | findAndHookMethod("com.android.org.conscrypt.TrustManagerImpl", lpparam.classLoader,
287 | "checkServerTrusted", X509Certificate[].class, String.class,
288 | new XC_MethodReplacement() {
289 | @Override
290 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
291 | Log.d(TAG, "Hooking com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(X509Certificate[] chain, String authType) for: " + currentPackageName);
292 | return 0;
293 | }
294 | });
295 |
296 | /* public List checkServerTrusted(X509Certificate[] chain,
297 | String authType, String host) throws CertificateException */
298 | findAndHookMethod("com.android.org.conscrypt.TrustManagerImpl", lpparam.classLoader,
299 | "checkServerTrusted", X509Certificate[].class, String.class,
300 | String.class, new XC_MethodReplacement() {
301 | @Override
302 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
303 | Log.d(TAG, "Hooking com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(X509Certificate[] chain, String authType, String host) for: " + currentPackageName);
304 | ArrayList list = new ArrayList();
305 | return list;
306 | }
307 | });
308 |
309 |
310 | /* public List checkServerTrusted(X509Certificate[] chain,
311 | String authType, SSLSession session) throws CertificateException */
312 | findAndHookMethod("com.android.org.conscrypt.TrustManagerImpl", lpparam.classLoader,
313 | "checkServerTrusted", X509Certificate[].class, String.class,
314 | SSLSession.class, new XC_MethodReplacement() {
315 | @Override
316 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
317 | Log.d(TAG, "Hooking com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(X509Certificate[] chain, String authType, SSLSession session) for: " + currentPackageName);
318 | ArrayList list = new ArrayList();
319 | return list;
320 | }
321 | });
322 | }
323 |
324 | } // End Hooks
325 |
326 | /* Helpers */
327 | // Check for TrustManagerImpl class
328 | public boolean hasTrustManagerImpl() {
329 |
330 | try {
331 | Class.forName("com.android.org.conscrypt.TrustManagerImpl");
332 | } catch (ClassNotFoundException e) {
333 | return false;
334 | }
335 | return true;
336 | }
337 |
338 | private javax.net.ssl.SSLSocketFactory getEmptySSLFactory() {
339 | try {
340 | SSLContext sslContext = SSLContext.getInstance("TLS");
341 | sslContext.init(null, new TrustManager[]{new ImSureItsLegitTrustManager()}, null);
342 | return sslContext.getSocketFactory();
343 | } catch (NoSuchAlgorithmException e) {
344 | return null;
345 | } catch (KeyManagementException e) {
346 | return null;
347 | }
348 | }
349 |
350 | //Create a SingleClientConnManager that trusts everyone!
351 | public ClientConnectionManager getSCCM() {
352 |
353 | KeyStore trustStore;
354 | try {
355 |
356 | trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
357 | trustStore.load(null, null);
358 |
359 | SSLSocketFactory sf = new TrustAllSSLSocketFactory(trustStore);
360 | sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
361 |
362 | SchemeRegistry registry = new SchemeRegistry();
363 | registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
364 | registry.register(new Scheme("https", sf, 443));
365 |
366 | ClientConnectionManager ccm = new SingleClientConnManager(null, registry);
367 |
368 | return ccm;
369 |
370 | } catch (Exception e) {
371 | return null;
372 | }
373 | }
374 |
375 | //This function creates a ThreadSafeClientConnManager that trusts everyone!
376 | public ClientConnectionManager getTSCCM(HttpParams params) {
377 |
378 | KeyStore trustStore;
379 | try {
380 |
381 | trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
382 | trustStore.load(null, null);
383 |
384 | SSLSocketFactory sf = new TrustAllSSLSocketFactory(trustStore);
385 | sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
386 |
387 | SchemeRegistry registry = new SchemeRegistry();
388 | registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
389 | registry.register(new Scheme("https", sf, 443));
390 |
391 | ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
392 |
393 | return ccm;
394 |
395 | } catch (Exception e) {
396 | return null;
397 | }
398 | }
399 |
400 | //This function determines what object we are dealing with.
401 | public ClientConnectionManager getCCM(Object o, HttpParams params) {
402 |
403 | String className = o.getClass().getSimpleName();
404 |
405 | if (className.equals("SingleClientConnManager")) {
406 | return getSCCM();
407 | } else if (className.equals("ThreadSafeClientConnManager")) {
408 | return getTSCCM(params);
409 | }
410 |
411 | return null;
412 | }
413 |
414 | private void processXutils(ClassLoader classLoader) {
415 |
416 | try {
417 | classLoader.loadClass("org.xutils.http.RequestParams");
418 | findAndHookMethod("org.xutils.http.RequestParams", classLoader, "setSslSocketFactory", javax.net.ssl.SSLSocketFactory.class, new XC_MethodHook() {
419 | @Override
420 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
421 | Log.d(TAG, "Hooking org.xutils.http.RequestParams.setSslSocketFactory(SSLSocketFactory) (3) for: " + currentPackageName);
422 | super.beforeHookedMethod(param);
423 | param.args[0] = getEmptySSLFactory();
424 | }
425 | });
426 | findAndHookMethod("org.xutils.http.RequestParams", classLoader, "setHostnameVerifier", HostnameVerifier.class, new XC_MethodHook() {
427 | @Override
428 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
429 | Log.d(TAG, "Hooking org.xutils.http.RequestParams.setHostnameVerifier for: " + currentPackageName);
430 | super.beforeHookedMethod(param);
431 | param.args[0] = new ImSureItsLegitHostnameVerifier();
432 | }
433 | });
434 | } catch (Exception e) {
435 | Log.d(TAG, "org.xutils.http.RequestParams not found in " + currentPackageName + "-- not hooking");
436 | }
437 | }
438 |
439 | void processOkHttp(ClassLoader classLoader) {
440 | /* hooking OKHTTP by SQUAREUP */
441 | /* com/squareup/okhttp/CertificatePinner.java available online @ https://github.com/square/okhttp/blob/master/okhttp/src/main/java/com/squareup/okhttp/CertificatePinner.java */
442 | /* public void check(String hostname, List peerCertificates) throws SSLPeerUnverifiedException{}*/
443 | /* Either returns true or a exception so blanket return true */
444 | /* Tested against version 2.5 */
445 |
446 |
447 | try {
448 | classLoader.loadClass("com.squareup.okhttp.CertificatePinner");
449 | findAndHookMethod("com.squareup.okhttp.CertificatePinner",
450 | classLoader,
451 | "check",
452 | String.class,
453 | List.class,
454 | new XC_MethodReplacement() {
455 | @Override
456 | protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
457 | Log.d(TAG, "Hooking com.squareup.okhttp.CertificatePinner.check(String,List) (2.5) for: " + currentPackageName);
458 | return true;
459 | }
460 | });
461 | } catch (ClassNotFoundException e) {
462 | // pass
463 | Log.d(TAG, "OKHTTP 2.5 not found in " + currentPackageName + "-- not hooking");
464 | }
465 |
466 | //https://github.com/square/okhttp/blob/parent-3.0.1/okhttp/src/main/java/okhttp3/CertificatePinner.java#L144
467 |
468 |
469 | try {
470 | classLoader.loadClass("okhttp3.CertificatePinner");
471 | findAndHookMethod("okhttp3.CertificatePinner",
472 | classLoader,
473 | "check",
474 | String.class,
475 | List.class,
476 | new XC_MethodReplacement() {
477 | @Override
478 | protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
479 | Log.d(TAG, "Hooking okhttp3.CertificatePinner.check(String,List) (3.x) for: " + currentPackageName);
480 | return null;
481 | }
482 | });
483 | } catch (ClassNotFoundException e) {
484 | Log.d(TAG, "OKHTTP 3.x not found in " + currentPackageName + " -- not hooking");
485 | // pass
486 | }
487 |
488 | //https://github.com/square/okhttp/blob/parent-3.0.1/okhttp/src/main/java/okhttp3/internal/tls/OkHostnameVerifier.java
489 | try {
490 | classLoader.loadClass("okhttp3.internal.tls.OkHostnameVerifier");
491 | findAndHookMethod("okhttp3.internal.tls.OkHostnameVerifier",
492 | classLoader,
493 | "verify",
494 | String.class,
495 | javax.net.ssl.SSLSession.class,
496 | new XC_MethodReplacement() {
497 | @Override
498 | protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
499 | Log.d(TAG, "Hooking okhttp3.internal.tls.OkHostnameVerifier.verify(String, SSLSession) for: " + currentPackageName);
500 | return true;
501 | }
502 | });
503 | } catch (ClassNotFoundException e) {
504 | Log.d(TAG, "OKHTTP 3.x not found in " + currentPackageName + " -- not hooking OkHostnameVerifier.verify(String, SSLSession)");
505 | // pass
506 | }
507 |
508 | //https://github.com/square/okhttp/blob/parent-3.0.1/okhttp/src/main/java/okhttp3/internal/tls/OkHostnameVerifier.java
509 | try {
510 | classLoader.loadClass("okhttp3.internal.tls.OkHostnameVerifier");
511 | findAndHookMethod("okhttp3.internal.tls.OkHostnameVerifier",
512 | classLoader,
513 | "verify",
514 | String.class,
515 | java.security.cert.X509Certificate.class,
516 | new XC_MethodReplacement() {
517 | @Override
518 | protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
519 | Log.d(TAG, "Hooking okhttp3.internal.tls.OkHostnameVerifier.verify(String, X509) for: " + currentPackageName);
520 | return true;
521 | }
522 | });
523 | } catch (ClassNotFoundException e) {
524 | Log.d(TAG, "OKHTTP 3.x not found in " + currentPackageName + " -- not hooking OkHostnameVerifier.verify(String, X509)(");
525 | // pass
526 | }
527 | }
528 |
529 | void processHttpClientAndroidLib(ClassLoader classLoader) {
530 | /* httpclientandroidlib Hooks */
531 | /* public final void verify(String host, String[] cns, String[] subjectAlts, boolean strictWithSubDomains) throws SSLException */
532 |
533 |
534 | try {
535 | classLoader.loadClass("ch.boye.httpclientandroidlib.conn.ssl.AbstractVerifier");
536 | findAndHookMethod("ch.boye.httpclientandroidlib.conn.ssl.AbstractVerifier", classLoader, "verify",
537 | String.class, String[].class, String[].class, boolean.class,
538 | new XC_MethodReplacement() {
539 | @Override
540 | protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
541 | Log.d(TAG, "Hooking AbstractVerifier.verify(String, String[], String[], boolean) for: " + currentPackageName);
542 | return null;
543 | }
544 | });
545 | } catch (ClassNotFoundException e) {
546 | // pass
547 | Log.d(TAG, "httpclientandroidlib not found in " + currentPackageName + "-- not hooking");
548 | }
549 | }
550 |
551 | private class ImSureItsLegitTrustManager implements X509TrustManager {
552 | @Override
553 | public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
554 | }
555 |
556 | @Override
557 | public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
558 | }
559 |
560 | @Override
561 | public X509Certificate[] getAcceptedIssuers() {
562 | return new X509Certificate[0];
563 | }
564 | }
565 |
566 | private class ImSureItsLegitHostnameVerifier implements HostnameVerifier {
567 |
568 | @Override
569 | public boolean verify(String hostname, SSLSession session) {
570 | return true;
571 | }
572 | }
573 |
574 | /* This class creates a SSLSocket that trusts everyone. */
575 | public class TrustAllSSLSocketFactory extends SSLSocketFactory {
576 |
577 | SSLContext sslContext = SSLContext.getInstance("TLS");
578 |
579 | public TrustAllSSLSocketFactory(KeyStore truststore) throws
580 | NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
581 | super(truststore);
582 |
583 | TrustManager tm = new X509TrustManager() {
584 |
585 | public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
586 | }
587 |
588 | public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
589 | }
590 |
591 | public X509Certificate[] getAcceptedIssuers() {
592 | return null;
593 | }
594 | };
595 |
596 | sslContext.init(null, new TrustManager[]{tm}, null);
597 | }
598 |
599 | @Override
600 | public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
601 | return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
602 | }
603 |
604 | @Override
605 | public Socket createSocket() throws IOException {
606 | return sslContext.getSocketFactory().createSocket();
607 | }
608 | }
609 | }
610 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | JustTrustMe
5 | Hello world!
6 | Settings
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.3.3'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | APK_PATH="bin/JustTrustMe.apk"
2 | ./gradlew assembleRelease && cp app/build/outputs/apk/app-release-unsigned.apk $APK_PATH && signapk $APK_PATH
3 |
4 | #adb install -r bin/AndroidVTS.apk
5 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | ## Project-wide Gradle settings.
2 | #
3 | # For more details on how to configure your build environment visit
4 | # http://www.gradle.org/docs/current/userguide/build_environment.html
5 | #
6 | # Specifies the JVM arguments used for the daemon process.
7 | # The setting is particularly useful for tweaking memory settings.
8 | # Default value: -Xmx1024m -XX:MaxPermSize=256m
9 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
10 | #
11 | # When configured, Gradle will run in incubating parallel mode.
12 | # This option should only be used with decoupled projects. More details, visit
13 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
14 | # org.gradle.parallel=true
15 | #Mon Jun 26 14:34:35 CST 2017
16 | systemProp.http.proxyHost=127.0.0.1
17 | systemProp.http.proxyPort=1080
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/la0s/JustTrustMe-master/d0072cf6f1ccae0c7dec020840c1e46c84bfb0e3/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat Apr 08 16:14:51 PDT 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------