diff --git a/app/build.gradle b/app/build.gradle
index 0149b1d..603b060 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -4,7 +4,7 @@ android {
compileSdkVersion 20
buildToolsVersion '20.0.0'
defaultConfig {
- applicationId 'me.trust.just.justtrustme'
+ applicationId 'just.trust.me'
minSdkVersion 16
targetSdkVersion 20
versionCode 1
@@ -14,7 +14,6 @@ android {
buildTypes {
release {
runProguard false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
productFlavors {
diff --git a/app/libs/XposedBridgeApi.jar b/app/libs/XposedBridgeApi.jar
index a87ddb4..fefd4ec 100644
Binary files a/app/libs/XposedBridgeApi.jar and b/app/libs/XposedBridgeApi.jar differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 32b1b2f..a507b3d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -6,9 +6,14 @@
android:allowBackup="true"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
-
-
-
+
+
+
-
diff --git a/app/src/main/java/just/trust/me/Main.java b/app/src/main/java/just/trust/me/Main.java
index 2d866d9..510e733 100644
--- a/app/src/main/java/just/trust/me/Main.java
+++ b/app/src/main/java/just/trust/me/Main.java
@@ -1,11 +1,22 @@
package just.trust.me;
-import javax.net.ssl.SSLSocketFactory;
+import android.net.http.SslError;
+import android.webkit.SslErrorHandler;
+import android.webkit.WebView;
+import java.io.IOException;
import java.net.Socket;
+import java.net.UnknownHostException;
+
import java.security.SecureRandom;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
@@ -13,45 +24,111 @@ import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.scheme.HostNameResolver;
+import org.apache.http.conn.scheme.PlainSocketFactory;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.conn.SingleClientConnManager;
+import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
+import org.apache.http.params.HttpParams;
+
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodReplacement;
+import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
+import static de.robv.android.xposed.XposedHelpers.callMethod;
+import static de.robv.android.xposed.XposedHelpers.callStaticMethod;
+import static de.robv.android.xposed.XposedHelpers.findAndHookConstructor;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
+import static de.robv.android.xposed.XposedHelpers.getObjectField;
+import static de.robv.android.xposed.XposedHelpers.newInstance;
+import static de.robv.android.xposed.XposedHelpers.setObjectField;
public class Main implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
- findAndHookMethod("javax.net.ssl.TrustManagerFactory", lpparam.classLoader, "getTrustManagers", new XC_MethodReplacement() {
+ /* Apache Hooks */
+ /* external/apache-http/src/org/apache/http/impl/client/DefaultHttpClient.java */
+ /* public DefaultHttpClient() */
+ findAndHookConstructor(DefaultHttpClient.class, new XC_MethodHook() {
+ @Override
+ protected void afterHookedMethod(MethodHookParam param) throws Throwable {
+
+ setObjectField(param.thisObject, "defaultParams", null);
+ setObjectField(param.thisObject, "connManager", getSCCM());
+ }
+ });
+
+ /* external/apache-http/src/org/apache/http/impl/client/DefaultHttpClient.java */
+ /* public DefaultHttpClient(HttpParams params) */
+ findAndHookConstructor(DefaultHttpClient.class, HttpParams.class, new XC_MethodHook() {
+ @Override
+ protected void afterHookedMethod(MethodHookParam param) throws Throwable {
+
+ setObjectField(param.thisObject, "defaultParams", (HttpParams)param.args[0]);
+ setObjectField(param.thisObject, "connManager", getSCCM());
+ }
+ });
+
+ /* external/apache-http/src/org/apache/http/impl/client/DefaultHttpClient.java */
+ /* public DefaultHttpClient(ClientConnectionManager conman, HttpParams params) */
+ findAndHookConstructor(DefaultHttpClient.class, ClientConnectionManager.class, HttpParams.class, new XC_MethodHook() {
+ @Override
+ protected void afterHookedMethod(MethodHookParam param) throws Throwable {
+
+ HttpParams params = (HttpParams)param.args[1];
+
+ setObjectField(param.thisObject, "defaultParams", params);
+ setObjectField(param.thisObject, "connManager", getCCM(param.args[0], params));
+ }
+ });
+
+ /* external/apache-http/src/org/apache/http/conn/ssl/SSLSocketFactory.java */
+ /* public SSLSocketFactory( ... ) */
+ findAndHookConstructor(SSLSocketFactory.class, String.class, KeyStore.class, String.class, KeyStore.class,
+ SecureRandom.class, HostNameResolver.class, new XC_MethodHook() {
+ @Override
+ protected void afterHookedMethod(MethodHookParam param) throws Throwable {
+
+ String algorithm = (String)param.args[0];
+ KeyStore keystore = (KeyStore)param.args[1];
+ String keystorePassword = (String)param.args[2];
+ SecureRandom random = (SecureRandom)param.args[4];
+
+ KeyManager[] keymanagers = null;
+ TrustManager[] trustmanagers = null;
+
+ if (keystore != null) {
+ keymanagers = (KeyManager[])callStaticMethod(SSLSocketFactory.class, "createKeyManagers", keystore, keystorePassword);
+ }
+
+ trustmanagers = new TrustManager[]{new ImSureItsLegitTrustManager()};
+
+ setObjectField(param.thisObject, "sslcontext", SSLContext.getInstance(algorithm));
+ callMethod(getObjectField(param.thisObject, "sslcontext"), "init", keymanagers, trustmanagers, random);
+ setObjectField(param.thisObject, "socketfactory",
+ callMethod(getObjectField(param.thisObject, "sslcontext"), "getSocketFactory"));
+ }
+
+ });
+
+ /* external/apache-http/src/org/apache/http/conn/ssl/SSLSocketFactory.java */
+ /* public static SSLSocketFactory getSocketFactory() */
+ findAndHookMethod("org.apache.http.conn.ssl.SSLSocketFactory", lpparam.classLoader, "getSocketFactory", new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
- return new TrustManager[]{new ImSureItsLegitTrustManager()};
+ return (SSLSocketFactory)newInstance(SSLSocketFactory.class);
}
});
- findAndHookMethod("javax.net.ssl.SSLContext", lpparam.classLoader, "init", KeyManager[].class, TrustManager[].class, SecureRandom.class, new XC_MethodHook() {
- @Override
- protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
- param.args[0] = null;
- param.args[1] = new TrustManager[]{new ImSureItsLegitTrustManager()};
- param.args[2] = null;
- }
- });
-
-
- findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setSSLSocketFactory", SSLSocketFactory.class, new XC_MethodHook() {
- @Override
- protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
- super.beforeHookedMethod(param);
- SSLContext context = SSLContext.getInstance("TLS");
- context.init(null, new TrustManager[]{new ImSureItsLegitTrustManager()}, null);
- param.args[0] = context.getSocketFactory();
- }
- });
-
-
+ /* external/apache-http/src/org/apache/http/conn/ssl/SSLSocketFactory.java */
+ /* public boolean isSecure(Socket) */
findAndHookMethod("org.apache.http.conn.ssl.SSLSocketFactory", lpparam.classLoader, "isSecure", Socket.class, new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
@@ -59,32 +136,134 @@ public class Main implements IXposedHookLoadPackage {
}
});
- findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setHostnameVerifier", HostnameVerifier.class, new XC_MethodHook() {
+ /* JSSE Hooks */
+ /* libcore/luni/src/main/java/javax/net/ssl/TrustManagerFactory.java */
+ /* public final TrustManager[] getTrustManager() */
+ findAndHookMethod("javax.net.ssl.TrustManagerFactory", lpparam.classLoader, "getTrustManagers", new XC_MethodReplacement() {
@Override
- protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
- param.args[0] = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
+ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
+ return new TrustManager[]{new ImSureItsLegitTrustManager()};
}
});
- findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setDefaultHostnameVerifier", HostnameVerifier.class, new XC_MethodHook() {
+ /* libcore/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java */
+ /* public void setDefaultHostnameVerifier(HostnameVerifier) */
+ findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setDefaultHostnameVerifier",
+ HostnameVerifier.class, new XC_MethodReplacement() {
@Override
- protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
- param.args[0] = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
+ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
+ return null;
}
});
- // Trick for WebViews
- findAndHookMethod("android.webkit.WebViewClient", lpparam.classLoader, "onReceivedSslError", HostnameVerifier.class, new XC_MethodReplacement() {
+ /* libcore/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java */
+ /* public void setSSLSocketFactory(SSLSocketFactory) */
+ findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setSSLSocketFactory", SSLSocketFactory.class,
+ new XC_MethodReplacement() {
+ @Override
+ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
+ return null;
+ }
+ });
+
+ /* libcore/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java */
+ /* public void setHostnameVerifier(HostNameVerifier) */
+ findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setHostnameVerifier", HostnameVerifier.class,
+ new XC_MethodReplacement() {
+ @Override
+ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
+ return null;
+ }
+ });
+
+
+ /* WebView Hooks */
+ /* frameworks/base/core/java/android/webkit/WebViewClient.java */
+ /* public void onReceivedSslError(Webview, SslErrorHandler, SslError) */
+ findAndHookMethod("android.webkit.WebViewClient", lpparam.classLoader, "onReceivedSslError",
+ WebView.class, SslErrorHandler.class, SslError.class, new XC_MethodReplacement() {
+ @Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
((android.webkit.SslErrorHandler)param.args[1]).proceed();
return null;
}
});
- findAndHookMethod("android.webkit.WebViewClient", lpparam.classLoader, "onReceivedError", HostnameVerifier.class,new XC_MethodReplacement() {
+
+ /* frameworks/base/core/java/android/webkit/WebViewClient.java */
+ /* public voidonReceivedError(WebView, int, String, String) */
+ findAndHookMethod("android.webkit.WebViewClient", lpparam.classLoader, "onReceivedError",
+ WebView.class, Integer.class, String.class, String.class, new XC_MethodReplacement() {
+ @Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
return null;
}
});
+ } // End Hooks
+
+ /* Helpers */
+ //Create a SingleClientConnManager that trusts everyone!
+ public ClientConnectionManager getSCCM() {
+
+ KeyStore trustStore;
+ try {
+
+ trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ trustStore.load(null, null);
+
+ SSLSocketFactory sf = new TrustAllSSLSocketFactory(trustStore);
+ sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+
+ SchemeRegistry registry = new SchemeRegistry();
+ registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
+ registry.register(new Scheme("https", sf, 443));
+
+ ClientConnectionManager ccm = new SingleClientConnManager(null, registry);
+
+ return ccm;
+
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ //This function creates a ThreadSafeClientConnManager that trusts everyone!
+ public ClientConnectionManager getTSCCM(HttpParams params) {
+
+ KeyStore trustStore;
+ try {
+
+ trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
+ trustStore.load(null, null);
+
+ SSLSocketFactory sf = new TrustAllSSLSocketFactory(trustStore);
+ sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+
+ SchemeRegistry registry = new SchemeRegistry();
+ registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
+ registry.register(new Scheme("https", sf, 443));
+
+ ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
+
+ return ccm;
+
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ //This function determines what object we are dealing with.
+ public ClientConnectionManager getCCM(Object o, HttpParams params) {
+
+ String className = o.getClass().getSimpleName();
+
+ if (className.equals("SingleClientConnManager")) {
+ return getSCCM();
+ }
+ else if (className.equals("ThreadSafeClientConnManager")) {
+ return getTSCCM(params);
+ }
+
+ return null;
}
class ImSureItsLegitTrustManager implements X509TrustManager {
@@ -97,4 +276,40 @@ public class Main implements IXposedHookLoadPackage {
return new X509Certificate[0];
}
}
+
+ /* This class creates a SSLSocket that trusts everyone. */
+ public class TrustAllSSLSocketFactory extends SSLSocketFactory {
+
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+
+ public TrustAllSSLSocketFactory(KeyStore truststore) throws
+ NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
+ super(truststore);
+
+ TrustManager tm = new X509TrustManager() {
+
+ public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+ }
+
+ public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+ }
+
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+ };
+
+ sslContext.init(null, new TrustManager[] { tm }, null);
+ }
+
+ @Override
+ public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
+ return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
+ }
+
+ @Override
+ public Socket createSocket() throws IOException {
+ return sslContext.getSocketFactory().createSocket();
+ }
+ }
}
diff --git a/bin/JustTrustMe.apk b/bin/JustTrustMe.apk
deleted file mode 100644
index c08c864..0000000
Binary files a/bin/JustTrustMe.apk and /dev/null differ