├── .gitignore
├── License.md
├── 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
/.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 |
--------------------------------------------------------------------------------
/License.md:
--------------------------------------------------------------------------------
1 | Copyright [ 2019 ] [ Ryan Welton ]
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | JustTrustMe
2 | ===========
3 |
4 | An xposed module that disables SSL certificate checking. This is useful for auditing an application which does certificate pinning. There also exists a nice framework built by @moxie to aid in pinning certs in your app: [certificate pinning](https://github.com/moxie0/AndroidPinning).
5 |
6 | An example of an application that does cert pinning is [Twitter](https://play.google.com/store/apps/details?id=com.twitter.android). If you would like to view the network traffic for this application, you must disable the certificate pinning.
7 |
8 | I built this for xposed rather than cydia substrate because xposed seems to support newer devices better. Marc Blanchou wrote the [original tool](https://github.com/iSECPartners/Android-SSL-TrustKiller) for cydia substrate. If you find that you are not able to MITM an application please file an issue.
9 |
10 | ## Installation
11 |
12 | As a prequsite, your device must be rooted and the xposed framework must be installed.
13 | You can download the xposed framework [here](http://repo.xposed.info/module/de.robv.android.xposed.installer).
14 |
15 | ### Install from binary
16 |
17 | The JustTrustMe binary can be downloaded from [https://github.com/Fuzion24/JustTrustMe/releases/latest](https://github.com/Fuzion24/JustTrustMe/releases/latest)
18 |
19 | ```
20 | adb install ./JustTrustMe.apk
21 | ```
22 |
23 | or navigate here and download the APK on your phone:
24 | [https://github.com/Fuzion24/JustTrustMe/releases/latest](https://github.com/Fuzion24/JustTrustMe/releases/latest)
25 |
26 |
27 | ### Build from Source
28 | All the normal gradle build commands apply:
29 | To build a release APK:
30 | ```
31 | ./gradlew assembleRelease
32 | ```
33 | To install directly to the phone connected via ADB:
34 | ```
35 | ./gradlew installRelease
36 | ```
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 30
5 | defaultConfig {
6 | applicationId 'just.trust.me'
7 | minSdkVersion 16
8 | targetSdkVersion 30
9 | versionCode 3
10 | versionName '.3'
11 | }
12 |
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | }
17 | }
18 | productFlavors {
19 | }
20 | useLibrary 'org.apache.http.legacy'
21 | }
22 |
23 | dependencies {
24 | compileOnly fileTree(dir: 'libs', include: ['*.jar'])
25 | implementation 'org.apache.httpcomponents:httpcore:4.4.2'
26 | }
27 |
--------------------------------------------------------------------------------
/app/libs/XposedBridgeApi.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TrackerControl/JustTrustMe/78a4fd50842fca908e63cf34a1e9565ceea25ba3/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.net.http.X509TrustManagerExtensions;
6 | import android.util.Log;
7 | import android.webkit.SslErrorHandler;
8 | import android.webkit.WebView;
9 |
10 | import org.apache.http.conn.ClientConnectionManager;
11 | import org.apache.http.conn.scheme.HostNameResolver;
12 | import org.apache.http.conn.scheme.PlainSocketFactory;
13 | import org.apache.http.conn.scheme.Scheme;
14 | import org.apache.http.conn.scheme.SchemeRegistry;
15 | import org.apache.http.conn.ssl.SSLSocketFactory;
16 | import org.apache.http.impl.client.DefaultHttpClient;
17 | import org.apache.http.impl.conn.SingleClientConnManager;
18 | import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
19 | import org.apache.http.params.HttpParams;
20 |
21 | import java.io.IOException;
22 | import java.net.Socket;
23 | import java.net.UnknownHostException;
24 | import java.security.KeyManagementException;
25 | import java.security.KeyStore;
26 | import java.security.KeyStoreException;
27 | import java.security.NoSuchAlgorithmException;
28 | import java.security.SecureRandom;
29 | import java.security.UnrecoverableKeyException;
30 | import java.security.cert.CertificateException;
31 | import java.security.cert.X509Certificate;
32 | import java.util.ArrayList;
33 | import java.util.List;
34 |
35 | import javax.net.ssl.HostnameVerifier;
36 | import javax.net.ssl.KeyManager;
37 | import javax.net.ssl.SSLContext;
38 | import javax.net.ssl.SSLParameters;
39 | import javax.net.ssl.SSLSession;
40 | import javax.net.ssl.TrustManager;
41 | import javax.net.ssl.X509TrustManager;
42 |
43 | import de.robv.android.xposed.IXposedHookLoadPackage;
44 | import de.robv.android.xposed.XC_MethodHook;
45 | import de.robv.android.xposed.XC_MethodReplacement;
46 | import de.robv.android.xposed.XposedHelpers;
47 | import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
48 |
49 | import static de.robv.android.xposed.XC_MethodReplacement.DO_NOTHING;
50 | import static de.robv.android.xposed.XposedHelpers.callMethod;
51 | import static de.robv.android.xposed.XposedHelpers.callStaticMethod;
52 | import static de.robv.android.xposed.XposedHelpers.findAndHookConstructor;
53 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
54 | import static de.robv.android.xposed.XposedHelpers.findClass;
55 | import static de.robv.android.xposed.XposedHelpers.getObjectField;
56 | import static de.robv.android.xposed.XposedHelpers.newInstance;
57 | import static de.robv.android.xposed.XposedHelpers.setObjectField;
58 |
59 | public class Main implements IXposedHookLoadPackage {
60 |
61 | private static final String TAG = "JustTrustMe";
62 | String currentPackageName = "";
63 |
64 | public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
65 |
66 | currentPackageName = lpparam.packageName;
67 |
68 |
69 |
70 | /* Apache Hooks */
71 | /* external/apache-http/src/org/apache/http/impl/client/DefaultHttpClient.java */
72 | /* public DefaultHttpClient() */
73 | if (hasDefaultHTTPClient()) {
74 | Log.d(TAG, "Hooking DefaultHTTPClient for: " + currentPackageName);
75 | findAndHookConstructor(DefaultHttpClient.class, new XC_MethodHook() {
76 | @Override
77 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
78 |
79 | setObjectField(param.thisObject, "defaultParams", null);
80 | setObjectField(param.thisObject, "connManager", getSCCM());
81 | }
82 | });
83 |
84 | /* external/apache-http/src/org/apache/http/impl/client/DefaultHttpClient.java */
85 | /* public DefaultHttpClient(HttpParams params) */
86 | Log.d(TAG, "Hooking DefaultHTTPClient(HttpParams) for: " + currentPackageName);
87 | findAndHookConstructor(DefaultHttpClient.class, HttpParams.class, new XC_MethodHook() {
88 | @Override
89 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
90 |
91 | setObjectField(param.thisObject, "defaultParams", (HttpParams) param.args[0]);
92 | setObjectField(param.thisObject, "connManager", getSCCM());
93 | }
94 | });
95 |
96 | /* external/apache-http/src/org/apache/http/impl/client/DefaultHttpClient.java */
97 | /* public DefaultHttpClient(ClientConnectionManager conman, HttpParams params) */
98 | Log.d(TAG, "Hooking DefaultHTTPClient(ClientConnectionManager, HttpParams) for: " + currentPackageName);
99 | findAndHookConstructor(DefaultHttpClient.class, ClientConnectionManager.class, HttpParams.class, new XC_MethodHook() {
100 | @Override
101 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
102 |
103 | HttpParams params = (HttpParams) param.args[1];
104 |
105 | setObjectField(param.thisObject, "defaultParams", params);
106 | setObjectField(param.thisObject, "connManager", getCCM(param.args[0], params));
107 | }
108 | });
109 | }
110 |
111 | findAndHookMethod(X509TrustManagerExtensions.class, "checkServerTrusted", X509Certificate[].class, String.class, String.class, new XC_MethodReplacement() {
112 | @Override
113 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
114 | return param.args[0];
115 | }
116 | });
117 |
118 | findAndHookMethod("android.security.net.config.NetworkSecurityTrustManager", lpparam.classLoader, "checkPins", List.class, DO_NOTHING);
119 |
120 | /* external/apache-http/src/org/apache/http/conn/ssl/SSLSocketFactory.java */
121 | /* public SSLSocketFactory( ... ) */
122 | try {
123 | Log.d(TAG, "Hooking SSLSocketFactory(String, KeyStore, String, KeyStore) for: " + currentPackageName);
124 | findAndHookConstructor(SSLSocketFactory.class, String.class, KeyStore.class, String.class, KeyStore.class,
125 | SecureRandom.class, HostNameResolver.class, new XC_MethodHook() {
126 | @Override
127 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
128 |
129 | String algorithm = (String) param.args[0];
130 | KeyStore keystore = (KeyStore) param.args[1];
131 | String keystorePassword = (String) param.args[2];
132 | SecureRandom random = (SecureRandom) param.args[4];
133 |
134 | KeyManager[] keymanagers = null;
135 | TrustManager[] trustmanagers = null;
136 |
137 | if (keystore != null) {
138 | keymanagers = (KeyManager[]) callStaticMethod(SSLSocketFactory.class, "createKeyManagers", keystore, keystorePassword);
139 | }
140 |
141 | trustmanagers = new TrustManager[]{new ImSureItsLegitTrustManager()};
142 |
143 | setObjectField(param.thisObject, "sslcontext", SSLContext.getInstance(algorithm));
144 | callMethod(getObjectField(param.thisObject, "sslcontext"), "init", keymanagers, trustmanagers, random);
145 | setObjectField(param.thisObject, "socketfactory",
146 | callMethod(getObjectField(param.thisObject, "sslcontext"), "getSocketFactory"));
147 | }
148 |
149 | });
150 |
151 |
152 | /* external/apache-http/src/org/apache/http/conn/ssl/SSLSocketFactory.java */
153 | /* public static SSLSocketFactory getSocketFactory() */
154 | Log.d(TAG, "Hooking static SSLSocketFactory(String, KeyStore, String, KeyStore) for: " + currentPackageName);
155 | findAndHookMethod("org.apache.http.conn.ssl.SSLSocketFactory", lpparam.classLoader, "getSocketFactory", new XC_MethodReplacement() {
156 | @Override
157 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
158 | return (SSLSocketFactory) newInstance(SSLSocketFactory.class);
159 | }
160 | });
161 | } catch (NoClassDefFoundError e) {
162 | Log.d(TAG, "NoClassDefFoundError SSLSocketFactory HostNameResolver for: " + currentPackageName);
163 | }
164 |
165 | /* external/apache-http/src/org/apache/http/conn/ssl/SSLSocketFactory.java */
166 | /* public boolean isSecure(Socket) */
167 | Log.d(TAG, "Hooking SSLSocketFactory(Socket) for: " + currentPackageName);
168 | findAndHookMethod("org.apache.http.conn.ssl.SSLSocketFactory", lpparam.classLoader, "isSecure", Socket.class, DO_NOTHING);
169 |
170 | /* JSSE Hooks */
171 | /* libcore/luni/src/main/java/javax/net/ssl/TrustManagerFactory.java */
172 | /* public final TrustManager[] getTrustManager() */
173 | Log.d(TAG, "Hooking TrustManagerFactory.getTrustManagers() for: " + currentPackageName);
174 | findAndHookMethod("javax.net.ssl.TrustManagerFactory", lpparam.classLoader, "getTrustManagers", new XC_MethodHook() {
175 | @Override
176 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
177 |
178 | if (hasTrustManagerImpl()) {
179 | Class> cls = findClass("com.android.org.conscrypt.TrustManagerImpl", lpparam.classLoader);
180 |
181 | TrustManager[] managers = (TrustManager[]) param.getResult();
182 | if (managers.length > 0 && cls.isInstance(managers[0]))
183 | return;
184 | }
185 |
186 | param.setResult(new TrustManager[]{new ImSureItsLegitTrustManager()});
187 | }
188 | });
189 |
190 | /* libcore/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java */
191 | /* public void setDefaultHostnameVerifier(HostnameVerifier) */
192 | Log.d(TAG, "Hooking HttpsURLConnection.setDefaultHostnameVerifier for: " + currentPackageName);
193 | findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setDefaultHostnameVerifier",
194 | HostnameVerifier.class, DO_NOTHING);
195 |
196 | /* libcore/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java */
197 | /* public void setSSLSocketFactory(SSLSocketFactory) */
198 | Log.d(TAG, "Hooking HttpsURLConnection.setSSLSocketFactory for: " + currentPackageName);
199 | findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setSSLSocketFactory", javax.net.ssl.SSLSocketFactory.class, DO_NOTHING);
200 |
201 | /* libcore/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java */
202 | /* public void setHostnameVerifier(HostNameVerifier) */
203 | Log.d(TAG, "Hooking HttpsURLConnection.setHostnameVerifier for: " + currentPackageName);
204 | findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setHostnameVerifier", HostnameVerifier.class, DO_NOTHING);
205 |
206 |
207 | /* WebView Hooks */
208 | /* frameworks/base/core/java/android/webkit/WebViewClient.java */
209 | /* public void onReceivedSslError(Webview, SslErrorHandler, SslError) */
210 | Log.d(TAG, "Hooking WebViewClient.onReceivedSslError(WebView, SslErrorHandler, SslError) for: " + currentPackageName);
211 |
212 | findAndHookMethod("android.webkit.WebViewClient", lpparam.classLoader, "onReceivedSslError",
213 | WebView.class, SslErrorHandler.class, SslError.class, new XC_MethodReplacement() {
214 | @Override
215 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
216 | ((android.webkit.SslErrorHandler) param.args[1]).proceed();
217 | return null;
218 | }
219 | });
220 |
221 | /* frameworks/base/core/java/android/webkit/WebViewClient.java */
222 | /* public void onReceivedError(WebView, int, String, String) */
223 | Log.d(TAG, "Hooking WebViewClient.onReceivedSslError(WebView, int, string, string) for: " + currentPackageName);
224 |
225 | findAndHookMethod("android.webkit.WebViewClient", lpparam.classLoader, "onReceivedError",
226 | WebView.class, int.class, String.class, String.class, DO_NOTHING);
227 |
228 | //SSLContext.init >> (null,ImSureItsLegitTrustManager,null)
229 | findAndHookMethod("javax.net.ssl.SSLContext", lpparam.classLoader, "init", KeyManager[].class, TrustManager[].class, SecureRandom.class, new XC_MethodHook() {
230 |
231 | @Override
232 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
233 |
234 | param.args[0] = null;
235 | param.args[1] = new TrustManager[]{new ImSureItsLegitTrustManager()};
236 | param.args[2] = null;
237 |
238 | }
239 | });
240 |
241 | // Multi-dex support: https://github.com/rovo89/XposedBridge/issues/30#issuecomment-68486449
242 | findAndHookMethod("android.app.Application",
243 | lpparam.classLoader,
244 | "attach",
245 | Context.class,
246 | new XC_MethodHook() {
247 | @Override
248 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
249 | // Hook OkHttp or third party libraries.
250 | Context context = (Context) param.args[0];
251 | processOkHttp(context.getClassLoader());
252 | processHttpClientAndroidLib(context.getClassLoader());
253 | processXutils(context.getClassLoader());
254 | }
255 | }
256 | );
257 |
258 | /* Only for newer devices should we try to hook TrustManagerImpl */
259 | if (hasTrustManagerImpl()) {
260 | /* TrustManagerImpl Hooks */
261 | /* external/conscrypt/src/platform/java/org/conscrypt/TrustManagerImpl.java */
262 | Log.d(TAG, "Hooking com.android.org.conscrypt.TrustManagerImpl for: " + currentPackageName);
263 |
264 | /* public void checkServerTrusted(X509Certificate[] chain, String authType) */
265 | findAndHookMethod("com.android.org.conscrypt.TrustManagerImpl", lpparam.classLoader,
266 | "checkServerTrusted", X509Certificate[].class, String.class,
267 | new XC_MethodReplacement() {
268 | @Override
269 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
270 | return 0;
271 | }
272 | });
273 |
274 | /* public List checkServerTrusted(X509Certificate[] chain,
275 | String authType, String host) throws CertificateException */
276 | findAndHookMethod("com.android.org.conscrypt.TrustManagerImpl", lpparam.classLoader,
277 | "checkServerTrusted", X509Certificate[].class, String.class,
278 | String.class, new XC_MethodReplacement() {
279 | @Override
280 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
281 | ArrayList list = new ArrayList();
282 | return list;
283 | }
284 | });
285 |
286 |
287 | /* public List checkServerTrusted(X509Certificate[] chain,
288 | String authType, SSLSession session) throws CertificateException */
289 | findAndHookMethod("com.android.org.conscrypt.TrustManagerImpl", lpparam.classLoader,
290 | "checkServerTrusted", X509Certificate[].class, String.class,
291 | SSLSession.class, new XC_MethodReplacement() {
292 | @Override
293 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
294 | ArrayList list = new ArrayList();
295 | return list;
296 | }
297 | });
298 |
299 | try {
300 | findAndHookMethod("com.android.org.conscrypt.TrustManagerImpl", lpparam.classLoader, "checkTrusted", X509Certificate[].class, String.class, SSLSession.class, SSLParameters.class, boolean.class, new XC_MethodReplacement() {
301 | @Override
302 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
303 | ArrayList list = new ArrayList();
304 | return list;
305 | }
306 | });
307 |
308 |
309 | findAndHookMethod("com.android.org.conscrypt.TrustManagerImpl", lpparam.classLoader, "checkTrusted", X509Certificate[].class, byte[].class, byte[].class, String.class, String.class, boolean.class, new XC_MethodReplacement() {
310 | @Override
311 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
312 | ArrayList list = new ArrayList();
313 | return list;
314 | }
315 | });
316 | } catch (NoSuchMethodError e) {
317 |
318 | }
319 |
320 | }
321 |
322 | } // End Hooks
323 |
324 | /* Helpers */
325 | // Check for TrustManagerImpl class
326 | public boolean hasTrustManagerImpl() {
327 |
328 | try {
329 | Class.forName("com.android.org.conscrypt.TrustManagerImpl");
330 | } catch (ClassNotFoundException e) {
331 | return false;
332 | }
333 | return true;
334 | }
335 |
336 | public boolean hasDefaultHTTPClient() {
337 | try {
338 | Class.forName("org.apache.http.impl.client.DefaultHttpClient");
339 | } catch (ClassNotFoundException e) {
340 | return false;
341 | }
342 | return true;
343 | }
344 |
345 | private javax.net.ssl.SSLSocketFactory getEmptySSLFactory() {
346 | try {
347 | SSLContext sslContext = SSLContext.getInstance("TLS");
348 | sslContext.init(null, new TrustManager[]{new ImSureItsLegitTrustManager()}, null);
349 | return sslContext.getSocketFactory();
350 | } catch (NoSuchAlgorithmException | KeyManagementException e) {
351 | return null;
352 | }
353 | }
354 |
355 | //Create a SingleClientConnManager that trusts everyone!
356 | public ClientConnectionManager getSCCM() {
357 |
358 | KeyStore trustStore;
359 | try {
360 |
361 | trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
362 | trustStore.load(null, null);
363 |
364 | SSLSocketFactory sf = new TrustAllSSLSocketFactory(trustStore);
365 | sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
366 |
367 | SchemeRegistry registry = new SchemeRegistry();
368 | registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
369 | registry.register(new Scheme("https", sf, 443));
370 |
371 | ClientConnectionManager ccm = new SingleClientConnManager(null, registry);
372 |
373 | return ccm;
374 |
375 | } catch (Exception e) {
376 | return null;
377 | }
378 | }
379 |
380 | //This function creates a ThreadSafeClientConnManager that trusts everyone!
381 | public ClientConnectionManager getTSCCM(HttpParams params) {
382 |
383 | KeyStore trustStore;
384 | try {
385 |
386 | trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
387 | trustStore.load(null, null);
388 |
389 | SSLSocketFactory sf = new TrustAllSSLSocketFactory(trustStore);
390 | sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
391 |
392 | SchemeRegistry registry = new SchemeRegistry();
393 | registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
394 | registry.register(new Scheme("https", sf, 443));
395 |
396 | ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
397 |
398 | return ccm;
399 |
400 | } catch (Exception e) {
401 | return null;
402 | }
403 | }
404 |
405 | //This function determines what object we are dealing with.
406 | public ClientConnectionManager getCCM(Object o, HttpParams params) {
407 |
408 | String className = o.getClass().getSimpleName();
409 |
410 | if (className.equals("SingleClientConnManager")) {
411 | return getSCCM();
412 | } else if (className.equals("ThreadSafeClientConnManager")) {
413 | return getTSCCM(params);
414 | }
415 |
416 | return null;
417 | }
418 |
419 | private void processXutils(ClassLoader classLoader) {
420 | Log.d(TAG, "Hooking org.xutils.http.RequestParams.setSslSocketFactory(SSLSocketFactory) (3) for: " + currentPackageName);
421 | try {
422 | classLoader.loadClass("org.xutils.http.RequestParams");
423 | findAndHookMethod("org.xutils.http.RequestParams", classLoader, "setSslSocketFactory", javax.net.ssl.SSLSocketFactory.class, new XC_MethodHook() {
424 | @Override
425 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
426 | super.beforeHookedMethod(param);
427 | param.args[0] = getEmptySSLFactory();
428 | }
429 | });
430 | findAndHookMethod("org.xutils.http.RequestParams", classLoader, "setHostnameVerifier", HostnameVerifier.class, new XC_MethodHook() {
431 | @Override
432 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
433 | super.beforeHookedMethod(param);
434 | param.args[0] = new ImSureItsLegitHostnameVerifier();
435 | }
436 | });
437 | } catch (Exception e) {
438 | Log.d(TAG, "org.xutils.http.RequestParams not found in " + currentPackageName + "-- not hooking");
439 | }
440 | }
441 |
442 | void processOkHttp(ClassLoader classLoader) {
443 | /* hooking OKHTTP by SQUAREUP */
444 | /* com/squareup/okhttp/CertificatePinner.java available online @ https://github.com/square/okhttp/blob/master/okhttp/src/main/java/com/squareup/okhttp/CertificatePinner.java */
445 | /* public void check(String hostname, List peerCertificates) throws SSLPeerUnverifiedException{}*/
446 | /* Either returns true or a exception so blanket return true */
447 | /* Tested against version 2.5 */
448 | Log.d(TAG, "Hooking com.squareup.okhttp.CertificatePinner.check(String,List) (2.5) for: " + currentPackageName);
449 |
450 | try {
451 | classLoader.loadClass("com.squareup.okhttp.CertificatePinner");
452 | findAndHookMethod("com.squareup.okhttp.CertificatePinner",
453 | classLoader,
454 | "check",
455 | String.class,
456 | List.class,
457 | new XC_MethodReplacement() {
458 | @Override
459 | protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
460 | return true;
461 | }
462 | });
463 | } catch (ClassNotFoundException e) {
464 | // pass
465 | Log.d(TAG, "OKHTTP 2.5 not found in " + currentPackageName + "-- not hooking");
466 | }
467 |
468 | //https://github.com/square/okhttp/blob/parent-3.0.1/okhttp/src/main/java/okhttp3/CertificatePinner.java#L144
469 | Log.d(TAG, "Hooking okhttp3.CertificatePinner.check(String,List) (3.x) for: " + currentPackageName);
470 |
471 | try {
472 | classLoader.loadClass("okhttp3.CertificatePinner");
473 | findAndHookMethod("okhttp3.CertificatePinner",
474 | classLoader,
475 | "check",
476 | String.class,
477 | List.class,
478 | DO_NOTHING);
479 | } catch (ClassNotFoundException e) {
480 | Log.d(TAG, "OKHTTP 3.x not found in " + currentPackageName + " -- not hooking");
481 | // pass
482 | }
483 |
484 | //https://github.com/square/okhttp/blob/parent-3.0.1/okhttp/src/main/java/okhttp3/internal/tls/OkHostnameVerifier.java
485 | try {
486 | classLoader.loadClass("okhttp3.internal.tls.OkHostnameVerifier");
487 | findAndHookMethod("okhttp3.internal.tls.OkHostnameVerifier",
488 | classLoader,
489 | "verify",
490 | String.class,
491 | javax.net.ssl.SSLSession.class,
492 | new XC_MethodReplacement() {
493 | @Override
494 | protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
495 | return true;
496 | }
497 | });
498 | } catch (ClassNotFoundException e) {
499 | Log.d(TAG, "OKHTTP 3.x not found in " + currentPackageName + " -- not hooking OkHostnameVerifier.verify(String, SSLSession)");
500 | // pass
501 | }
502 |
503 | //https://github.com/square/okhttp/blob/parent-3.0.1/okhttp/src/main/java/okhttp3/internal/tls/OkHostnameVerifier.java
504 | try {
505 | classLoader.loadClass("okhttp3.internal.tls.OkHostnameVerifier");
506 | findAndHookMethod("okhttp3.internal.tls.OkHostnameVerifier",
507 | classLoader,
508 | "verify",
509 | String.class,
510 | java.security.cert.X509Certificate.class,
511 | new XC_MethodReplacement() {
512 | @Override
513 | protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
514 | return true;
515 | }
516 | });
517 | } catch (ClassNotFoundException e) {
518 | Log.d(TAG, "OKHTTP 3.x not found in " + currentPackageName + " -- not hooking OkHostnameVerifier.verify(String, X509)(");
519 | // pass
520 | }
521 |
522 | //https://github.com/square/okhttp/blob/okhttp_4.2.x/okhttp/src/main/java/okhttp3/CertificatePinner.kt
523 | Log.d(TAG, "Hooking okhttp3.CertificatePinner.check(String,List) (4.2.0+) for: " + currentPackageName);
524 |
525 | try {
526 | classLoader.loadClass("okhttp3.CertificatePinner");
527 | findAndHookMethod("okhttp3.CertificatePinner",
528 | classLoader,
529 | "check$okhttp",
530 | String.class,
531 | "kotlin.jvm.functions.Function0",
532 | DO_NOTHING);
533 | } catch (XposedHelpers.ClassNotFoundError | ClassNotFoundException | NoSuchMethodError e) {
534 | Log.d(TAG, "OKHTTP 4.2.0+ (check$okhttp) not found in " + currentPackageName + " -- not hooking");
535 | // pass
536 | }
537 |
538 | try {
539 | classLoader.loadClass("okhttp3.CertificatePinner");
540 | findAndHookMethod("okhttp3.CertificatePinner",
541 | classLoader,
542 | "check",
543 | String.class,
544 | List.class,
545 | DO_NOTHING);
546 | } catch (XposedHelpers.ClassNotFoundError | ClassNotFoundException | NoSuchMethodError e) {
547 | Log.d(TAG, "OKHTTP 4.2.0+ (check) not found in " + currentPackageName + " -- not hooking");
548 | // pass
549 | }
550 |
551 | }
552 |
553 | void processHttpClientAndroidLib(ClassLoader classLoader) {
554 | /* httpclientandroidlib Hooks */
555 | /* public final void verify(String host, String[] cns, String[] subjectAlts, boolean strictWithSubDomains) throws SSLException */
556 | Log.d(TAG, "Hooking AbstractVerifier.verify(String, String[], String[], boolean) for: " + currentPackageName);
557 |
558 | try {
559 | classLoader.loadClass("ch.boye.httpclientandroidlib.conn.ssl.AbstractVerifier");
560 | findAndHookMethod("ch.boye.httpclientandroidlib.conn.ssl.AbstractVerifier", classLoader, "verify",
561 | String.class, String[].class, String[].class, boolean.class,
562 | DO_NOTHING);
563 | } catch (ClassNotFoundException e) {
564 | // pass
565 | Log.d(TAG, "httpclientandroidlib not found in " + currentPackageName + "-- not hooking");
566 | }
567 | }
568 |
569 | private class ImSureItsLegitTrustManager implements X509TrustManager {
570 | @Override
571 | public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
572 | }
573 |
574 | @Override
575 | public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
576 | }
577 |
578 | public List checkServerTrusted(X509Certificate[] chain, String authType, String host) throws CertificateException {
579 | ArrayList list = new ArrayList();
580 | return list;
581 | }
582 |
583 | @Override
584 | public X509Certificate[] getAcceptedIssuers() {
585 | return new X509Certificate[0];
586 | }
587 | }
588 |
589 | private class ImSureItsLegitHostnameVerifier implements HostnameVerifier {
590 |
591 | @Override
592 | public boolean verify(String hostname, SSLSession session) {
593 | return true;
594 | }
595 | }
596 |
597 | /* This class creates a SSLSocket that trusts everyone. */
598 | public class TrustAllSSLSocketFactory extends SSLSocketFactory {
599 |
600 | SSLContext sslContext = SSLContext.getInstance("TLS");
601 |
602 | public TrustAllSSLSocketFactory(KeyStore truststore) throws
603 | NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
604 | super(truststore);
605 |
606 | TrustManager tm = new X509TrustManager() {
607 |
608 | public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
609 | }
610 |
611 | public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
612 | }
613 |
614 | public X509Certificate[] getAcceptedIssuers() {
615 | return null;
616 | }
617 | };
618 |
619 | sslContext.init(null, new TrustManager[]{tm}, null);
620 | }
621 |
622 | @Override
623 | public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
624 | return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
625 | }
626 |
627 | @Override
628 | public Socket createSocket() throws IOException {
629 | return sslContext.getSocketFactory().createSocket();
630 | }
631 | }
632 | }
633 |
--------------------------------------------------------------------------------
/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 | google()
6 | jcenter()
7 | }
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:7.2.1'
10 |
11 | // NOTE: Do not place your application dependencies here; they belong
12 | // in the individual module build.gradle files
13 | }
14 | }
15 |
16 | allprojects {
17 | repositories {
18 | google()
19 | jcenter()
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | APK_PATH="bin/JustTrustMe.apk"
2 | mkdir bin
3 | ./gradlew assembleRelease && cp app/build/outputs/apk/app-release-unsigned.apk $APK_PATH && signapk $APK_PATH
4 |
5 | #adb install -r bin/AndroidVTS.apk
6 |
--------------------------------------------------------------------------------
/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/TrackerControl/JustTrustMe/78a4fd50842fca908e63cf34a1e9565ceea25ba3/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
6 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------