### GET /?type=startapp Source: https://context7.com/ac-pm/inspeckage/llms.txt Starts the target application currently configured in Inspeckage. ```APIDOC ## GET /?type=startapp ### Description Starts the target application configured in the Inspeckage preferences. ### Method GET ### Endpoint /?type=startapp ``` -------------------------------- ### GET /?type=proxy Source: https://context7.com/ac-pm/inspeckage/llms.txt Configures proxy settings for the target application. ```APIDOC ## GET /?type=proxy ### Description Sets the proxy host and port for network traffic analysis. ### Method GET ### Query Parameters - **host** (string) - Required - The proxy host IP address. - **port** (string) - Required - The proxy port number. ``` -------------------------------- ### GET /?type=screenshot Source: https://context7.com/ac-pm/inspeckage/llms.txt Takes a screenshot of the target application. ```APIDOC ## GET /?type=screenshot ### Description Captures a screenshot of the target application and returns the image file. ### Method GET ### Endpoint /?type=screenshot ``` -------------------------------- ### GET /?type=sslunpinning Source: https://context7.com/ac-pm/inspeckage/llms.txt Enables or disables SSL unpinning. ```APIDOC ## GET /?type=sslunpinning ### Description Configures the SSL unpinning state. ### Method GET ### Query Parameters - **sslswitch** (boolean) - Required - Set to true to enable or false to disable SSL unpinning. ``` -------------------------------- ### GET /?type=downapk Source: https://context7.com/ac-pm/inspeckage/llms.txt Downloads the target APK file from the device. ```APIDOC ## GET /?type=downapk ### Description Retrieves the target APK file from the device storage. ### Method GET ### Endpoint /?type=downapk ``` -------------------------------- ### GET /?type=finishapp Source: https://context7.com/ac-pm/inspeckage/llms.txt Stops the target application by sending a broadcast intent. ```APIDOC ## GET /?type=finishapp ### Description Stops the target application by sending a broadcast intent to the Inspeckage filter. ### Method GET ### Endpoint /?type=finishapp ``` -------------------------------- ### GET /?type=location Source: https://context7.com/ac-pm/inspeckage/llms.txt Sets a spoofed GPS location for the target application. ```APIDOC ## GET /?type=location ### Description Sets the geolocation coordinates for location spoofing. ### Method GET ### Query Parameters - **geolocation** (string) - Required - Latitude and longitude coordinates (e.g., 40.7128,-74.0060). ``` -------------------------------- ### GET /?type=adduserhooks Source: https://context7.com/ac-pm/inspeckage/llms.txt Adds custom hooks dynamically to the target application. ```APIDOC ## GET /?type=adduserhooks ### Description Updates the user hooks configuration with a JSON string. ### Method GET ### Query Parameters - **jhooks** (string) - Required - A JSON array of hook objects containing id, className, method, and state. ``` -------------------------------- ### Initialize Xposed Module and Hooks Source: https://context7.com/ac-pm/inspeckage/llms.txt The main Xposed module entry point initializes preferences and hooks based on user configuration. It only hooks the target package specified in preferences. ```java // Module.java - Main Xposed module implementation public class Module extends XC_MethodHook implements IXposedHookLoadPackage, IXposedHookZygoteInit { public static final String PREFS = "InspeckagePrefs"; public static final String TAG = "Inspeckage_Module:"; public static XSharedPreferences sPrefs; // Initialize preferences in Zygote process public void initZygote(StartupParam startupParam) throws Throwable { sPrefs = new XSharedPreferences(MY_PACKAGE_NAME, PREFS); sPrefs.makeWorldReadable(); } @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { sPrefs.reload(); // Only hook the configured target package if (!loadPackageParam.packageName.equals(sPrefs.getString("package", ""))) return; // Initialize all hook modules based on preferences UIHook.initAllHooks(loadPackageParam); if(sPrefs.getBoolean(Config.SP_TAB_ENABLE_CRYPTO, true)) { CryptoHook.initAllHooks(loadPackageParam); } if(sPrefs.getBoolean(Config.SP_TAB_ENABLE_SQLITE, true)) { SQLiteHook.initAllHooks(loadPackageParam); } SSLPinningHook.initAllHooks(loadPackageParam); FingerprintHook.initAllHooks(loadPackageParam); // ... additional hooks initialized based on preferences } } ``` -------------------------------- ### Initialize and Apply User-Defined Hooks Source: https://context7.com/ac-pm/inspeckage/llms.txt This Java code initializes and applies user-defined hooks based on a JSON configuration. It loads preferences, parses the JSON to identify active hooks, and then applies them to the specified classes and methods using XposedBridge. Ensure the JSON format is correct and hooks are enabled in preferences. ```java public class UserHooks extends XC_MethodHook { public static final String TAG = "Inspeckage_UserHooks:"; private static Gson gson = new GsonBuilder().disableHtmlEscaping().create(); public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) { loadPrefs(); String json = "{\"hookJson\": " + sPrefs.getString(Config.SP_USER_HOOKS, "") + "}"; try { if (!json.trim().equals("{\"hookJson\":}")) { HookList hookList = gson.fromJson(json, HookList.class); for (HookItem hookItem : hookList.hookJson) { if (hookItem.state) { hook(hookItem, loadPackageParam.classLoader); } } } } catch (JsonSyntaxException ex) { } } static void hook(HookItem item, ClassLoader classLoader) { try { Class hookClass = findClass(item.className, classLoader); if (hookClass != null) { // Hook specific method or all methods if (item.method != null && !item.method.equals("")) { for (Method method : hookClass.getDeclaredMethods()) { if (method.getName().equals(item.method) && !Modifier.isAbstract(method.getModifiers())) { XposedBridge.hookMethod(method, methodHook); } } } else { // Hook all methods in class for (Method method : hookClass.getDeclaredMethods()) { if (!Modifier.isAbstract(method.getModifiers())) { XposedBridge.hookMethod(method, methodHook); } } } // Optionally hook constructors if (item.constructor) { for (Constructor constructor : hookClass.getDeclaredConstructors()) { XposedBridge.hookMethod(constructor, methodHook); } } } } catch (Error e) { Module.logError(e); } } // Log method invocations with parameters and return values static XC_MethodHook methodHook = new XC_MethodHook() { protected void afterHookedMethod(MethodHookParam param) throws Throwable { loadPrefs(); Replacement.resultReplace(param, sPrefs); parseParam(param); } }; } ``` -------------------------------- ### JavaScript Map Initialization and Autocomplete Logic Source: https://github.com/ac-pm/inspeckage/blob/master/app/src/main/assets/HTMLFiles/content/maps.html Initializes the Google Map, sets up the autocomplete service, and handles marker drag events and place selection. ```javascript function initMap() { var map = new google.maps.Map(document.getElementById('map'), { center: {lat: -8.063234502829292, lng: -34.87092351895751}, zoom: 15 }); google.maps.event.trigger(map, "resize"); var geocoder = new google.maps.Geocoder; var card = document.getElementById('pac-card'); var input = document.getElementById('pac-input'); var types = document.getElementById('type-selector'); var strictBounds = document.getElementById('strict-bounds-selector'); map.controls[google.maps.ControlPosition.TOP_RIGHT].push(card); var autocomplete = new google.maps.places.Autocomplete(input); autocomplete.bindTo('bounds', map); var infowindow = new google.maps.InfoWindow(); var infowindowContent = document.getElementById('infowindow-content'); infowindow.setContent(infowindowContent); var marker = new google.maps.Marker({ map: map, draggable: true, anchorPoint: new google.maps.Point(0, -29) }); marker.addListener('dragend', function(e) { geocodeLatLng(geocoder, e.latLng); parent.document.getElementById("loc").value = e.latLng.lat()+","+e.latLng.lng(); infowindowContent.children['place-address'].textContent = 'LatLng '+e.latLng; infowindow.open(map, marker); }); autocomplete.addListener('place_changed', function() { infowindow.close(); marker.setVisible(false); var place = autocomplete.getPlace(); if (!place.geometry) { window.alert("No details available for input: '" + place.name + "'"); return; } if (place.geometry.viewport) { map.fitBounds(place.geometry.viewport); } else { map.setCenter(place.geometry.location); map.setZoom(20); } marker.setPosition(place.geometry.location); marker.setVisible(true); var address = ''; if (place.address_components) { address = [ (place.address_components[0] && place.address_components[0].short_name || ''), (place.address_components[1] && place.address_components[1].short_name || ''), (place.address_components[2] && place.address_components[2].short_name || '') ].join(' '); } infowindowContent.children['place-icon'].src = place.icon; infowindowContent.children['place-name'].textContent = place.name; var lat = place.geometry.location.lat(); var lng = place.geometry.location.lng(); parent.document.getElementById("loc").value = lat+","+lng; geocodeLatLng(geocoder, place.geometry.location); infowindowContent.children['place-address'].textContent = "LatLng ("+lat+","+lng+")"; infowindow.open(map, marker); }); function setupClickListener(id, types) { var radioButton = document.getElementById(id); radioButton.addEventListener('click', function() { autocomplete.setTypes(types); }); } setupClickListener('changetype-all', []); setupClickListener('changetype-address', ['address']); setupClickListener('changetype-establishment', ['establishment']); setupClickListener('changetype-geocode', ['geocode']); document.getElementById('use-strict-bounds') .addEventListener('click', function() { console.log('Checkbox clicked! New state=' + this.checked); autocomplete.setOptions({strictBounds: this.checked}); }); } function geocodeLatLng(geocoder, latlng) { geocoder.geocode({'location': latlng}, function(results, status) { if (status === 'OK') { if (results[1]) { parent.document.getElementById("address").innerHTML = results[1].formatted_address; } else { window.alert('No results found'); } } else { window.alert('Geocoder failed due to: ' + status); } }); } ``` -------------------------------- ### Decompile APK and Analyze Bytecode Source: https://github.com/ac-pm/inspeckage/blob/master/app/src/main/assets/HTMLFiles/content/tips.html Translate Dalvik bytecode to Java bytecode using Enjarify, then analyze the resulting JAR file with JD-GUI. ```bash enjarify yourapp.apk -o yourapp.jar ``` ```bash java -jar jd-gui.jar ``` -------------------------------- ### Common ADB Commands for Inspeckage Source: https://context7.com/ac-pm/inspeckage/llms.txt Shell commands for managing the Inspeckage module, forwarding ports, and filtering Xposed logs. ```bash # Install Inspeckage module adb install mobi.acpm.inspeckage.apk # Uninstall Inspeckage adb uninstall mobi.acpm.inspeckage # Forward port to access web interface adb forward tcp:8008 tcp:8008 # Access Inspeckage web interface # Open browser: http://localhost:8008 # View Xposed logs (Inspeckage output) adb logcat -s "Xposed" | grep "Inspeckage" # Filter specific hook types adb logcat | grep "Inspeckage_Crypto" adb logcat | grep "Inspeckage_Prefs" adb logcat | grep "Inspeckage_SQLite" # Launch target app for analysis adb shell am start -n com.target.app/.MainActivity # Clear Inspeckage data adb shell rm -rf /sdcard/Inspeckage/* ``` -------------------------------- ### Implement Device Fingerprint Spoofing with Xposed Source: https://context7.com/ac-pm/inspeckage/llms.txt Uses XposedHelpers to intercept and modify system properties and method return values for device identification. Requires a JSON configuration to define which identifiers to spoof. ```java // FingerprintHook.java - Spoof device identifiers public class FingerprintHook extends XC_MethodHook { public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) { loadPrefs(); String json = sPrefs.getString("fingerprint_hooks", ""); Class classBuild = XposedHelpers.findClass("android.os.Build", loadPackageParam.classLoader); Class classBuildVersion = XposedHelpers.findClass("android.os.Build.VERSION", loadPackageParam.classLoader); try { FingerprintList fingerprintList = gson.fromJson(json, FingerprintList.class); for (FingerprintItem item : fingerprintList.fingerprintItems) { if (item.enable) { // Spoof Build properties (BRAND, MODEL, DEVICE, etc.) if (item.type.equals("BUILD")) { XposedHelpers.setStaticObjectField(classBuild, item.name, item.newValue); } // Spoof Build.VERSION properties (SDK_INT, RELEASE) else if (item.type.equals("VERSION")) { XposedHelpers.setStaticObjectField(classBuildVersion, item.name, item.newValue); } // Spoof TelephonyManager values else if (item.type.equals("TelephonyManager")) { switch (item.name) { case "IMEI": HookFingerprintItem("android.telephony.TelephonyManager", loadPackageParam, "getDeviceId", item.newValue); break; case "PhoneNumber": HookFingerprintItem("android.telephony.TelephonyManager", loadPackageParam, "getLine1Number", item.newValue); break; } } // Spoof WiFi information else if (item.type.equals("Wi-Fi")) { switch (item.name) { case "BSSID": HookFingerprintItem("android.net.wifi.WifiInfo", loadPackageParam, "getBSSID", item.newValue); break; case "Android": // MAC address byte[] mac = Util.macAddressToByteArr(item.newValue); HookFingerprintItem("java.net.NetworkInterface", loadPackageParam, "getHardwareAddress", mac); break; } } // Spoof Advertising ID else if (item.type.equals("Advertising")) { HookFingerprintItem( "com.google.android.gms.ads.identifier.AdvertisingIdClient$Info", loadPackageParam, "getId", item.newValue); } } } } catch (JsonSyntaxException ex) { } } private static void HookFingerprintItem(String hookClass, XC_LoadPackage.LoadPackageParam loadPkgParam, String methodName, final Object value) { XposedHelpers.findAndHookMethod(hookClass, loadPkgParam.classLoader, methodName, new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { param.setResult(value); } }); } } // Fingerprint configuration JSON format: // {"fingerprintItems":[ // {"name":"BRAND","type":"BUILD","enable":true,"newValue":"Samsung"}, // {"name":"IMEI","type":"TelephonyManager","enable":true,"newValue":"123456789012345"}, // {"name":"Android","type":"Wi-Fi","enable":true,"newValue":"00:11:22:33:44:55"} // ]} ``` -------------------------------- ### Monitor SharedPreferences access with Xposed Source: https://context7.com/ac-pm/inspeckage/llms.txt Hooks into ContextWrapper and SharedPreferencesImpl to log file access and data modification operations. Requires the Xposed framework to function. ```java // SharedPrefsHook.java - Monitor SharedPreferences access public class SharedPrefsHook extends XC_MethodHook { public static final String TAG = "Inspeckage_Prefs:"; public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) { // Monitor SharedPreferences file access findAndHookMethod(ContextWrapper.class, "getSharedPreferences", String.class, "int", new XC_MethodHook() { protected void afterHookedMethod(MethodHookParam param) throws Throwable { int modeId = (Integer) param.args[1]; String mode = modeId == 1 ? "MODE_PRIVATE" : modeId == 2 ? "MODE_WORLD_WRITEABLE" : "APPEND or MULTI_PROCESS"; putFileName = "PUT[" + (String) param.args[0] + ".xml , " + mode + "]"; } }); // Monitor getString operations findAndHookMethod("android.app.SharedPreferencesImpl", loadPackageParam.classLoader, "getString", String.class, String.class, new XC_MethodHook() { protected void afterHookedMethod(MethodHookParam param) throws Throwable { File f = (File) getObjectField(param.thisObject, "mFile"); XposedBridge.log(TAG + "GET[" + f.getName() + "] String(" + (String) param.args[0] + " , " + (String) param.getResult() + ")"); } }); // Monitor putString operations findAndHookMethod("android.app.SharedPreferencesImpl.EditorImpl", loadPackageParam.classLoader, "putString", String.class, String.class, new XC_MethodHook() { protected void afterHookedMethod(MethodHookParam param) throws Throwable { sb.append(putFileName + " String(" + (String) param.args[0] + "," + (String) param.args[1] + "),"); } }); // Monitor putBoolean operations findAndHookMethod("android.app.SharedPreferencesImpl.EditorImpl", loadPackageParam.classLoader, "putBoolean", String.class, "boolean", new XC_MethodHook() { protected void afterHookedMethod(MethodHookParam param) throws Throwable { sb.append(putFileName + " Boolean(" + (String) param.args[0] + "," + String.valueOf(param.args[1]) + "),"); } }); } } ``` -------------------------------- ### Backup and Extract Android App Data Source: https://github.com/ac-pm/inspeckage/blob/master/app/src/main/assets/HTMLFiles/content/tips.html Use ADB to create a backup file and the Android Backup Extractor to unpack it into a tar archive. ```bash adb backup -f backup.ab app.package.name ``` ```bash abe unpack backup.ab backup.tar ``` -------------------------------- ### Execute monkeyrunner Script Source: https://github.com/ac-pm/inspeckage/blob/master/app/src/main/assets/HTMLFiles/content/tips.html Command to run the automated test script. ```bash monkeyrunner startfox.py ``` -------------------------------- ### Automate Android Testing with monkeyrunner Source: https://github.com/ac-pm/inspeckage/blob/master/app/src/main/assets/HTMLFiles/content/tips.html A Python script for monkeyrunner to connect to a device and launch an application. ```python from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice import commands import sys # starting script print "start" # connection to the current device device = MonkeyRunner.waitForConnection() print "launching firefox: Package=org.mozilla.firefox and Main Activity=org.mozilla.gecko.BrowserApp" device.startActivity(component='org.mozilla.firefox/org.mozilla.gecko.BrowserApp') #wait MonkeyRunner.sleep(3) print "end of script" ``` -------------------------------- ### Inspeckage Web Server API Endpoints Source: https://context7.com/ac-pm/inspeckage/llms.txt Java methods implementing REST-like endpoints for the NanoHTTPD web server. These endpoints are accessible via http://:8008/. ```java // WebServer.java - HTTP API endpoints // Access via: http://:8008/?type= // Start the target application // GET /?type=startapp public void startApp() { PackageDetail pd = new PackageDetail(mContext, mPrefs.getString(Config.SP_PACKAGE, "")); Intent i = pd.getLaunchIntent(); mContext.startActivity(i); } // Stop the target application // GET /?type=finishapp public void finishApp() { Intent intent = new Intent("mobi.acpm.inspeckage.INSPECKAGE_FILTER"); intent.putExtra("package", mPrefs.getString(Config.SP_PACKAGE, "")); intent.putExtra("action", "finish"); mContext.sendBroadcast(intent, null); } // Download the target APK // GET /?type=downapk public Response downloadApk() { String absolutePath = mPrefs.getString(Config.SP_APK_DIR, ""); FileInputStream f = new FileInputStream(absolutePath); Response res = newChunkedResponse(Response.Status.OK, "application/vnd.android.package-archive", f); res.addHeader("Content-Disposition", "attachment;filename=" + mPrefs.getString(Config.SP_PACKAGE, "") + ".apk"); return res; } // Take screenshot of target app // GET /?type=screenshot public Response takeScreenshot() { String fileName = String.valueOf(Calendar.getInstance().getTimeInMillis()) + ".png"; Util.takeScreenshot(fileName); FileInputStream f = new FileInputStream(sdcardPath + Config.P_ROOT + "/" + fileName); Response res = newChunkedResponse(Response.Status.OK, "image/png", f); res.addHeader("Content-Disposition", "attachment;filename=" + fileName); return res; } // Enable/disable SSL unpinning // GET /?type=sslunpinning&sslswitch=true private String sslUnpinning(Map parms) { String ssl_switch = parms.get("sslswitch"); if (ssl_switch != null) { SharedPreferences.Editor edit = mPrefs.edit(); edit.putBoolean(Config.SP_UNPINNING, Boolean.valueOf(ssl_switch)); edit.apply(); } return "#sslunpinning#"; } // Configure proxy settings // GET /?type=proxy&host=192.168.1.100&port=8080 private String proxy(Map parms) { String host = parms.get("host"); String port = parms.get("port"); if (host != null && port != null) { SharedPreferences.Editor edit = mPrefs.edit(); edit.putString(Config.SP_PROXY_PORT, port); edit.putString(Config.SP_PROXY_HOST, host); edit.apply(); } return "#proxy#"; } // Add custom hooks dynamically // GET /?type=adduserhooks&jhooks=[{"id":1,"className":"com.example.Class","method":"test","state":true}] private Response addUserHooks(Map parms) { String json = parms.get("jhooks"); SharedPreferences.Editor edit = mPrefs.edit(); edit.putString(Config.SP_USER_HOOKS, json); edit.apply(); return ok("OK"); } // Set spoofed GPS location // GET /?type=location&geolocation=40.7128,-74.0060 private Response addLocation(Map parms) { String loc = parms.get("geolocation"); SharedPreferences.Editor edit = mPrefs.edit(); edit.putString(Config.SP_GEOLOCATION, loc); edit.apply(); return ok("OK"); } ``` -------------------------------- ### Bypass JSSE TrustManagerFactory and SSLContext Initialization Source: https://context7.com/ac-pm/inspeckage/llms.txt Hooks JSSE's TrustManagerFactory and SSLContext to bypass certificate pinning. Requires preferences to be loaded to determine if unpinning is enabled. ```java // SSLPinningHook.java - Bypass certificate pinning public class SSLPinningHook extends XC_MethodHook { public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) { // Bypass JSSE TrustManagerFactory findAndHookMethod("javax.net.ssl.TrustManagerFactory", loadPackageParam.classLoader, "getTrustManagers", new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { loadPrefs(); if (sPrefs.getBoolean("sslunpinning", false)) { param.setResult(EmptyTrustManager.getInstance()); } } }); // Bypass SSLContext initialization findAndHookMethod("javax.net.ssl.SSLContext", loadPackageParam.classLoader, "init", KeyManager[].class, TrustManager[].class, SecureRandom.class, new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { loadPrefs(); if (sPrefs.getBoolean("sslunpinning", false)) { param.args[0] = null; param.args[1] = EmptyTrustManager.getInstance(); param.args[2] = null; } } }); // Bypass OkHttp3 certificate pinner try { findAndHookMethod("okhttp3.CertificatePinner", loadPackageParam.classLoader, "findMatchingPins", String.class, new XC_MethodHook() { protected void beforeHookedMethod(MethodHookParam param) throws Throwable { loadPrefs(); if (sPrefs.getBoolean("sslunpinning", false)) { param.args[0] = ""; // Empty hostname returns no pins } } }); } catch (Error e) { Module.logError(e); } } } ``` -------------------------------- ### EmptyTrustManager Implementation Source: https://context7.com/ac-pm/inspeckage/llms.txt Provides a TrustManager implementation that accepts all certificates, effectively disabling server certificate validation. Used to bypass SSL certificate pinning. ```java // EmptyTrustManager implementation that accepts all certificates class EmptyTrustManager implements X509TrustManager { private static TrustManager[] emptyTM = null; public static TrustManager[] getInstance() { if (emptyTM == null) { emptyTM = new TrustManager[]{new EmptyTrustManager()}; } return emptyTM; } @Override public void checkClientTrusted(X509Certificate[] chain, String authType) {} @Override public void checkServerTrusted(X509Certificate[] chain, String authType) {} @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } } ``` -------------------------------- ### Monitor Cryptographic Operations with CryptoHook Source: https://context7.com/ac-pm/inspeckage/llms.txt Uses Xposed method hooks to intercept and log cryptographic parameters and results. Requires the Xposed framework and appropriate permissions to hook into the target package. ```java // CryptoHook.java - Monitor encryption/decryption operations public class CryptoHook extends XC_MethodHook { public static final String TAG = "Inspeckage_Crypto:"; private static StringBuffer sb; public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) { // Hook SecretKeySpec constructor to capture encryption keys findAndHookConstructor(SecretKeySpec.class, byte[].class, String.class, new XC_MethodHook() { protected void afterHookedMethod(MethodHookParam param) throws Throwable { sb = new StringBuffer(); sb.append("SecretKeySpec(" + Util.byteArrayToString((byte[]) param.args[0]) + "," + (String) param.args[1] + ")"); } }); // Hook Cipher.doFinal to capture plaintext and ciphertext findAndHookMethod(Cipher.class, "doFinal", byte[].class, new XC_MethodHook() { protected void afterHookedMethod(MethodHookParam param) throws Throwable { if (sb == null) sb = new StringBuffer(); sb.append(" (" + Util.byteArrayToString((byte[]) param.args[0]) + " , "); sb.append(Util.byteArrayToString((byte[]) param.getResult()) + ")"); XposedBridge.log(TAG + sb.toString()); sb = new StringBuffer(); } }); // Hook IvParameterSpec to capture initialization vectors findAndHookConstructor(IvParameterSpec.class, byte[].class, new XC_MethodHook() { protected void afterHookedMethod(MethodHookParam param) throws Throwable { if (sb == null) sb = new StringBuffer(); sb.append(" IV: " + Util.byteArrayToString((byte[]) param.args[0])); } }); // Hook PBEKeySpec to capture password-based key derivation findAndHookConstructor(PBEKeySpec.class, char[].class, byte[].class, int.class, int.class, new XC_MethodHook() { protected void afterHookedMethod(MethodHookParam param) throws Throwable { sb = new StringBuffer(); sb.append("[PBEKeySpec] - Password: " + String.valueOf((char[])param.args[0]) + " || Salt: " + Util.byteArrayToString((byte[])param.args[1])); XposedBridge.log(TAG + sb.toString()); } }); } } ``` -------------------------------- ### Monitor WebView Security with WebViewHook Source: https://context7.com/ac-pm/inspeckage/llms.txt Monitors WebView operations including URL loading, JavaScript interface injection, and security settings. Logs potential vulnerabilities and security configuration. ```java // WebViewHook.java - Monitor WebView security public class WebViewHook extends XC_MethodHook { public static final String TAG = "Inspeckage_WebView:"; public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) { // Monitor JavaScript interface injection (potential security risk) findAndHookMethod(WebView.class, "addJavascriptInterface", Object.class, String.class, new XC_MethodHook() { protected void beforeHookedMethod(MethodHookParam param) throws Throwable { String objName = (String) param.args[1]; XposedBridge.log(TAG + "addJavascriptInterface(Object, " + objName + ");"); } }); // Monitor URL loading with security settings findAndHookMethod(WebView.class, "loadUrl", String.class, new XC_MethodHook() { protected void beforeHookedMethod(MethodHookParam param) throws Throwable { StringBuilder sb = new StringBuilder(); WebView wv = (WebView) param.thisObject; sb.append("Load URL: " + param.args[0]); sb.append(checkSettings(wv)); XposedBridge.log(TAG + sb.toString()); } }); // Monitor WebView debugging mode findAndHookMethod(WebView.class, "setWebContentsDebuggingEnabled", "boolean", new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { boolean value = (boolean) param.args[0]; XposedBridge.log(TAG + "Web Contents Debugging Enabled: " + String.valueOf(value)); } }); } // Check WebView security configuration static String checkSettings(WebView wv) { String r = "
"; r += wv.getSettings().getJavaScriptEnabled() ? " -- JavaScript: Enable
" : " -- JavaScript: Disable
"; r += wv.getSettings().getPluginState() == WebSettings.PluginState.OFF ? " -- Plugin State: OFF
" : " -- Plugin State: ON
"; r += wv.getSettings().getAllowFileAccess() ? " -- Allow File Access: Enable
" : " -- Allow File Access: Disable
"; return r; } } // Example output: // Inspeckage_WebView: addJavascriptInterface(Object, AndroidBridge); // Inspeckage_WebView: Load URL: https://example.com/api // -- JavaScript: Enable // -- Plugin State: OFF // -- Allow File Access: Enable ``` -------------------------------- ### CSS Styles for Map and Autocomplete UI Source: https://github.com/ac-pm/inspeckage/blob/master/app/src/main/assets/HTMLFiles/content/maps.html Defines the layout and appearance for the map container, info windows, and the autocomplete input card. ```css #map { height: 100%; } html, body { height: 100%; margin: 0; padding: 0; } #description { font-family: Roboto; font-size: 15px; font-weight: 300; } #infowindow-content .title { font-weight: bold; } #infowindow-content { display: none; } #map #infowindow-content { display: inline; } .pac-card { margin: 10px 10px 0 0; border-radius: 2px 0 0 2px; box-sizing: border-box; -moz-box-sizing: border-box; outline: none; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); background-color: #fff; font-family: Roboto; } #pac-container { padding-bottom: 12px; margin-right: 12px; } .pac-controls { display: inline-block; padding: 5px 11px; } .pac-controls label { font-family: Roboto; font-size: 13px; font-weight: 300; } #pac-input { background-color: #fff; font-family: Roboto; font-size: 15px; font-weight: 300; margin-left: 12px; padding: 0 11px 0 13px; text-overflow: ellipsis; width: 400px; } #pac-input:focus { border-color: #4d90fe; } #title { color: #fff; background-color: #4d90fe; font-size: 25px; font-weight: 500; padding: 6px 12px; } ``` -------------------------------- ### Configure Class Hook Tree View Source: https://github.com/ac-pm/inspeckage/blob/master/app/src/main/assets/HTMLFiles/index.html Initializes a jstree component to handle class and method selection for hooking, updating input fields upon selection. ```javascript $('#jstree-classes').on("changed.jstree", function(e, data) { if (data.selected.length) { if (!data.instance.is_parent(data.selected[0])) { document.getElementById('method').value = data.instance.get_node(data.selected[0]).text; document.getElementById('className').value = data.instance.get_parent(data.selected[0]); } } }).jstree({ 'core': { 'data': { "url": "./struct", "dataType": "json" } } }); ``` -------------------------------- ### JSON Format for Custom Hooks Source: https://context7.com/ac-pm/inspeckage/llms.txt This JSON structure defines custom hooks for runtime modification. Each object specifies the target class, method (optional, if empty, all methods are targeted), whether to hook constructors, and the active state of the hook. Ensure the 'state' field is true to enable the hook. ```json [ {"id":1,"className":"com.example.app.LoginManager","method":"authenticate","constructor":false,"state":true}, {"id":2,"className":"com.example.app.CryptoUtil","method":"","constructor":true,"state":true} ] ``` -------------------------------- ### Hook SQLite Database Operations in Java Source: https://context7.com/ac-pm/inspeckage/llms.txt This Java code hooks into SQLiteDatabase methods to log raw SQL execution, insert operations, and query results. It requires the Xposed framework and is intended for use within an Android application context. ```java // SQLiteHook.java - Monitor database operations public class SQLiteHook extends XC_MethodHook { public static final String TAG = "Inspeckage_SQLite:"; public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) { // Hook execSQL for raw SQL execution findAndHookMethod(SQLiteDatabase.class, "execSQL", String.class, new XC_MethodHook() { protected void afterHookedMethod(MethodHookParam param) throws Throwable { XposedBridge.log(TAG + "execSQL(" + param.args[0] + ")"); } }); // Hook insert operations findAndHookMethod(SQLiteDatabase.class, "insert", String.class, String.class, ContentValues.class, new XC_MethodHook() { protected void afterHookedMethod(MethodHookParam param) throws Throwable { ContentValues contentValues = (ContentValues) param.args[2]; StringBuffer sb = new StringBuffer(); for (Map.Entry entry : contentValues.valueSet()) { sb.append(entry.getKey() + "=" + String.valueOf(entry.getValue()) + ","); } XposedBridge.log(TAG + "INSERT INTO " + param.args[0] + " VALUES(" + sb.toString().substring(0, sb.length() - 1) + ")"); } }); // Hook query operations with result capture findAndHookMethod(SQLiteDatabase.class, "query", String.class, String[].class, String.class, String[].class, String.class, String.class, String.class, String.class, new XC_MethodHook() { protected void afterHookedMethod(MethodHookParam param) throws Throwable { String table = (String) param.args[0]; Cursor cursor = (Cursor) param.getResult(); StringBuffer result = new StringBuffer(); if (cursor != null && cursor.moveToFirst()) { do { int x = cursor.getColumnCount(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < x; i++) { sb.append(cursor.getColumnName(i) + "=" + cursor.getString(i) + ","); } result.append(sb.toString().substring(0, sb.length() - 1) + "\n"); } while (cursor.moveToNext()); } XposedBridge.log(TAG + "SELECT * FROM " + table + "\n" + result.toString()); } }); // Hook SQLCipher encrypted database operations try { findAndHookMethod("net.sqlcipher.database.SQLiteDatabase", loadPackageParam.classLoader, "openOrCreateDatabase", File.class, String.class, "net.sqlcipher.database.SQLiteDatabase.CursorFactory", new XC_MethodHook() { protected void afterHookedMethod(MethodHookParam param) throws Throwable { File f = (File) param.args[0]; String passwd = (String) param.args[1]; XposedBridge.log(TAG + "[SQLCipher] Open or Create:" + f.getName() + " with password: " + passwd); } }); } catch (XposedHelpers.ClassNotFoundError e) { } } } ``` -------------------------------- ### Spoof GPS Coordinates with LocationHook Source: https://context7.com/ac-pm/inspeckage/llms.txt Hooks into the Android Location API to spoof GPS coordinates. Requires setting location via web interface or preferences in 'latitude,longitude' format. ```java // LocationHook.java - Spoof GPS coordinates public class LocationHook extends XC_MethodHook { public static final String TAG = "Inspeckage_Location: "; public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) { try { Class location = XposedHelpers.findClass("android.location.Location", loadPackageParam.classLoader); // Hook getLatitude to return spoofed latitude findAndHookMethod(location, "getLatitude", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { loadPrefs(); String geolocation = sPrefs.getString("geoloc", ""); if (!geolocation.equals("") && geolocation.contains(",")) { final String[] latlng = geolocation.split(","); param.setResult(Double.valueOf(latlng[0])); } } }); // Hook getLongitude to return spoofed longitude findAndHookMethod(location, "getLongitude", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { loadPrefs(); String geolocation = sPrefs.getString("geoloc", ""); if (!geolocation.equals("") && geolocation.contains(",")) { final String[] latlng = geolocation.split(","); param.setResult(Double.valueOf(latlng[1])); } } }); } catch (XposedHelpers.ClassNotFoundError ex) { } } } // Usage: Set location via web interface or preferences // Format: "latitude,longitude" (e.g., "40.7128,-74.0060" for New York) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.