diff --git a/.idea/.name b/.idea/.name
deleted file mode 100644
index f255ec0..0000000
--- a/.idea/.name
+++ /dev/null
@@ -1 +0,0 @@
-Inspeckage
\ No newline at end of file
diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser
new file mode 100644
index 0000000..519649e
Binary files /dev/null and b/.idea/caches/build_file_checksums.ser differ
diff --git a/.idea/caches/gradle_models.ser b/.idea/caches/gradle_models.ser
new file mode 100644
index 0000000..7cf0b08
Binary files /dev/null and b/.idea/caches/gradle_models.ser differ
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index 30aa626..681f41a 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -1,29 +1,116 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+ xmlns:android
+
+ ^$
+
+
+
+
+
+
+
+
+ xmlns:.*
+
+ ^$
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*:id
+
+ http://schemas.android.com/apk/res/android
+
+
+
+
+
+
+
+
+ .*:name
+
+ http://schemas.android.com/apk/res/android
+
+
+
+
+
+
+
+
+ name
+
+ ^$
+
+
+
+
+
+
+
+
+ style
+
+ ^$
+
+
+
+
+
+
+
+
+ .*
+
+ ^$
+
+
+ BY_NAME
+
+
+
+
+
+
+ .*
+
+ http://schemas.android.com/apk/res/android
+
+
+ ANDROID_ATTRIBUTE_ORDER
+
+
+
+
+
+
+ .*
+
+ .*
+
+
+ BY_NAME
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
deleted file mode 100644
index 96cc43e..0000000
--- a/.idea/compiler.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
deleted file mode 100644
index e7bedf3..0000000
--- a/.idea/copyright/profiles_settings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
deleted file mode 100644
index 97626ba..0000000
--- a/.idea/encodings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index afaee01..ee635a3 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -3,9 +3,11 @@
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
deleted file mode 100644
index 010be73..0000000
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
deleted file mode 100644
index 3b31283..0000000
--- a/.idea/inspectionProfiles/profiles_settings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index ba7052b..dfd2c79 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,30 +1,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 94a25f7..35eb1dd 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index c6ff81f..be9e68f 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -2,7 +2,7 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion 26
- buildToolsVersion '28.0.2'
+ buildToolsVersion '28.0.3'
defaultConfig {
applicationId "mobi.acpm.inspeckage"
minSdkVersion 21
diff --git a/app/release/output.json b/app/release/output.json
new file mode 100644
index 0000000..235b52b
--- /dev/null
+++ b/app/release/output.json
@@ -0,0 +1 @@
+[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":10,"versionName":"2.4","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
\ No newline at end of file
diff --git a/app/src/main/java/mobi/acpm/inspeckage/Module.java b/app/src/main/java/mobi/acpm/inspeckage/Module.java
index cd87771..3e3a2e7 100644
--- a/app/src/main/java/mobi/acpm/inspeckage/Module.java
+++ b/app/src/main/java/mobi/acpm/inspeckage/Module.java
@@ -4,6 +4,7 @@
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
+import android.util.Log;
import java.io.File;
@@ -22,6 +23,7 @@
import mobi.acpm.inspeckage.hooks.HashHook;
import mobi.acpm.inspeckage.hooks.HttpHook;
import mobi.acpm.inspeckage.hooks.IPCHook;
+import mobi.acpm.inspeckage.hooks.JustTrustMeHook;
import mobi.acpm.inspeckage.hooks.MiscHook;
import mobi.acpm.inspeckage.hooks.ProxyHook;
import mobi.acpm.inspeckage.hooks.SQLiteHook;
@@ -33,6 +35,7 @@
import mobi.acpm.inspeckage.hooks.WebViewHook;
import mobi.acpm.inspeckage.hooks.entities.LocationHook;
import mobi.acpm.inspeckage.util.Config;
+import mobi.acpm.inspeckage.util.DexUtil;
import mobi.acpm.inspeckage.util.FileType;
import mobi.acpm.inspeckage.util.FileUtil;
@@ -157,14 +160,13 @@ protected void afterHookedMethod(MethodHookParam param) throws Throwable {
if(sPrefs.getBoolean(Config.SP_TAB_ENABLE_IPC,true)) {
IPCHook.initAllHooks(loadPackageParam);
}
- ProxyHook.initAllHooks(loadPackageParam);// --
if(sPrefs.getBoolean(Config.SP_TAB_ENABLE_SHAREDP,true)) {
SharedPrefsHook.initAllHooks(loadPackageParam);
}
if(sPrefs.getBoolean(Config.SP_TAB_ENABLE_SQLITE,true)) {
SQLiteHook.initAllHooks(loadPackageParam);
}
- SSLPinningHook.initAllHooks(loadPackageParam);// --
+
if(sPrefs.getBoolean(Config.SP_TAB_ENABLE_SERIALIZATION,true)) {
SerializationHook.initAllHooks(loadPackageParam);
}
@@ -176,7 +178,12 @@ protected void afterHookedMethod(MethodHookParam param) throws Throwable {
}
FingerprintHook.initAllHooks(loadPackageParam);
- //DexUtil.saveClassesWithMethodsJson(loadPackageParam, sPrefs);
+
+
+ SSLPinningHook.initAllHooks(loadPackageParam);// --
+ ProxyHook.initAllHooks(loadPackageParam);// --
+ DexUtil.saveClassesWithMethodsJson(loadPackageParam, sPrefs);
+ JustTrustMeHook.initAllHooks(loadPackageParam);// --
}
public static void logError(Error e){
diff --git a/app/src/main/java/mobi/acpm/inspeckage/hooks/JustTrustMeHook.java b/app/src/main/java/mobi/acpm/inspeckage/hooks/JustTrustMeHook.java
new file mode 100644
index 0000000..979c1e6
--- /dev/null
+++ b/app/src/main/java/mobi/acpm/inspeckage/hooks/JustTrustMeHook.java
@@ -0,0 +1,598 @@
+package mobi.acpm.inspeckage.hooks;
+
+import android.content.Context;
+import android.net.http.SslError;
+import android.util.Log;
+import android.webkit.SslErrorHandler;
+import android.webkit.WebView;
+
+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.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+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 java.io.IOException;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+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.XSharedPreferences;
+import de.robv.android.xposed.callbacks.XC_LoadPackage;
+import mobi.acpm.inspeckage.Module;
+
+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.findClass;
+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 JustTrustMeHook extends XC_MethodHook{
+
+ private static final String TAG = JustTrustMeHook.class.getSimpleName();
+ private static XSharedPreferences sPrefs;
+
+ public static void loadPrefs() {
+ sPrefs = new XSharedPreferences(Module.class.getPackage().getName(), Module.PREFS);
+ sPrefs.makeWorldReadable();
+ }
+
+ public static void initAllHooks(final XC_LoadPackage.LoadPackageParam lpparam) {
+
+ String currentPackageName = lpparam.packageName;
+
+
+
+ /* Apache Hooks */
+ /* external/apache-http/src/org/apache/http/impl/client/DefaultHttpClient.java */
+ /* public DefaultHttpClient() */
+ Log.d(TAG, "Hooking DefaultHTTPClient for: ");
+ 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) */
+ Log.d(TAG, "Hooking DefaultHTTPClient(HttpParams) for: ");
+ 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) */
+ Log.d(TAG, "Hooking DefaultHTTPClient(ClientConnectionManager, HttpParams) for: ");
+ 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( ... ) */
+ Log.d(TAG, "Hooking SSLSocketFactory(String, KeyStore, String, KeyStore) for: ");
+ 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() */
+ Log.d(TAG, "Hooking static SSLSocketFactory(String, KeyStore, String, KeyStore) for: ");
+ findAndHookMethod("org.apache.http.conn.ssl.SSLSocketFactory", lpparam.classLoader, "getSocketFactory", new XC_MethodReplacement() {
+ @Override
+ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
+ return (SSLSocketFactory) newInstance(SSLSocketFactory.class);
+ }
+ });
+
+ /* external/apache-http/src/org/apache/http/conn/ssl/SSLSocketFactory.java */
+ /* public boolean isSecure(Socket) */
+ Log.d(TAG, "Hooking SSLSocketFactory(Socket) for: ");
+ findAndHookMethod("org.apache.http.conn.ssl.SSLSocketFactory", lpparam.classLoader, "isSecure", Socket.class, new XC_MethodReplacement() {
+ @Override
+ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
+ return true;
+ }
+ });
+
+ /* JSSE Hooks */
+ /* libcore/luni/src/main/java/javax/net/ssl/TrustManagerFactory.java */
+ /* public final TrustManager[] getTrustManager() */
+ Log.d(TAG, "Hooking TrustManagerFactory.getTrustManagers() for: ");
+ findAndHookMethod("javax.net.ssl.TrustManagerFactory", lpparam.classLoader, "getTrustManagers", new XC_MethodHook() {
+ @Override
+ protected void afterHookedMethod(MethodHookParam param) throws Throwable {
+
+ if (hasTrustManagerImpl()) {
+ Class> cls = findClass("com.android.org.conscrypt.TrustManagerImpl", lpparam.classLoader);
+
+ TrustManager[] managers = (TrustManager[]) param.getResult();
+ if (managers.length > 0 && cls.isInstance(managers[0]))
+ return;
+ }
+
+ param.setResult(new TrustManager[]{new ImSureItsLegitTrustManager()});
+ }
+ });
+
+ /* libcore/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java */
+ /* public void setDefaultHostnameVerifier(HostnameVerifier) */
+ Log.d(TAG, "Hooking HttpsURLConnection.setDefaultHostnameVerifier for: ");
+ findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setDefaultHostnameVerifier",
+ HostnameVerifier.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 setSSLSocketFactory(SSLSocketFactory) */
+ Log.d(TAG, "Hooking HttpsURLConnection.setSSLSocketFactory for: ");
+ findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setSSLSocketFactory", javax.net.ssl.SSLSocketFactory.class,
+ new XC_MethodReplacement() {
+ @Override
+ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
+ return null;
+ }
+ });
+
+ /* libcore/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java */
+ /* public void setHostnameVerifier(HostNameVerifier) */
+ Log.d(TAG, "Hooking HttpsURLConnection.setHostnameVerifier for: ");
+ 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) */
+ Log.d(TAG, "Hooking WebViewClient.onReceivedSslError(WebView, SslErrorHandler, SslError) for: ");
+
+ 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;
+ }
+ });
+
+ /* frameworks/base/core/java/android/webkit/WebViewClient.java */
+ /* public void onReceivedError(WebView, int, String, String) */
+ Log.d(TAG, "Hooking WebViewClient.onReceivedSslError(WebView, int, string, string) for: ");
+
+ findAndHookMethod("android.webkit.WebViewClient", lpparam.classLoader, "onReceivedError",
+ WebView.class, int.class, String.class, String.class, new XC_MethodReplacement() {
+ @Override
+ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
+ return null;
+ }
+ });
+
+ //SSLContext.init >> (null,ImSureItsLegitTrustManager,null)
+ 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;
+
+ }
+ });
+
+ // Multi-dex support: https://github.com/rovo89/XposedBridge/issues/30#issuecomment-68486449
+ findAndHookMethod("android.app.Application",
+ lpparam.classLoader,
+ "attach",
+ Context.class,
+ new XC_MethodHook() {
+ @Override
+ protected void afterHookedMethod(MethodHookParam param) throws Throwable {
+ // Hook OkHttp or third party libraries.
+ Context context = (Context) param.args[0];
+ processOkHttp(context.getClassLoader());
+ processHttpClientAndroidLib(context.getClassLoader());
+ processXutils(context.getClassLoader());
+ }
+ }
+ );
+
+ /* Only for newer devices should we try to hook TrustManagerImpl */
+ if (hasTrustManagerImpl()) {
+ /* TrustManagerImpl Hooks */
+ /* external/conscrypt/src/platform/java/org/conscrypt/TrustManagerImpl.java */
+ Log.d(TAG, "Hooking com.android.org.conscrypt.TrustManagerImpl for: ");
+
+ /* public void checkServerTrusted(X509Certificate[] chain, String authType) */
+ findAndHookMethod("com.android.org.conscrypt.TrustManagerImpl", lpparam.classLoader,
+ "checkServerTrusted", X509Certificate[].class, String.class,
+ new XC_MethodReplacement() {
+ @Override
+ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
+ return 0;
+ }
+ });
+
+ /* public List checkServerTrusted(X509Certificate[] chain,
+ String authType, String host) throws CertificateException */
+ findAndHookMethod("com.android.org.conscrypt.TrustManagerImpl", lpparam.classLoader,
+ "checkServerTrusted", X509Certificate[].class, String.class,
+ String.class, new XC_MethodReplacement() {
+ @Override
+ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
+ ArrayList list = new ArrayList();
+ return list;
+ }
+ });
+
+
+ /* public List checkServerTrusted(X509Certificate[] chain,
+ String authType, SSLSession session) throws CertificateException */
+ findAndHookMethod("com.android.org.conscrypt.TrustManagerImpl", lpparam.classLoader,
+ "checkServerTrusted", X509Certificate[].class, String.class,
+ SSLSession.class, new XC_MethodReplacement() {
+ @Override
+ protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
+ ArrayList list = new ArrayList();
+ return list;
+ }
+ });
+ }
+
+ } // End Hooks
+
+ /* Helpers */
+ // Check for TrustManagerImpl class
+ public static boolean hasTrustManagerImpl() {
+
+ try {
+ Class.forName("com.android.org.conscrypt.TrustManagerImpl");
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ return true;
+ }
+
+ private static javax.net.ssl.SSLSocketFactory getEmptySSLFactory() {
+ try {
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(null, new TrustManager[]{new ImSureItsLegitTrustManager()}, null);
+ return sslContext.getSocketFactory();
+ } catch (NoSuchAlgorithmException e) {
+ return null;
+ } catch (KeyManagementException e) {
+ return null;
+ }
+ }
+
+ //Create a SingleClientConnManager that trusts everyone!
+ public static 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 static 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 static 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;
+ }
+
+ private static void processXutils(ClassLoader classLoader) {
+ Log.d(TAG, "Hooking org.xutils.http.RequestParams.setSslSocketFactory(SSLSocketFactory) (3) for: ");
+ try {
+ classLoader.loadClass("org.xutils.http.RequestParams");
+ findAndHookMethod("org.xutils.http.RequestParams", classLoader, "setSslSocketFactory", javax.net.ssl.SSLSocketFactory.class, new XC_MethodHook() {
+ @Override
+ protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
+ super.beforeHookedMethod(param);
+ param.args[0] = getEmptySSLFactory();
+ }
+ });
+ findAndHookMethod("org.xutils.http.RequestParams", classLoader, "setHostnameVerifier", HostnameVerifier.class, new XC_MethodHook() {
+ @Override
+ protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
+ super.beforeHookedMethod(param);
+ param.args[0] = new ImSureItsLegitHostnameVerifier();
+ }
+ });
+ } catch (Exception e) {
+ Log.d(TAG, "org.xutils.http.RequestParams not found in -- not hooking");
+ }
+ }
+
+ static void processOkHttp(ClassLoader classLoader) {
+ /* hooking OKHTTP by SQUAREUP */
+ /* com/squareup/okhttp/CertificatePinner.java available online @ https://github.com/square/okhttp/blob/master/okhttp/src/main/java/com/squareup/okhttp/CertificatePinner.java */
+ /* public void check(String hostname, List peerCertificates) throws SSLPeerUnverifiedException{}*/
+ /* Either returns true or a exception so blanket return true */
+ /* Tested against version 2.5 */
+ Log.d(TAG, "Hooking com.squareup.okhttp.CertificatePinner.check(String,List) (2.5) for: ");
+
+ try {
+ classLoader.loadClass("com.squareup.okhttp.CertificatePinner");
+ findAndHookMethod("com.squareup.okhttp.CertificatePinner",
+ classLoader,
+ "check",
+ String.class,
+ List.class,
+ new XC_MethodReplacement() {
+ @Override
+ protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
+ return true;
+ }
+ });
+ } catch (ClassNotFoundException e) {
+ // pass
+ Log.d(TAG, "OKHTTP 2.5 not found in -- not hooking");
+ }
+
+ //https://github.com/square/okhttp/blob/parent-3.0.1/okhttp/src/main/java/okhttp3/CertificatePinner.java#L144
+ Log.d(TAG, "Hooking okhttp3.CertificatePinner.check(String,List) (3.x) for: ");
+
+ try {
+ classLoader.loadClass("okhttp3.CertificatePinner");
+ findAndHookMethod("okhttp3.CertificatePinner",
+ classLoader,
+ "check",
+ String.class,
+ List.class,
+ new XC_MethodReplacement() {
+ @Override
+ protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
+ return null;
+ }
+ });
+ } catch (ClassNotFoundException e) {
+ Log.d(TAG, "OKHTTP 3.x not found in -- not hooking");
+ // pass
+ }
+
+ //https://github.com/square/okhttp/blob/parent-3.0.1/okhttp/src/main/java/okhttp3/internal/tls/OkHostnameVerifier.java
+ try {
+ classLoader.loadClass("okhttp3.internal.tls.OkHostnameVerifier");
+ findAndHookMethod("okhttp3.internal.tls.OkHostnameVerifier",
+ classLoader,
+ "verify",
+ String.class,
+ javax.net.ssl.SSLSession.class,
+ new XC_MethodReplacement() {
+ @Override
+ protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
+ return true;
+ }
+ });
+ } catch (ClassNotFoundException e) {
+ Log.d(TAG, "OKHTTP 3.x not found in -- not hooking OkHostnameVerifier.verify(String, SSLSession)");
+ // pass
+ }
+
+ //https://github.com/square/okhttp/blob/parent-3.0.1/okhttp/src/main/java/okhttp3/internal/tls/OkHostnameVerifier.java
+ try {
+ classLoader.loadClass("okhttp3.internal.tls.OkHostnameVerifier");
+ findAndHookMethod("okhttp3.internal.tls.OkHostnameVerifier",
+ classLoader,
+ "verify",
+ String.class,
+ java.security.cert.X509Certificate.class,
+ new XC_MethodReplacement() {
+ @Override
+ protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
+ return true;
+ }
+ });
+ } catch (ClassNotFoundException e) {
+ Log.d(TAG, "OKHTTP 3.x not found in -- not hooking OkHostnameVerifier.verify(String, X509)(");
+ // pass
+ }
+ }
+
+ static void processHttpClientAndroidLib(ClassLoader classLoader) {
+ /* httpclientandroidlib Hooks */
+ /* public final void verify(String host, String[] cns, String[] subjectAlts, boolean strictWithSubDomains) throws SSLException */
+ Log.d(TAG, "Hooking AbstractVerifier.verify(String, String[], String[], boolean) for: ");
+
+ try {
+ classLoader.loadClass("ch.boye.httpclientandroidlib.conn.ssl.AbstractVerifier");
+ findAndHookMethod("ch.boye.httpclientandroidlib.conn.ssl.AbstractVerifier", classLoader, "verify",
+ String.class, String[].class, String[].class, boolean.class,
+ new XC_MethodReplacement() {
+ @Override
+ protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
+ return null;
+ }
+ });
+ } catch (ClassNotFoundException e) {
+ // pass
+ Log.d(TAG, "httpclientandroidlib not found in -- not hooking");
+ }
+ }
+
+ private static class ImSureItsLegitTrustManager implements X509TrustManager {
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+ }
+
+ public List checkServerTrusted(X509Certificate[] chain, String authType, String host) throws CertificateException {
+ ArrayList list = new ArrayList();
+ return list;
+ }
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ return new X509Certificate[0];
+ }
+ }
+
+ private static class ImSureItsLegitHostnameVerifier implements HostnameVerifier {
+
+ @Override
+ public boolean verify(String hostname, SSLSession session) {
+ return true;
+ }
+ }
+
+ /* This class creates a SSLSocket that trusts everyone. */
+ public static 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();
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/mobi/acpm/inspeckage/hooks/LRUCache.java b/app/src/main/java/mobi/acpm/inspeckage/hooks/LRUCache.java
new file mode 100644
index 0000000..f55c68a
--- /dev/null
+++ b/app/src/main/java/mobi/acpm/inspeckage/hooks/LRUCache.java
@@ -0,0 +1,18 @@
+package mobi.acpm.inspeckage.hooks;
+
+
+import java.util.LinkedHashMap;
+
+public class LRUCache extends LinkedHashMap {
+ private int maxEntries;
+
+ public LRUCache(int maxEntries) {
+ super(16, 0.75f, true);
+ this.maxEntries = maxEntries;
+ }
+
+ @Override
+ protected boolean removeEldestEntry(Entry eldest) {
+ return size() > maxEntries;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/mobi/acpm/inspeckage/hooks/ProxyHook.java b/app/src/main/java/mobi/acpm/inspeckage/hooks/ProxyHook.java
index 561c32c..c0e32e9 100644
--- a/app/src/main/java/mobi/acpm/inspeckage/hooks/ProxyHook.java
+++ b/app/src/main/java/mobi/acpm/inspeckage/hooks/ProxyHook.java
@@ -1,12 +1,19 @@
package mobi.acpm.inspeckage.hooks;
+import android.content.Context;
import android.os.Build;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.webkit.WebView;
import org.apache.http.HttpHost;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.impl.client.DefaultHttpClient;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
import java.net.URI;
+import java.net.URL;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XSharedPreferences;
@@ -17,6 +24,7 @@
import static de.robv.android.xposed.XposedBridge.hookAllConstructors;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
+import static mobi.acpm.inspeckage.util.WebViewHttpProxy.setProxy;
/**
* Created by acpm on 21/11/15.
@@ -72,11 +80,25 @@ protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
Module.logError(e);
}
+ try{
+ findAndHookMethod("java.net.URL", loadPackageParam.classLoader, "openConnection", new XC_MethodHook() {
+ @Override
+ protected void beforeHookedMethod(MethodHookParam param)
+ throws Throwable {
+ URL url = (URL) param.thisObject;
+ Log.d("overjt", url.toString());
+ Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress( sPrefs.getString("host", null), Integer.parseInt(sPrefs.getString("port", null))));
+ param.setResult(url.openConnection(proxy));
+ }
+ });
+ }catch(Error e){
+ Log.d("overjt", "falló algo");
+ }
+
hookAllConstructors(XposedHelpers.findClass("org.apache.http.impl.client.DefaultHttpClient", loadPackageParam.classLoader), new XC_MethodHook() {
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
loadPrefs();
-
if (sPrefs.getBoolean("switch_proxy", false)) {
String proxyHost = sPrefs.getString("host", null);
int proxyPort;
@@ -92,5 +114,65 @@ protected void afterHookedMethod(MethodHookParam param) throws Throwable {
}
}
});
+
+ try {
+ hookWebView(loadPackageParam.classLoader, loadPackageParam.packageName);
+ }catch (Throwable exception) {
+ }
+ }
+
+ private static Class findClass(String className, ClassLoader classLoader) {
+ try {
+ return XposedHelpers.findClass(className, classLoader);
+ } catch (Throwable exception) {
+ }
+ return null;
+ }
+
+ private static void hookWebView(final ClassLoader classLoader, final String packageName) {
+ final String[] webviewList = {
+ "android.webkit.WebView", // android webview
+ "com.tencent.smtt.sdk.WebView", // tencent x5
+ "com.uc.webview.export.WebView", // UC
+ WebView.class.toString()
+ };
+
+ LRUCache hookedClassLoader = new LRUCache<>(10000);
+
+ for (int i = 0; i < webviewList.length; i++) {
+ final String className = webviewList[i];
+ final Class cla = findClass(className, classLoader);
+ if(cla == null){
+ continue;
+ }
+ String key = cla.getName() + "@" + cla.getClassLoader().hashCode();
+ boolean hooked;
+ if (hookedClassLoader.get(key) == null) {
+ hookedClassLoader.put(key, true);
+ hooked = true;
+ }else{
+ hooked = false;
+ }
+ if (cla != null && hooked) {
+ XposedBridge.log(packageName + " hook " + className + "@" + cla.getClassLoader().getClass().getName() + ":" + cla.getClassLoader().hashCode());
+ XC_MethodHook WebserviceProxyHook = new XC_MethodHook() {
+ @Override
+ protected void afterHookedMethod(MethodHookParam param) throws Throwable {
+
+ loadPrefs();
+ if (sPrefs.getBoolean("switch_proxy", false)) {
+ WebView wv = (WebView) param.thisObject;
+ setProxy(wv, sPrefs.getString("host", null), Integer.parseInt(sPrefs.getString("port", null)), "android.app.Application");
+ }
+ }
+ };
+
+ XposedHelpers.findAndHookConstructor(cla, Context.class, WebserviceProxyHook);
+ XposedHelpers.findAndHookConstructor(cla, Context.class, AttributeSet.class, WebserviceProxyHook);
+ XposedHelpers.findAndHookConstructor(cla, Context.class, AttributeSet.class, int.class, WebserviceProxyHook);
+ XposedHelpers.findAndHookConstructor(cla, Context.class, AttributeSet.class, int.class, int.class, WebserviceProxyHook);
+ XposedHelpers.findAndHookConstructor(cla, Context.class, AttributeSet.class, int.class, boolean.class, WebserviceProxyHook);
+ }
+ }
}
}
diff --git a/app/src/main/java/mobi/acpm/inspeckage/hooks/SSLPinningHook.java b/app/src/main/java/mobi/acpm/inspeckage/hooks/SSLPinningHook.java
index 823ee4b..11b5ceb 100644
--- a/app/src/main/java/mobi/acpm/inspeckage/hooks/SSLPinningHook.java
+++ b/app/src/main/java/mobi/acpm/inspeckage/hooks/SSLPinningHook.java
@@ -1,5 +1,7 @@
package mobi.acpm.inspeckage.hooks;
+import android.util.Log;
+
import org.apache.http.conn.scheme.HostNameResolver;
import org.apache.http.conn.ssl.SSLSocketFactory;
@@ -8,10 +10,13 @@
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.List;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
@@ -46,6 +51,7 @@ public static void loadPrefs() {
public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) {
+
// --- Java Secure Socket Extension (JSSE) ---
//TrustManagerFactory.getTrustManagers >> EmptyTrustManager
@@ -227,11 +233,19 @@ public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
+ public void checkServerTrusted(X509Certificate[] certs, String authType, Socket socket) throws CertificateException {
+ }
+
+ public void checkServerTrusted(X509Certificate[] certs, String authType, SSLEngine engine) throws CertificateException {
+ }
+
@Override
- public void checkServerTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
+ public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
}
+ public List checkServerTrusted(X509Certificate[] certs, String authType, String hostname) throws CertificateException {
+ return Arrays.asList(new X509Certificate[0]);
+ }
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
diff --git a/app/src/main/java/mobi/acpm/inspeckage/hooks/WebViewHook.java b/app/src/main/java/mobi/acpm/inspeckage/hooks/WebViewHook.java
index 58b2fdc..2c86fcc 100644
--- a/app/src/main/java/mobi/acpm/inspeckage/hooks/WebViewHook.java
+++ b/app/src/main/java/mobi/acpm/inspeckage/hooks/WebViewHook.java
@@ -1,5 +1,6 @@
package mobi.acpm.inspeckage.hooks;
+import android.content.res.XResources;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
@@ -33,21 +34,6 @@ protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
}
});
- findAndHookMethod(WebView.class, "loadUrl",
- String.class, new XC_MethodHook() {
-
- protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
-
- sb = new StringBuilder();
- WebView wv = (WebView) param.thisObject;
- sb.append("Load URL: " + param.args[0]);
-
- sb.append(checkSettings(wv));
-
- XposedBridge.log(TAG + sb.toString());
- }
- });
-
findAndHookMethod(WebView.class, "loadData",
String.class, String.class, String.class, new XC_MethodHook() {
@@ -89,6 +75,16 @@ protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
}
});
+ //XResources.setSystemWideReplacement("android", "string", "config_webViewPackageName", "com.google.android.webview");
+
+// findAndHookMethod("android.webkit.WebViewFactory", null, "getWebViewPackageName", new XC_MethodHook() {
+// @Override
+// protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
+// XposedBridge.log("getWebViewPackageName");
+// param.setResult("com.google.android.webview");
+// }
+// });
+
}
static String checkSettings(WebView wv) {
diff --git a/app/src/main/java/mobi/acpm/inspeckage/receivers/InspeckageReceiver.java b/app/src/main/java/mobi/acpm/inspeckage/receivers/InspeckageReceiver.java
index 55853f2..0ab3497 100644
--- a/app/src/main/java/mobi/acpm/inspeckage/receivers/InspeckageReceiver.java
+++ b/app/src/main/java/mobi/acpm/inspeckage/receivers/InspeckageReceiver.java
@@ -5,8 +5,11 @@
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Build;
+import android.preference.PreferenceManager;
+import android.util.Log;
import android.webkit.WebView;
import java.lang.reflect.Field;
@@ -156,13 +159,13 @@ public void onReceive(Context context, Intent intent) {
String tree = Util.FileTree(activity.getApplicationInfo().dataDir, "");
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this.activity);
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putString("tree",tree);
+ editor.apply();
+
Intent i = new Intent("mobi.acpm.inspeckage.INSPECKAGE_WEB");
i.putExtra("action", "fileTree");
- float m = (float) tree.length() / 3;
- String sub1 = tree.substring(0, (int) m);
- String sub2 = tree.substring((int) m, tree.length());
- //talvez tenha que dividir pq a arvore pode ficar muito grande para ser enviada via intent
- i.putExtra("tree", tree);
activity.sendBroadcast(i, null);
Util.sb = new StringBuilder();
diff --git a/app/src/main/java/mobi/acpm/inspeckage/receivers/InspeckageWebReceiver.java b/app/src/main/java/mobi/acpm/inspeckage/receivers/InspeckageWebReceiver.java
index 2d93b34..7e252c9 100644
--- a/app/src/main/java/mobi/acpm/inspeckage/receivers/InspeckageWebReceiver.java
+++ b/app/src/main/java/mobi/acpm/inspeckage/receivers/InspeckageWebReceiver.java
@@ -4,6 +4,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
import mobi.acpm.inspeckage.Module;
import mobi.acpm.inspeckage.util.Config;
@@ -29,8 +30,7 @@ public void onReceive(Context context, Intent intent) {
String action = intent.getExtras().getString("action");
if(action.equals("fileTree")){
-
- String sub1 = intent.getExtras().getString("tree");
+ String sub1 = mPrefs.getString("tree","");
String script = "