├── .gitignore ├── .idea ├── .name ├── codeStyles │ └── Project.xml ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── inspectionProfiles │ ├── Project_Default.xml │ └── profiles_settings.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── CHANGELOG ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── mobi │ │ └── acpm │ │ └── inspeckage │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── assets │ ├── HTMLFiles │ │ ├── content │ │ │ ├── fingerprint.html │ │ │ ├── location.html │ │ │ ├── maps.html │ │ │ ├── replace.html │ │ │ ├── tabs.html │ │ │ └── tips.html │ │ ├── css │ │ │ ├── 32px.png │ │ │ ├── animate.min.css │ │ │ ├── bootstrap-editable.css │ │ │ ├── bootstrap-switch.css │ │ │ ├── bootstrap-table.min.css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap-theme.min.css.map │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ ├── bootstrap.min.css │ │ │ ├── bootstrap.min.css.map │ │ │ ├── normalize.css │ │ │ ├── style.css │ │ │ ├── style.min.css │ │ │ └── throbber.gif │ │ ├── img │ │ │ ├── favicon-16.png │ │ │ ├── favicon-32.png │ │ │ ├── favicon.ico │ │ │ ├── inspeckage.svg │ │ │ └── sponsored.svg │ │ ├── index.html │ │ ├── js │ │ │ ├── CollapsibleLists.compressed.js │ │ │ ├── base.js │ │ │ ├── bootstrap-editable.min.js │ │ │ ├── bootstrap-switch.js │ │ │ ├── bootstrap-table-editable.min.js │ │ │ ├── bootstrap-table.min.js │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ ├── fingerprint.js │ │ │ ├── jquery-1.10.2.js │ │ │ ├── jquery-ui.js │ │ │ ├── jquery.min.js │ │ │ ├── jquery.min.map │ │ │ ├── jstree.min.js │ │ │ ├── logcat.js │ │ │ ├── menu.js │ │ │ ├── npm.js │ │ │ ├── plushooks.js │ │ │ ├── prototype.min.js │ │ │ └── tabs.js │ │ └── logcat.html │ └── xposed_init │ ├── java │ └── mobi │ │ └── acpm │ │ └── inspeckage │ │ ├── Module.java │ │ ├── hooks │ │ ├── ClipboardHook.java │ │ ├── CryptoHook.java │ │ ├── FileSystemHook.java │ │ ├── FingerprintHook.java │ │ ├── FlagSecureHook.java │ │ ├── HashHook.java │ │ ├── HttpHook.java │ │ ├── IPCHook.java │ │ ├── MiscHook.java │ │ ├── ProcessHook.java │ │ ├── ProxyHook.java │ │ ├── SQLiteHook.java │ │ ├── SSLPinningHook.java │ │ ├── SerializationHook.java │ │ ├── SharedPrefsHook.java │ │ ├── UIHook.java │ │ ├── UserHooks.java │ │ ├── WebViewHook.java │ │ └── entities │ │ │ ├── FingerprintItem.java │ │ │ ├── FingerprintList.java │ │ │ └── LocationHook.java │ │ ├── log │ │ ├── LogService.java │ │ └── WSocketServer.java │ │ ├── receivers │ │ ├── InspeckageReceiver.java │ │ └── InspeckageWebReceiver.java │ │ ├── ui │ │ ├── AuthFragment.java │ │ ├── ConfigFragment.java │ │ ├── ExpandableListAdapter.java │ │ ├── ExpandableListItem.java │ │ ├── MainActivity.java │ │ ├── MainFragment.java │ │ └── SplashActivity.java │ │ ├── util │ │ ├── Config.java │ │ ├── DexUtil.java │ │ ├── FileType.java │ │ ├── FileUtil.java │ │ ├── Fingerprint.java │ │ ├── PackageDetail.java │ │ ├── Replacement.java │ │ └── Util.java │ │ └── webserver │ │ ├── InspeckageService.java │ │ └── WebServer.java │ └── res │ ├── drawable-hdpi-v11 │ └── inspectorw.png │ ├── drawable-hdpi-v9 │ └── inspectorw.png │ ├── drawable-hdpi │ └── inspectorw.png │ ├── drawable-mdpi-v11 │ └── inspectorw.png │ ├── drawable-mdpi-v9 │ └── inspectorw.png │ ├── drawable-mdpi │ └── inspectorw.png │ ├── drawable-xhdpi-v11 │ └── inspectorw.png │ ├── drawable-xhdpi-v9 │ └── inspectorw.png │ ├── drawable-xhdpi │ └── inspectorw.png │ ├── drawable-xxhdpi-v11 │ └── inspectorw.png │ ├── drawable-xxhdpi-v9 │ └── inspectorw.png │ ├── drawable-xxhdpi │ └── inspectorw.png │ ├── drawable │ ├── background_splash.xml │ ├── btn_shape.xml │ ├── ic_autorenew_24dp.xml │ ├── ic_check_box_outline_blank_24dp.xml │ ├── ic_exit_to_app_24dp.xml │ ├── ic_play_circle_fill_24dp.xml │ ├── ic_settings_24dp.xml │ ├── ic_vpn_key_black_24dp.xml │ ├── inspeckage.png │ ├── side_nav_bar.xml │ └── sponsored.png │ ├── layout │ ├── activity_inspeckage.xml │ ├── activity_main.xml │ ├── activity_splash.xml │ ├── app_bar_main.xml │ ├── content_main.xml │ ├── fragment_auth.xml │ ├── fragment_config.xml │ ├── fragment_main.xml │ ├── list_group.xml │ ├── list_item.xml │ └── nav_header_main.xml │ ├── menu │ ├── activity_main_drawer.xml │ ├── main.xml │ └── menu_inspeckage.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values-ru │ └── strings.xml │ ├── values-v21 │ └── styles.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── dimens.xml │ ├── drawables.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | /local.properties 2 | /.idea/workspace.xml 3 | /.idea/libraries 4 | .DS_Store 5 | 6 | # Built application files 7 | *.ap_ 8 | 9 | # Files for the Dalvik VM 10 | *.dex 11 | 12 | # Java class files 13 | *.class 14 | 15 | # Generated files 16 | bin/ 17 | gen/ 18 | out/ 19 | 20 | # Gradle files 21 | .gradle/ 22 | build/ 23 | 24 | # Local configuration file (sdk path, etc) 25 | local.properties 26 | 27 | # Proguard folder generated by Eclipse 28 | proguard/ 29 | 30 | # Log Files 31 | *.log 32 | 33 | # Android Studio Navigation editor temp files 34 | .navigation/ 35 | 36 | # Android Studio captures folder 37 | captures/ 38 | 39 | # Intellij 40 | *.iml 41 | 42 | # Keystore files 43 | *.jks -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | Inspeckage -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | # Inspeckage - CHANGELOG 2 | 3 | 2.3 4 | --------------- 5 | - Device Fingerprint - override more than 30 parameters such as advertising id, MAC address, IMEI, release, brand, build mode... 6 | - Location - without use "Mock location" functionality, change GPS location to the searched location on the map or enter latitude/longitude 7 | - bug fix 8 | 9 | 2.2 10 | --------------- 11 | - Replaces - now you can replace parameters/return value of hooked methods (+Hooks) 12 | - Sidebar menu (so far) 13 | * Tabs - hooks 14 | * Replaces - shortcut to the Replaces feature 15 | * Tips - some tips about monkeyrunner, decompile, proxy, etc. 16 | * clipboard input 17 | * share options 18 | - "clear log" option in all tabs 19 | - bug fix 20 | 21 | 2.1 22 | --------------- 23 | - Classes and Methods tree in +Hooks modal - now you can see all classes and methods of your target, select any method and add with new Hook! 24 | - bug fix 25 | 26 | 2.0 27 | --------------- 28 | - New menu option "SSL / Authentication" (only Android 6) - Now you can use https with basic authentication. 29 | - SSL uncheck (pinning bypass) - okhttp3 30 | - Android 6 permissions fix 31 | 32 | 1.4.1 33 | --------------- 34 | 35 | - add the option "Bind to address" on "Config" app screen - now you can bind to all interfaces, any specific local IP address, or to just the loopback interface. 36 | Note: if you choose a non-loopback interface, other computers maybe can access the Inspeckage. 37 | - bug fix - the "App is running:" always false 38 | 39 | 1.4 40 | --------------- 41 | 42 | - tabs with badges (counter); 43 | - for "+ Hooks", FLAG_SECURE and proxy options you dont need restart the app; 44 | - enable/disable hooks (tabs); 45 | - support to android 4.x (experimental); 46 | - android:allowBackup in info area; 47 | - app icon in info area; 48 | - some bug fixes. 49 | 50 | 1.3 51 | --------------- 52 | 53 | - New tab "+ Hooks". Now the user can specify new hook's dynamically. 54 | - collapsible app info area 55 | - some bug fixes 56 | 57 | 1.2 58 | --------------- 59 | 60 | New logcat.html page. A experimental page with websocket to show some information from the logcat. 61 | 62 | 1.1b 63 | --------------- 64 | 65 | Fix the backpressed crash 66 | Fix intent launch not found 67 | Improvements in the Start Activity option 68 | 69 | 1.0b 70 | --------------- 71 | 72 | With Inspeckage, we can get a good amount of information about the application's behavior: 73 | 74 | == Information gathering 75 | 76 | * Requested Permissions; 77 | * App Permissions; 78 | * Shared Libraries; 79 | * Exported and Non-exported Activities, Content Providers,Broadcast Receivers and Services; 80 | * Check if the app is debuggable or not; 81 | * Version, UID and GIDs; 82 | * etc. 83 | 84 | == Hooks (so far) 85 | 86 | With the hooks, we can see what the application is doing in real time: 87 | 88 | * Shared Preferences (log and file); 89 | * Serialization; 90 | * Crypto; 91 | * Hashes; 92 | * SQLite; 93 | * HTTP (an HTTP proxy tool is still the best alternative); 94 | * File System; 95 | * Miscellaneous (Clipboard, URL.Parse()); 96 | * WebView; 97 | * IPC. 98 | 99 | == Actions 100 | 101 | With Xposed it's possible to perform actions such as start a unexported activity and much else: 102 | 103 | * Start any activity (exported and unexported); 104 | * Call any provider (exported and unexported); 105 | * Disable FLAG_SECURE; 106 | * SSL uncheck; 107 | * Start, stop and restart the application. 108 | 109 | == Extras 110 | 111 | * APK Download; 112 | * View the app's directory tree; 113 | * Download the app's files; 114 | * Download the output generated by hooks in text file format; 115 | * Take a screen capture; 116 | 117 | == Configuration 118 | 119 | Even though our tool has some hooks to the HTTP libraries, using an external proxy tool is still the best option to analyze the app's traffic. With Inspeckage, you can: 120 | 121 | * Add a proxy to the target app; 122 | * Enable and disable proxy; 123 | * Add entries in the arp table. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Inspeckage - Android Package Inspector 2 | 3 | Inspeckage is a tool developed to offer dynamic analysis of Android applications. By applying hooks to functions of the Android API, Inspeckage will help you understand what an Android application is doing at runtime. 4 | 5 | * http://ac-pm.github.io/Inspeckage 6 | * https://twitter.com/inspeckage 7 | * https://play.google.com/store/apps/details?id=mobi.acpm.inspeckage 8 | * http://repo.xposed.info/module/mobi.acpm.inspeckage 9 | 10 | Features 11 | --------------- 12 | 13 | With Inspeckage, we can get a good amount of information about the application's behavior: 14 | 15 | #### Information gathering 16 | 17 | * Requested Permissions; 18 | * App Permissions; 19 | * Shared Libraries; 20 | * Exported and Non-exported Activities, Content Providers,Broadcast Receivers and Services; 21 | * Check if the app is debuggable or not; 22 | * Version, UID and GIDs; 23 | * etc. 24 | 25 | #### Hooks (so far) 26 | 27 | With the hooks, we can see what the application is doing in real time: 28 | 29 | * Shared Preferences (log and file); 30 | * Serialization; 31 | * Crypto; 32 | * Hashes; 33 | * SQLite; 34 | * HTTP (an HTTP proxy tool is still the best alternative); 35 | * File System; 36 | * Miscellaneous (Clipboard, URL.Parse()); 37 | * WebView; 38 | * IPC; 39 | * + Hooks (add new hooks dynamically) 40 | 41 | #### Actions 42 | 43 | With Xposed it's possible to perform actions such as start a unexported activity and much else: 44 | 45 | * Start any activity (exported and unexported); 46 | * Call any provider (exported and unexported); 47 | * Disable FLAG_SECURE; 48 | * SSL uncheck (bypass certificate pinning - JSSE, Apache and okhttp3); 49 | * Start, stop and restart the application; 50 | * Replace params and return value (+Hooks tab). 51 | 52 | #### Fingerprint 53 | 54 | * Device fingerprint - advertising id, MAC address, IMEI, release, brand, build mode... 55 | 56 | #### Location 57 | 58 | * Change GPS location (without use "Mock location" functionality) 59 | 60 | #### Extras 61 | 62 | * APK Download; 63 | * View the app's directory tree; 64 | * Download the app's files; 65 | * Download the output generated by hooks in text file format; 66 | * Take a screen capture; 67 | * Send text to android clipboard. 68 | * Tips - some howto/guide 69 | 70 | #### Configuration 71 | 72 | Even though our tool has some hooks to the HTTP libraries, using an external proxy tool is still the best option to analyze the app's traffic. With Inspeckage, you can: 73 | 74 | * Add a proxy to the target app; 75 | * Enable and disable proxy; 76 | * Add entries in the arp table. 77 | 78 | #### Logcat 79 | 80 | Logcat.html page. A experimental page with websocket to show some information from the logcat. 81 | 82 | Installation 83 | --------------- 84 | Requirements: 85 | Xposed Framework 86 | 87 | ##### Xposed Installer 88 | 89 | 1. Go to Xposed Installer, select "Download" 90 | 2. Refresh and search for "Inspeckage" 91 | 3. Download the latest version and install 92 | 4. Enable it in Xposed 93 | 5. Reboot and enjoy! 94 | 95 | ##### Xposed Repository 96 | 97 | Get it from Xposed repo: http://repo.xposed.info/module/mobi.acpm.inspeckage 98 | 99 | adb install mobi.acpm.inspeckage.apk 100 | 1. Enable it in Xposed 101 | 2. Reboot and enjoy! 102 | 103 | ##### From Source 104 | 105 | Feel free to download the source! 106 | 107 | ### How to uninstall 108 | 109 | adb uninstall mobi.acpm.inspeckage 110 | And reboot! 111 | 112 | ## Genymotion 113 | 114 | [![Genymotion](http://i.imgur.com/2bjhFn2.png)](https://vimeo.com/156745941) 115 | 116 | ### Screenshots 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | License 146 | ------- 147 | 148 | Copyright 2016 ac-pm 149 | 150 | Licensed under the Apache License, Version 2.0 (the "License"); 151 | you may not use this file except in compliance with the License. 152 | You may obtain a copy of the License at 153 | 154 | http://www.apache.org/licenses/LICENSE-2.0 155 | 156 | Unless required by applicable law or agreed to in writing, software 157 | distributed under the License is distributed on an "AS IS" BASIS, 158 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 159 | See the License for the specific language governing permissions and 160 | limitations under the License. 161 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 26 5 | buildToolsVersion '28.0.2' 6 | defaultConfig { 7 | applicationId "mobi.acpm.inspeckage" 8 | minSdkVersion 21 9 | targetSdkVersion 26 10 | versionCode 10 11 | versionName "2.4" 12 | } 13 | 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | 21 | useLibrary 'org.apache.http.legacy' 22 | } 23 | 24 | 25 | dependencies { 26 | implementation fileTree(dir: 'libs', include: ['*.jar']) 27 | compileOnly 'de.robv.android.xposed:api:5+' 28 | implementation 'com.google.code.gson:gson:2+' 29 | implementation group: 'org.nanohttpd', name: 'nanohttpd', version: '2.3.1' 30 | implementation 'com.android.support:appcompat-v7:26.1.0' 31 | implementation 'com.android.support:design:26.1.0' 32 | implementation 'com.android.support:support-v4:26.1.0' 33 | implementation 'org.java-websocket:Java-WebSocket:1.3.0' 34 | implementation 'com.google.android.gms:play-services:12.0.1' 35 | } 36 | -------------------------------------------------------------------------------- /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/acpm/android/sdk/android-sdk-linux/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/mobi/acpm/inspeckage/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage; 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 | 6 | 7 | 8 | 9 | 10 | 11 | 16 | 19 | 22 | 25 | 26 | 30 | 34 | 35 | 40 | 41 | 42 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /app/src/main/assets/HTMLFiles/content/fingerprint.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | Change the current device Fingerprint 4 | 5 |
6 | 9 |
10 |
11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/assets/HTMLFiles/content/location.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 14 | 15 | Location 16 | 17 |
18 |
19 |
20 |
21 | 22 | 23 |
24 |
25 | 26 |

27 |
28 | 29 |
30 | 31 |
32 | 33 |
34 | Saved location 35 |
36 | 37 | #switchLoc# 38 |
39 |
40 |
41 | 44 |
45 |
46 |
47 | -------------------------------------------------------------------------------- /app/src/main/assets/HTMLFiles/content/tips.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |

android:allowBackup the default value of this attribute is true

5 | 6 |
7 |
adb backup -f backup.ab app.package.name
8 |
9 | 10 |

Use Android backup extractor (abe) to extract and repack android backups.

11 | 12 |
13 |
abe unpack backup.ab backup.tar
14 |
15 | 16 | https://developer.android.com/guide/topics/manifest/application-element.html#allowbackup
17 | 18 | https://github.com/nelenkov/android-backup-extractor 19 | 20 | 21 |

Download the .apk through the Inspeckage.Download -> APK

22 | 23 |

Use Google Enjarify tool for translating Dalvik bytecode to equivalent Java bytecode. 24 |

25 |
enjarify yourapp.apk -o yourapp.jar
26 |
27 |

Use JD-GUI to decompile and analyze Java bytecode.

28 | 29 |
30 |
java -jar jd-gui.jar
31 |
32 | 33 | https://github.com/google/enjarify
34 | http://jd.benow.ca/ 35 | 36 | 37 | 38 |

With monkeyrunner, you can write a Python program that run an automated start-to-finish test of an Android application. You provide input values with keystrokes or touch events, and view the results as screenshots.

39 | 40 |

Exemplo: Go to android-sdk-path/tools/ where the monkeyrunner program there is and save in a file startfox.py:

41 |
42 | from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
43 | import commands
44 | import sys
45 |
46 | # starting script
47 | print "start"
48 |
49 | # connection to the current device
50 | device = MonkeyRunner.waitForConnection()
51 |
52 | print "launching firefox: Package=org.mozilla.firefox and Main Activity=org.mozilla.gecko.BrowserApp"
53 | device.startActivity(component='org.mozilla.firefox/org.mozilla.gecko.BrowserApp')
54 |
55 | #wait
56 | MonkeyRunner.sleep(3)
57 |
58 | print "end of script" 59 |
60 | 61 |

Now, run: monkeyrunner startfox.py and the firefox is launched.

62 | 63 | https://developer.android.com/studio/test/monkeyrunner/index.html 64 | 65 | 66 |

1 - Connect both your device and your computer to the same wireless network;

67 |

2 - Choose your favorite http proxy tool and set up a new proxy listenner -- eg. listener address: 192.168.25.22 (computer ip) and port: 8001 (port number that is not currently in use);

68 |

3 - Go to Inspeckage (Settings -> Add Proxy) and set up the same address (192.168.25.22) and port (8001) of your proxy tool;

69 |

4 - Now, open the app (in a feature that makes http request) and the request should be intercepted in your proxy tool.

70 | 71 | OWASP ZAP
72 | Burp Suite Free Edition
73 | Fiddler
74 | 75 | 76 | 77 |

If the app use HTTPS, you need install the proxy tool certificate in your device.

78 | 79 | https://developer.android.com/training/articles/security-ssl.html
80 | OWASP ZAP allows you to transparently decrypt SSL connections.
81 | 82 | 83 | 84 |

If the app use HTTPS and certificate pinning, you need install the proxy tool certificate in your device and bypass the pinning.

85 |

The Inspeckage can disable pinning for some libraries. Settings->SSL uncheck [ON]

86 | 87 |
-------------------------------------------------------------------------------- /app/src/main/assets/HTMLFiles/css/32px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ac-pm/Inspeckage/d8806c9e5f14d44c2e19a331e929d72d6faa4c54/app/src/main/assets/HTMLFiles/css/32px.png -------------------------------------------------------------------------------- /app/src/main/assets/HTMLFiles/css/bootstrap-switch.css: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * bootstrap-switch - v3.3.2 3 | * http://www.bootstrap-switch.org 4 | * ======================================================================== 5 | * Copyright 2012-2013 Mattia Larentis 6 | * 7 | * ======================================================================== 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * ======================================================================== 20 | */ 21 | 22 | .bootstrap-switch { 23 | display: inline-block; 24 | direction: ltr; 25 | cursor: pointer; 26 | border-radius: 4px; 27 | border: 1px solid; 28 | border-color: #cccccc; 29 | position: relative; 30 | text-align: left; 31 | overflow: hidden; 32 | line-height: 8px; 33 | z-index: 0; 34 | -webkit-user-select: none; 35 | -moz-user-select: none; 36 | -ms-user-select: none; 37 | user-select: none; 38 | vertical-align: middle; 39 | -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; 40 | -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; 41 | transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; 42 | } 43 | .bootstrap-switch .bootstrap-switch-container { 44 | display: inline-block; 45 | top: 0; 46 | border-radius: 4px; 47 | -webkit-transform: translate3d(0, 0, 0); 48 | transform: translate3d(0, 0, 0); 49 | } 50 | .bootstrap-switch .bootstrap-switch-handle-on, 51 | .bootstrap-switch .bootstrap-switch-handle-off, 52 | .bootstrap-switch .bootstrap-switch-label { 53 | -webkit-box-sizing: border-box; 54 | -moz-box-sizing: border-box; 55 | box-sizing: border-box; 56 | cursor: pointer; 57 | display: inline-block !important; 58 | height: 100%; 59 | padding: 6px 12px; 60 | font-size: 14px; 61 | line-height: 20px; 62 | } 63 | .bootstrap-switch .bootstrap-switch-handle-on, 64 | .bootstrap-switch .bootstrap-switch-handle-off { 65 | text-align: center; 66 | z-index: 1; 67 | } 68 | .bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-primary, 69 | .bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-primary { 70 | color: #fff; 71 | background: #337ab7; 72 | } 73 | .bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-info, 74 | .bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-info { 75 | color: #fff; 76 | background: #5bc0de; 77 | } 78 | .bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-success, 79 | .bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-success { 80 | color: #fff; 81 | background: #5cb85c; 82 | } 83 | .bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-warning, 84 | .bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-warning { 85 | background: #f0ad4e; 86 | color: #fff; 87 | } 88 | .bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-danger, 89 | .bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-danger { 90 | color: #fff; 91 | background: #d9534f; 92 | } 93 | .bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-default, 94 | .bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-default { 95 | color: #000; 96 | background: #eeeeee; 97 | } 98 | .bootstrap-switch .bootstrap-switch-label { 99 | text-align: center; 100 | margin-top: -1px; 101 | margin-bottom: -1px; 102 | z-index: 100; 103 | color: #333333; 104 | background: #ffffff; 105 | } 106 | .bootstrap-switch .bootstrap-switch-handle-on { 107 | border-bottom-left-radius: 3px; 108 | border-top-left-radius: 3px; 109 | } 110 | .bootstrap-switch .bootstrap-switch-handle-off { 111 | border-bottom-right-radius: 3px; 112 | border-top-right-radius: 3px; 113 | } 114 | .bootstrap-switch input[type='radio'], 115 | .bootstrap-switch input[type='checkbox'] { 116 | position: absolute !important; 117 | top: 0; 118 | left: 0; 119 | margin: 0; 120 | z-index: -1; 121 | opacity: 0; 122 | filter: alpha(opacity=0); 123 | } 124 | .bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-handle-on, 125 | .bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-handle-off, 126 | .bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-label { 127 | padding: 1px 5px; 128 | font-size: 12px; 129 | line-height: 1.5; 130 | } 131 | .bootstrap-switch.bootstrap-switch-small .bootstrap-switch-handle-on, 132 | .bootstrap-switch.bootstrap-switch-small .bootstrap-switch-handle-off, 133 | .bootstrap-switch.bootstrap-switch-small .bootstrap-switch-label { 134 | padding: 5px 10px; 135 | font-size: 12px; 136 | line-height: 1.5; 137 | } 138 | .bootstrap-switch.bootstrap-switch-large .bootstrap-switch-handle-on, 139 | .bootstrap-switch.bootstrap-switch-large .bootstrap-switch-handle-off, 140 | .bootstrap-switch.bootstrap-switch-large .bootstrap-switch-label { 141 | padding: 6px 16px; 142 | font-size: 18px; 143 | line-height: 1.3333333; 144 | } 145 | .bootstrap-switch.bootstrap-switch-disabled, 146 | .bootstrap-switch.bootstrap-switch-readonly, 147 | .bootstrap-switch.bootstrap-switch-indeterminate { 148 | cursor: default !important; 149 | } 150 | .bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-handle-on, 151 | .bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-handle-on, 152 | .bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-handle-on, 153 | .bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-handle-off, 154 | .bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-handle-off, 155 | .bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-handle-off, 156 | .bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-label, 157 | .bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-label, 158 | .bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-label { 159 | opacity: 0.5; 160 | filter: alpha(opacity=50); 161 | cursor: default !important; 162 | } 163 | .bootstrap-switch.bootstrap-switch-animate .bootstrap-switch-container { 164 | -webkit-transition: margin-left 0.5s; 165 | -o-transition: margin-left 0.5s; 166 | transition: margin-left 0.5s; 167 | } 168 | .bootstrap-switch.bootstrap-switch-inverse .bootstrap-switch-handle-on { 169 | border-bottom-left-radius: 0; 170 | border-top-left-radius: 0; 171 | border-bottom-right-radius: 3px; 172 | border-top-right-radius: 3px; 173 | } 174 | .bootstrap-switch.bootstrap-switch-inverse .bootstrap-switch-handle-off { 175 | border-bottom-right-radius: 0; 176 | border-top-right-radius: 0; 177 | border-bottom-left-radius: 3px; 178 | border-top-left-radius: 3px; 179 | } 180 | .bootstrap-switch.bootstrap-switch-focused { 181 | border-color: #66afe9; 182 | outline: 0; 183 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); 184 | box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); 185 | } 186 | .bootstrap-switch.bootstrap-switch-on .bootstrap-switch-label, 187 | .bootstrap-switch.bootstrap-switch-inverse.bootstrap-switch-off .bootstrap-switch-label { 188 | border-bottom-right-radius: 3px; 189 | border-top-right-radius: 3px; 190 | } 191 | .bootstrap-switch.bootstrap-switch-off .bootstrap-switch-label, 192 | .bootstrap-switch.bootstrap-switch-inverse.bootstrap-switch-on .bootstrap-switch-label { 193 | border-bottom-left-radius: 3px; 194 | border-top-left-radius: 3px; 195 | } 196 | -------------------------------------------------------------------------------- /app/src/main/assets/HTMLFiles/css/bootstrap-table.min.css: -------------------------------------------------------------------------------- 1 | .fixed-table-container .bs-checkbox,.fixed-table-container .no-records-found{text-align:center}.fixed-table-body thead th .th-inner,.table td,.table th{box-sizing:border-box}.bootstrap-table .table{margin-bottom:0!important;border-bottom:1px solid #ddd;border-collapse:collapse!important;border-radius:1px}.bootstrap-table .table:not(.table-condensed),.bootstrap-table .table:not(.table-condensed)>tbody>tr>td,.bootstrap-table .table:not(.table-condensed)>tbody>tr>th,.bootstrap-table .table:not(.table-condensed)>tfoot>tr>td,.bootstrap-table .table:not(.table-condensed)>tfoot>tr>th,.bootstrap-table .table:not(.table-condensed)>thead>tr>td{padding:8px}.bootstrap-table .table.table-no-bordered>tbody>tr>td,.bootstrap-table .table.table-no-bordered>thead>tr>th{border-right:2px solid transparent}.bootstrap-table .table.table-no-bordered>tbody>tr>td:last-child{border-right:none}.fixed-table-container{position:relative;clear:both;border:1px solid #ddd;border-radius:4px;-webkit-border-radius:4px;-moz-border-radius:4px}.fixed-table-container.table-no-bordered{border:1px solid transparent}.fixed-table-footer,.fixed-table-header{overflow:hidden}.fixed-table-footer{border-top:1px solid #ddd}.fixed-table-body{overflow-x:auto;overflow-y:auto;height:100%}.fixed-table-container table{width:100%}.fixed-table-container thead th{height:0;padding:0;margin:0;border-left:1px solid #ddd}.fixed-table-container thead th:focus{outline:transparent solid 0}.fixed-table-container thead th:first-child{border-left:none;border-top-left-radius:4px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px}.fixed-table-container tbody td .th-inner,.fixed-table-container thead th .th-inner{padding:8px;line-height:24px;vertical-align:top;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fixed-table-container thead th .sortable{cursor:pointer;background-position:right;background-repeat:no-repeat;padding-right:30px}.fixed-table-container thead th .both{background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azioNZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4euts6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC')}.fixed-table-container thead th .asc{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBdqEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVoAADeemwtPcZI2wAAAABJRU5ErkJggg==)}.fixed-table-container thead th .desc{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWjYBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJzcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII=)}.fixed-table-container th.detail{width:30px}.fixed-table-container tbody td{border-left:1px solid #ddd}.fixed-table-container tbody tr:first-child td{border-top:none}.fixed-table-container tbody td:first-child{border-left:none}.fixed-table-container tbody .selected td{background-color:#f5f5f5}.fixed-table-container .bs-checkbox .th-inner{padding:8px 0}.fixed-table-container input[type=radio],.fixed-table-container input[type=checkbox]{margin:0 auto!important}.fixed-table-pagination .pagination-detail,.fixed-table-pagination div.pagination{margin-top:10px;margin-bottom:10px}.fixed-table-pagination div.pagination .pagination{margin:0}.fixed-table-pagination .pagination a{padding:6px 12px;line-height:1.428571429}.fixed-table-pagination .pagination-info{line-height:34px;margin-right:5px}.fixed-table-pagination .btn-group{position:relative;display:inline-block;vertical-align:middle}.fixed-table-pagination .dropup .dropdown-menu{margin-bottom:0}.fixed-table-pagination .page-list{display:inline-block}.fixed-table-toolbar .columns-left{margin-right:5px}.fixed-table-toolbar .columns-right{margin-left:5px}.fixed-table-toolbar .columns label{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.428571429}.fixed-table-toolbar .bs-bars,.fixed-table-toolbar .columns,.fixed-table-toolbar .search{position:relative;margin-top:10px;margin-bottom:10px;line-height:34px}.fixed-table-pagination li.disabled a{pointer-events:none;cursor:default}.fixed-table-loading{display:none;position:absolute;top:42px;right:0;bottom:0;left:0;z-index:99;background-color:#fff;text-align:center}.fixed-table-body .card-view .title{font-weight:700;display:inline-block;min-width:30%;text-align:left!important}.table td,.table th{vertical-align:middle}.fixed-table-toolbar .dropdown-menu{text-align:left;max-height:300px;overflow:auto}.fixed-table-toolbar .btn-group>.btn-group{display:inline-block;margin-left:-1px!important}.fixed-table-toolbar .btn-group>.btn-group>.btn{border-radius:0}.fixed-table-toolbar .btn-group>.btn-group:first-child>.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.fixed-table-toolbar .btn-group>.btn-group:last-child>.btn{border-top-right-radius:4px;border-bottom-right-radius:4px}.bootstrap-table .table>thead>tr>th{vertical-align:bottom;border-bottom:1px solid #ddd}.bootstrap-table .table thead>tr>th{padding:0;margin:0}.bootstrap-table .fixed-table-footer tbody>tr>td{padding:0!important}.bootstrap-table .fixed-table-footer .table{border-bottom:none;border-radius:0;padding:0!important}.pull-right .dropdown-menu{right:0;left:auto}p.fixed-table-scroll-inner{width:100%;height:200px}div.fixed-table-scroll-outer{top:0;left:0;visibility:hidden;width:200px;height:150px;overflow:hidden} -------------------------------------------------------------------------------- /app/src/main/assets/HTMLFiles/css/bootstrap-theme.min.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["less/theme.less","less/mixins/vendor-prefixes.less","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":";;;;AAmBA,YAAA,aAAA,UAAA,aAAA,aAAA,aAME,YAAA,EAAA,KAAA,EAAA,eC2CA,mBAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBDvCR,mBAAA,mBAAA,oBAAA,oBAAA,iBAAA,iBAAA,oBAAA,oBAAA,oBAAA,oBAAA,oBAAA,oBCsCA,mBAAA,MAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,iBDlCR,qBAAA,sBAAA,sBAAA,uBAAA,mBAAA,oBAAA,sBAAA,uBAAA,sBAAA,uBAAA,sBAAA,uBAAA,+BAAA,gCAAA,6BAAA,gCAAA,gCAAA,gCCiCA,mBAAA,KACQ,WAAA,KDlDV,mBAAA,oBAAA,iBAAA,oBAAA,oBAAA,oBAuBI,YAAA,KAyCF,YAAA,YAEE,iBAAA,KAKJ,aErEI,YAAA,EAAA,IAAA,EAAA,KACA,iBAAA,iDACA,iBAAA,4CAAA,iBAAA,qEAEA,iBAAA,+CCnBF,OAAA,+GH4CA,OAAA,0DACA,kBAAA,SAuC2C,aAAA,QAA2B,aAAA,KArCtE,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAgBN,aEtEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAiBN,aEvEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAkBN,UExEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,gBAAA,gBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,iBAAA,iBAEE,iBAAA,QACA,aAAA,QAMA,mBAAA,0BAAA,yBAAA,0BAAA,yBAAA,yBAAA,oBAAA,2BAAA,0BAAA,2BAAA,0BAAA,0BAAA,6BAAA,oCAAA,mCAAA,oCAAA,mCAAA,mCAME,iBAAA,QACA,iBAAA,KAmBN,aEzEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAoBN,YE1EI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,kBAAA,kBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,mBAAA,mBAEE,iBAAA,QACA,aAAA,QAMA,qBAAA,4BAAA,2BAAA,4BAAA,2BAAA,2BAAA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,+BAAA,sCAAA,qCAAA,sCAAA,qCAAA,qCAME,iBAAA,QACA,iBAAA,KA2BN,eAAA,WClCE,mBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,EAAA,IAAA,IAAA,iBD2CV,0BAAA,0BE3FI,iBAAA,QACA,iBAAA,oDACA,iBAAA,+CAAA,iBAAA,wEACA,iBAAA,kDACA,OAAA,+GF0FF,kBAAA,SAEF,yBAAA,+BAAA,+BEhGI,iBAAA,QACA,iBAAA,oDACA,iBAAA,+CAAA,iBAAA,wEACA,iBAAA,kDACA,OAAA,+GFgGF,kBAAA,SASF,gBE7GI,iBAAA,iDACA,iBAAA,4CACA,iBAAA,qEAAA,iBAAA,+CACA,OAAA,+GACA,OAAA,0DCnBF,kBAAA,SH+HA,cAAA,ICjEA,mBAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBD6DV,sCAAA,oCE7GI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SD2CF,mBAAA,MAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,iBD0EV,cAAA,iBAEE,YAAA,EAAA,IAAA,EAAA,sBAIF,gBEhII,iBAAA,iDACA,iBAAA,4CACA,iBAAA,qEAAA,iBAAA,+CACA,OAAA,+GACA,OAAA,0DCnBF,kBAAA,SHkJA,cAAA,IAHF,sCAAA,oCEhII,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SD2CF,mBAAA,MAAA,EAAA,IAAA,IAAA,gBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,gBDgFV,8BAAA,iCAYI,YAAA,EAAA,KAAA,EAAA,gBAKJ,qBAAA,kBAAA,mBAGE,cAAA,EAqBF,yBAfI,mDAAA,yDAAA,yDAGE,MAAA,KE7JF,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,UFqKJ,OACE,YAAA,EAAA,IAAA,EAAA,qBC3HA,mBAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,gBACQ,WAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,gBDsIV,eEtLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAKF,YEvLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAMF,eExLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAOF,cEzLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAeF,UEjMI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFuMJ,cE3MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFwMJ,sBE5MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFyMJ,mBE7MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF0MJ,sBE9MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF2MJ,qBE/MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF+MJ,sBElLI,iBAAA,yKACA,iBAAA,oKACA,iBAAA,iKFyLJ,YACE,cAAA,IC9KA,mBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,EAAA,IAAA,IAAA,iBDgLV,wBAAA,8BAAA,8BAGE,YAAA,EAAA,KAAA,EAAA,QEnOE,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFiOF,aAAA,QALF,+BAAA,qCAAA,qCAQI,YAAA,KAUJ,OCnME,mBAAA,EAAA,IAAA,IAAA,gBACQ,WAAA,EAAA,IAAA,IAAA,gBD4MV,8BE5PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFyPJ,8BE7PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF0PJ,8BE9PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF2PJ,2BE/PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF4PJ,8BEhQI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF6PJ,6BEjQI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFoQJ,MExQI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFsQF,aAAA,QC3NA,mBAAA,MAAA,EAAA,IAAA,IAAA,gBAAA,EAAA,IAAA,EAAA,qBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,gBAAA,EAAA,IAAA,EAAA"} -------------------------------------------------------------------------------- /app/src/main/assets/HTMLFiles/css/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v4.0.0 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]){display:none;height:0}progress{vertical-align:baseline}template,[hidden]{display:none}a{background-color:transparent}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}svg:not(:root){overflow:hidden}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}button,input,select,textarea{font:inherit;margin:0}optgroup{font-weight:bold}button,input,select{overflow:visible}button,select{text-transform:none}button,[type="button"],[type="reset"],[type="submit"]{cursor:pointer}[disabled]{cursor:default}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button:-moz-focusring,input:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none} 2 | -------------------------------------------------------------------------------- /app/src/main/assets/HTMLFiles/css/throbber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ac-pm/Inspeckage/d8806c9e5f14d44c2e19a331e929d72d6faa4c54/app/src/main/assets/HTMLFiles/css/throbber.gif -------------------------------------------------------------------------------- /app/src/main/assets/HTMLFiles/img/favicon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ac-pm/Inspeckage/d8806c9e5f14d44c2e19a331e929d72d6faa4c54/app/src/main/assets/HTMLFiles/img/favicon-16.png -------------------------------------------------------------------------------- /app/src/main/assets/HTMLFiles/img/favicon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ac-pm/Inspeckage/d8806c9e5f14d44c2e19a331e929d72d6faa4c54/app/src/main/assets/HTMLFiles/img/favicon-32.png -------------------------------------------------------------------------------- /app/src/main/assets/HTMLFiles/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ac-pm/Inspeckage/d8806c9e5f14d44c2e19a331e929d72d6faa4c54/app/src/main/assets/HTMLFiles/img/favicon.ico -------------------------------------------------------------------------------- /app/src/main/assets/HTMLFiles/js/CollapsibleLists.compressed.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | CollapsibleLists.js 4 | 5 | An object allowing lists to dynamically expand and collapse 6 | 7 | Created by Stephen Morley - http://code.stephenmorley.org/ - and released under 8 | the terms of the CC0 1.0 Universal legal code: 9 | 10 | http://creativecommons.org/publicdomain/zero/1.0/legalcode 11 | 12 | */ 13 | 14 | var CollapsibleLists=new function(){ 15 | this.apply=function(_1){ 16 | var _2=document.getElementsByTagName("ul"); 17 | for(var _3=0;_3<_2.length;_3++){ 18 | if(_2[_3].className.match(/(^| )collapsibleList( |$)/)){ 19 | this.applyTo(_2[_3],true); 20 | if(!_1){ 21 | var _4=_2[_3].getElementsByTagName("ul"); 22 | for(var _5=0;_5<_4.length;_5++){ 23 | _4[_5].className+=" collapsibleList"; 24 | } 25 | } 26 | } 27 | } 28 | }; 29 | this.applyTo=function(_6,_7){ 30 | var _8=_6.getElementsByTagName("li"); 31 | for(var _9=0;_9<_8.length;_9++){ 32 | if(!_7||_6==_8[_9].parentNode){ 33 | if(_8[_9].addEventListener){ 34 | _8[_9].addEventListener("mousedown",function(e){ 35 | e.preventDefault(); 36 | },false); 37 | }else{ 38 | _8[_9].attachEvent("onselectstart",function(){ 39 | event.returnValue=false; 40 | }); 41 | } 42 | if(_8[_9].addEventListener){ 43 | _8[_9].addEventListener("click",_a(_8[_9]),false); 44 | }else{ 45 | _8[_9].attachEvent("onclick",_a(_8[_9])); 46 | } 47 | _b(_8[_9]); 48 | } 49 | } 50 | }; 51 | function _a(_c){ 52 | return function(e){ 53 | if(!e){ 54 | e=window.event; 55 | } 56 | var _d=(e.target?e.target:e.srcElement); 57 | while(_d.nodeName!="LI"){ 58 | _d=_d.parentNode; 59 | } 60 | if(_d==_c){ 61 | _b(_c); 62 | } 63 | }; 64 | }; 65 | function _b(_e){ 66 | var _f=_e.className.match(/(^| )collapsibleListClosed( |$)/); 67 | var uls=_e.getElementsByTagName("ul"); 68 | for(var _10=0;_100){ 79 | _e.className+=" collapsibleList"+(_f?"Open":"Closed"); 80 | } 81 | }; 82 | }(); 83 | 84 | -------------------------------------------------------------------------------- /app/src/main/assets/HTMLFiles/js/base.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | 3 | document.cookie.split(";").forEach(function(c) { document.cookie = c.replace(/^ +/, "").replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/"); }); 4 | 5 | $("[name='ssl_uncheck']").bootstrapSwitch(); 6 | $('input[name="ssl_uncheck"]').on('switchChange.bootstrapSwitch', function(event, state) { 7 | 8 | console.log(state); 9 | $.get("/", { 10 | type: "sslunpinning", 11 | sslswitch: state 12 | }); 13 | 14 | }); 15 | 16 | 17 | $("[name='flag_sec']").bootstrapSwitch(); 18 | $('input[name="flag_sec"]').on('switchChange.bootstrapSwitch', function(event, state) { 19 | console.log(state); 20 | $.get("/", { 21 | type: "flagsec", 22 | fsswitch: state 23 | }); 24 | 25 | }); 26 | 27 | $("[name='switch_proxy']").bootstrapSwitch(); 28 | $('input[name="switch_proxy"]').on('switchChange.bootstrapSwitch', function(event, state) { 29 | console.log(state); 30 | $.get("/", { 31 | type: "switchproxy", 32 | value: state 33 | }); 34 | 35 | }); 36 | 37 | 38 | $("[name='exported']").bootstrapSwitch(); 39 | $('input[name="exported"]').on('switchChange.bootstrapSwitch', function(event, state) { 40 | console.log(state); 41 | $.get("/", { 42 | type: "exported", 43 | value: state 44 | }); 45 | 46 | }); 47 | 48 | CollapsibleLists.apply(); 49 | 50 | }); 51 | 52 | $(document.body).on('keyup', '#clipboard', function(){ 53 | var chararcters = $("#clipboard").val(); 54 | $.get("/", { 55 | type: "clipboard", 56 | value: chararcters 57 | }); 58 | }); 59 | 60 | function fileTree() { 61 | $('#fileTree1').load('?type=filetree'); 62 | } 63 | 64 | function finishApp(){ 65 | $.get("/", { 66 | type: "finishapp" 67 | }); 68 | } 69 | 70 | function restartApp() { 71 | $.get("/", { 72 | type: "restartapp" 73 | }); 74 | } 75 | 76 | function startApp() { 77 | $.get("/", { 78 | type: "startapp" 79 | }); 80 | } 81 | 82 | function setARP() { 83 | 84 | var ip = document.getElementById("ip").value; 85 | var mac = document.getElementById("mac").value; 86 | var ipformat = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; 87 | 88 | if (document.getElementById("ip").value.match(ipformat)) { 89 | 90 | $.get("/", { 91 | type: "setarp", 92 | ip: ip, 93 | mac: mac 94 | }); 95 | 96 | return true; 97 | } else { 98 | alert("You have entered an invalid IP address!"); 99 | } 100 | } 101 | 102 | 103 | 104 | function proxyTest() { 105 | $('#proxyTest').load('?type=proxytest'); 106 | } 107 | 108 | function screenshot() { 109 | window.location = "/?type=screenshot"; 110 | } 111 | 112 | function download_apk() { 113 | window.location = "/?type=downapk"; 114 | } 115 | 116 | function download_all() { 117 | window.location = "/?type=downall"; 118 | } 119 | 120 | function download_file(path) { 121 | 122 | window.location = "/?type=downloadfile&value="+path; 123 | } 124 | 125 | function setProxy() { 126 | 127 | var host = document.getElementById("host").value; 128 | var port = document.getElementById("port").value; 129 | var ipformat = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; 130 | 131 | if (document.getElementById("host").value.match(ipformat)) { 132 | 133 | $.get("/", { 134 | type: "proxy", 135 | host: host, 136 | port: port 137 | }); 138 | 139 | return true; 140 | } else { 141 | alert("You have entered an invalid IP address!"); 142 | } 143 | } 144 | 145 | function startComplexActivity() { 146 | 147 | var txt_activity = document.getElementById("txt_activity").value; 148 | var txt_action = document.getElementById("txt_action").value; 149 | var txt_category = document.getElementById("txt_category").value; 150 | var txt_datauri = document.getElementById("txt_datauri").value; 151 | var txt_extra = document.getElementById("txt_extra").value; 152 | var txt_flags = document.getElementById("txt_flags").value; 153 | var txt_mimetype = document.getElementById("txt_mimetype").value; 154 | 155 | $.get("/", { 156 | type: "start", 157 | component: "activity", 158 | activity: txt_activity, 159 | action: txt_action, 160 | category: txt_category, 161 | datauri: txt_datauri, 162 | extra: txt_extra, 163 | flags: txt_flags, 164 | mimetype: txt_mimetype 165 | }); 166 | } 167 | 168 | function queryProvider(){ 169 | 170 | var txt_uri = document.getElementById("txt_uri").value; 171 | 172 | $.get("/", { 173 | type: "start", 174 | component: "provider", 175 | uri: txt_uri 176 | }); 177 | } 178 | 179 | function selectAct(act){ 180 | document.getElementById("txt_activity").value = act; 181 | } 182 | 183 | function selectAction(act){ 184 | document.getElementById("txt_action").value = act; 185 | } 186 | 187 | function selectCategory(act){ 188 | document.getElementById("txt_category").value = act; 189 | } 190 | 191 | function selectFlag(act){ 192 | document.getElementById("txt_flags").value = act; 193 | } 194 | 195 | function startActivity(act){ 196 | $.get("/", { 197 | type: "start", 198 | component: "activity", 199 | activity: act 200 | }); 201 | } 202 | 203 | function saveLocation() { 204 | 205 | var geolocation = document.getElementById("loc").value; 206 | 207 | $.get("/", { 208 | type: "location", 209 | geolocation: geolocation 210 | }).done(function( data ) { 211 | if(data == "OK"){ 212 | document.getElementById("savedLoc").innerHTML = geolocation; 213 | } 214 | }); 215 | } 216 | 217 | $("[name='savedLoc']").bootstrapSwitch(); 218 | $('input[name="savedLoc"]').on('switchChange.bootstrapSwitch', function(event, state) { 219 | 220 | console.log(state); 221 | $.get("/", { 222 | type: "geolocationSwitch", 223 | geolocationSwitch: state 224 | }); 225 | 226 | }); -------------------------------------------------------------------------------- /app/src/main/assets/HTMLFiles/js/bootstrap-table-editable.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.11.0 - 2016-07-02 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2016 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.extend(a.fn.bootstrapTable.defaults,{editable:!0,onEditableInit:function(){return!1},onEditableSave:function(){return!1},onEditableShown:function(){return!1},onEditableHidden:function(){return!1}}),a.extend(a.fn.bootstrapTable.Constructor.EVENTS,{"editable-init.bs.table":"onEditableInit","editable-save.bs.table":"onEditableSave","editable-shown.bs.table":"onEditableShown","editable-hidden.bs.table":"onEditableHidden"});var b=a.fn.bootstrapTable.Constructor,c=b.prototype.initTable,d=b.prototype.initBody;b.prototype.initTable=function(){var b=this;c.apply(this,Array.prototype.slice.apply(arguments)),this.options.editable&&a.each(this.columns,function(c,d){if(d.editable){var e={},f=[],g="editable-",h=function(a,b){var c=a.replace(/([A-Z])/g,function(a){return"-"+a.toLowerCase()});if(c.slice(0,g.length)==g){var d=c.replace(g,"data-");e[d]=b}};a.each(b.options,h),d.formatter=d.formatter||function(a){return a},d._formatter=d._formatter?d._formatter:d.formatter,d.formatter=function(c,g,i){var j=d._formatter?d._formatter(c,g,i):c;a.each(d,h),a.each(e,function(a,b){f.push(" "+a+'="'+b+'"')});var k=!1;return d.editable.hasOwnProperty("noeditFormatter")&&(k=d.editable.noeditFormatter(c,g,i)),k===!1?['"].join(""):k}}})},b.prototype.initBody=function(){var b=this;d.apply(this,Array.prototype.slice.apply(arguments)),this.options.editable&&(a.each(this.columns,function(c,d){d.editable&&(b.$body.find('a[data-name="'+d.field+'"]').editable(d.editable).off("save").on("save",function(c,e){var f=b.getData(),g=a(this).parents("tr[data-index]").data("index"),h=f[g],i=h[d.field];a(this).data("value",e.submitValue),h[d.field]=e.submitValue,b.trigger("editable-save",d.field,h,i,a(this)),b.resetFooter()}),b.$body.find('a[data-name="'+d.field+'"]').editable(d.editable).off("shown").on("shown",function(c,e){var f=b.getData(),g=a(this).parents("tr[data-index]").data("index"),h=f[g];b.trigger("editable-shown",d.field,h,a(this),e)}),b.$body.find('a[data-name="'+d.field+'"]').editable(d.editable).off("hidden").on("hidden",function(c,e){var f=b.getData(),g=a(this).parents("tr[data-index]").data("index"),h=f[g];b.trigger("editable-hidden",d.field,h,a(this),e)}))}),this.trigger("editable-init"))}}(jQuery); -------------------------------------------------------------------------------- /app/src/main/assets/HTMLFiles/js/fingerprint.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | var $tableBuild = $('#tableBuild'); 4 | 5 | $tableBuild.bootstrapTable({ 6 | idField: 'name', 7 | search: true, 8 | url: '/?type=getbuild', 9 | columns: [{ 10 | field: 'enable', 11 | title: 'Enable', 12 | checkbox: 'true' 13 | }, 14 | { 15 | field: 'type', 16 | title: 'From' 17 | },{ 18 | field: 'name', 19 | title: 'Name' 20 | }, { 21 | field: 'value', 22 | title: 'Value' 23 | }, { 24 | field: 'newValue', 25 | title: 'New Value', 26 | editable: { 27 | type: 'text', 28 | mode: 'inline' 29 | } 30 | } 31 | ] 32 | }); 33 | 34 | $tableBuild.on('all.bs.table', function(e, row) { 35 | addBuild(JSON.stringify($tableBuild.bootstrapTable('getData'))); 36 | }); 37 | }); 38 | 39 | function addBuild(build) { 40 | $.get("/", { 41 | type: "addbuild", 42 | build: build 43 | }).done(function(data) {}); 44 | }; 45 | 46 | function resetFingerprint() { 47 | 48 | $.get("/", { 49 | type: "resetfingerprint" 50 | }).done(function( data ) { 51 | $("#tbs-content").load("/content/fingerprint.html"); 52 | }); 53 | } -------------------------------------------------------------------------------- /app/src/main/assets/HTMLFiles/js/logcat.js: -------------------------------------------------------------------------------- 1 | var $j = jQuery.noConflict(); 2 | 3 | document.observe("dom:loaded", function() { 4 | 5 | function log(text) { 6 | $("log").innerHTML = $("log").innerHTML + (!Object.isUndefined(text) && text !== null ? text.escapeHTML() : "null"); 7 | 8 | } 9 | 10 | if (!window.WebSocket) { 11 | alert("WebSocket not natively supported."); 12 | } 13 | 14 | var ws; 15 | 16 | $("uriForm").observe("submit", function(e) { 17 | 18 | e.stop(); 19 | 20 | var port = document.getElementById("wsport"); 21 | ws = new WebSocket("ws://" + $F("uri") + ":" + port.textContent); 22 | 23 | ws.onopen = function() { 24 | log("[WebSocket Open]\n"); 25 | }; 26 | 27 | ws.onmessage = function(e) { 28 | log(e.data + "\n"); 29 | }; 30 | 31 | ws.onclose = function() { 32 | log("[WebSocket Close]\n"); 33 | 34 | $("uri", "connect").invoke("enable"); 35 | $("disconnect").disable(); 36 | 37 | ws = null; 38 | }; 39 | 40 | $("uri", "connect").invoke("disable"); 41 | $("disconnect").enable(); 42 | 43 | }); 44 | 45 | $("disconnect").observe("click", function(e) { 46 | e.stop(); 47 | if (ws) { 48 | ws.close(); 49 | ws = null; 50 | } 51 | }); 52 | 53 | $("startWS").observe("click", function(e) { 54 | 55 | $("startWS").disable(); 56 | $("stopWS").enable(); 57 | 58 | $("inlineCheckbox1").disable(); 59 | $("inlineCheckbox2").disable(); 60 | $("inlineCheckbox3").disable(); 61 | $("inlineCheckbox4").disable(); 62 | $("inlineCheckbox5").disable(); 63 | $("inlineCheckbox6").disable(); 64 | 65 | }); 66 | 67 | $("stopWS").observe("click", function(e) { 68 | 69 | $("stopWS").disable(); 70 | $("startWS").enable(); 71 | 72 | $("inlineCheckbox1").enable(); 73 | $("inlineCheckbox2").enable(); 74 | $("inlineCheckbox3").enable(); 75 | $("inlineCheckbox4").enable(); 76 | $("inlineCheckbox5").enable(); 77 | $("inlineCheckbox6").enable(); 78 | }); 79 | 80 | $("scroll").observe("click", function(e) { 81 | 82 | 83 | if($("scroll").value == "Stop Scroll"){ 84 | stopScroll(); 85 | $("scroll").value = 'Auto Scroll'; 86 | }else if($("scroll").value == "Auto Scroll"){ 87 | startScroll(); 88 | $("scroll").value = 'Stop Scroll'; 89 | } 90 | 91 | }); 92 | 93 | $("clear").observe("click", function(e) { 94 | $("log").innerHTML = "clear..."; 95 | }); 96 | 97 | 98 | }); 99 | 100 | var refresh; 101 | 102 | function stopScroll() { 103 | clearInterval(refresh); 104 | } 105 | 106 | function startScroll() { 107 | refresh = setInterval(function(){ autoScroll() }, 1000); 108 | } 109 | 110 | function autoScroll() { 111 | $("log").scrollTop = $("log").scrollHeight; 112 | } 113 | 114 | function startWSocket() { 115 | 116 | var options = []; 117 | $j('#formx input:checked').each(function() { 118 | options.push($j(this).attr('value')); 119 | }); 120 | 121 | $j.get("/", { 122 | type: "startWS", 123 | selected: "" + options 124 | 125 | }); 126 | } 127 | 128 | function stopWSocket() { 129 | $j.get("/", { 130 | type: "stopWS" 131 | }); 132 | } -------------------------------------------------------------------------------- /app/src/main/assets/HTMLFiles/js/menu.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | var trigger = $('.hamburger'), 3 | overlay = $('.overlay'), 4 | isClosed = false; 5 | 6 | trigger.click(function() { 7 | hamburger_cross(); 8 | }); 9 | 10 | function hamburger_cross() { 11 | 12 | if (isClosed == true) { 13 | overlay.hide(); 14 | trigger.removeClass('is-open'); 15 | trigger.addClass('is-closed'); 16 | isClosed = false; 17 | } else { 18 | overlay.show(); 19 | trigger.removeClass('is-closed'); 20 | trigger.addClass('is-open'); 21 | isClosed = true; 22 | } 23 | } 24 | 25 | $('[data-toggle="offcanvas"]').click(function() { 26 | $('#wrapper').toggleClass('toggled'); 27 | 28 | 29 | }); 30 | 31 | $("#tbs-content").load("/content/tabs.html"); 32 | }); 33 | 34 | $("#nav_tbs").on("click", function() { 35 | $("#tbs-content").load("/content/tabs.html"); 36 | $("[name='refresh']").bootstrapSwitch('state', true); 37 | }); 38 | 39 | $("#nav_replaces").on("click", function() { 40 | $("[name='refresh']").bootstrapSwitch('state', false); 41 | $("#tbs-content").load("/content/replace.html"); 42 | 43 | showGeneralInfo(true); 44 | }); 45 | 46 | $("#nav_location").on("click", function() { 47 | $("[name='refresh']").bootstrapSwitch('state', false); 48 | $("#tbs-content").load("/content/location.html"); 49 | 50 | showGeneralInfo(true); 51 | }); 52 | 53 | 54 | 55 | $("#nav_config").on("click", function() { 56 | $("[name='refresh']").bootstrapSwitch('state', false); 57 | $("#tbs-content").load("/content/fingerprint.html"); 58 | showGeneralInfo(true); 59 | }); 60 | 61 | $("#nav_source").on("click", function() { 62 | $("[name='refresh']").bootstrapSwitch('state', false); 63 | $("#tbs-content").load("/content/hooks.html"); 64 | showGeneralInfo(true); 65 | }); 66 | 67 | $("#nav_sponsor").on("click", function() { 68 | $("[name='refresh']").bootstrapSwitch('state', false); 69 | $("#tbs-content").load("/content/sponsor.html"); 70 | showGeneralInfo(true); 71 | }); 72 | 73 | $("#nav_about").on("click", function() { 74 | $("[name='refresh']").bootstrapSwitch('state', false); 75 | $("#tbs-content").load("/content/about.html"); 76 | showGeneralInfo(true); 77 | }); 78 | 79 | $("#nav_share").on("click", function() { 80 | $("[name='refresh']").bootstrapSwitch('state', false); 81 | $("#tbs-content").load("/content/share.html"); 82 | showGeneralInfo(true); 83 | }); 84 | 85 | 86 | 87 | 88 | 89 | $("#nav_howto").on("click", function() { 90 | $("[name='refresh']").bootstrapSwitch('state', false); 91 | $("#tbs-content").load("/content/tips.html"); 92 | showGeneralInfo(true); 93 | }); 94 | $("#nav_apk").on("click", function() { 95 | $("[name='refresh']").bootstrapSwitch('state', false); 96 | $("#tbs-content").load("/content/tips.html#nav-apk"); 97 | showGeneralInfo(true); 98 | }); 99 | $("#nav_proxy").on("click", function() { 100 | 101 | $("[name='refresh']").bootstrapSwitch('state', false); 102 | $("#tbs-content").load("/content/tips.html#nav-proxy"); 103 | showGeneralInfo(true); 104 | }); 105 | $("#nav_debug").on("click", function() { 106 | $("[name='refresh']").bootstrapSwitch('state', false); 107 | $("#tbs-content").load("/content/tips.html#nav-debug"); 108 | showGeneralInfo(true); 109 | }); 110 | $("#nav_hooks").on("click", function() { 111 | $("[name='refresh']").bootstrapSwitch('state', false); 112 | $("#tbs-content").load("/content/tips.html#nav-hooks"); 113 | showGeneralInfo(true); 114 | }); 115 | 116 | var shown = true; 117 | 118 | function showGeneralInfo(v) { 119 | 120 | if(v!=null){ 121 | shown = v; 122 | } 123 | 124 | var general = $('#general-info'); 125 | var generalInfoIcon = $('#general-info-icon'); 126 | if(shown) { 127 | general.fadeOut(); 128 | generalInfoIcon.attr("class", "fa fa-chevron-circle-down"); 129 | shown = false; 130 | } else { 131 | general.fadeIn(); 132 | generalInfoIcon.attr("class", "fa fa-chevron-circle-up"); 133 | shown = true; 134 | } 135 | } 136 | 137 | 138 | 139 | 140 | $.fn.customerPopup = function (e, intWidth, intHeight, blnResize) { 141 | 142 | 143 | e.preventDefault(); 144 | 145 | 146 | intWidth = intWidth || '500'; 147 | intHeight = intHeight || '400'; 148 | strResize = (blnResize ? 'yes' : 'no'); 149 | 150 | 151 | var strTitle = ((typeof this.attr('title') !== 'undefined') ? this.attr('title') : 'Social Share'), 152 | strParam = 'width=' + intWidth + ',height=' + intHeight + ',resizable=' + strResize, 153 | objWindow = window.open(this.attr('href'), strTitle, strParam).focus(); 154 | }; 155 | 156 | 157 | 158 | $(document).ready(function ($) { 159 | $('.customer.share').on("click", function(e) { 160 | $(this).customerPopup(e); 161 | }); 162 | }); 163 | -------------------------------------------------------------------------------- /app/src/main/assets/HTMLFiles/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /app/src/main/assets/HTMLFiles/logcat.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Inspeckage - Package Inspector 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 | 32 |
33 |
34 | 83 |
84 |
85 | 86 | 87 |
88 | 89 |
90 | 91 |
92 | 93 |
94 | 95 | ws:// 96 | 97 | #port_ws# 98 | 99 |
100 | 101 | 102 | 103 | 104 |
105 |
106 | 107 | 108 |
109 | 110 |
111 | 112 |
113 | 114 |
115 |
116 |
117 | 118 |
119 |
120 |

121 |
122 |
123 | 124 | 125 | 126 |
127 | 128 | 129 | -------------------------------------------------------------------------------- /app/src/main/assets/xposed_init: -------------------------------------------------------------------------------- 1 | mobi.acpm.inspeckage.Module -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/hooks/ClipboardHook.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.hooks; 2 | 3 | import android.content.ClipData; 4 | import android.content.ClipboardManager; 5 | 6 | import de.robv.android.xposed.XC_MethodHook; 7 | import de.robv.android.xposed.XposedBridge; 8 | import de.robv.android.xposed.callbacks.XC_LoadPackage; 9 | 10 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; 11 | 12 | /** 13 | * Created by acpm on 25/11/15. 14 | */ 15 | public class ClipboardHook extends XC_MethodHook { 16 | 17 | public static final String TAG = "Inspeckage_Clipboard:"; 18 | 19 | public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) { 20 | 21 | findAndHookMethod(ClipboardManager.class, "setPrimaryClip", ClipData.class, new XC_MethodHook() { 22 | 23 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 24 | 25 | ClipData cd = (ClipData) param.args[0]; 26 | StringBuilder sb = new StringBuilder(); 27 | if (cd != null && cd.getItemCount() > 0) { 28 | 29 | for (int i = 0; i < cd.getItemCount(); i++) { 30 | ClipData.Item item = cd.getItemAt(i); 31 | sb.append(item.getText()); 32 | } 33 | } 34 | XposedBridge.log(MiscHook.TAG + "Copied to the clipboard: " + sb.toString() + ""); 35 | 36 | } 37 | }); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/hooks/CryptoHook.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.hooks; 2 | 3 | import java.security.SecureRandom; 4 | 5 | import javax.crypto.Cipher; 6 | import javax.crypto.spec.IvParameterSpec; 7 | import javax.crypto.spec.PBEKeySpec; 8 | import javax.crypto.spec.SecretKeySpec; 9 | 10 | import de.robv.android.xposed.XC_MethodHook; 11 | import de.robv.android.xposed.XposedBridge; 12 | import de.robv.android.xposed.callbacks.XC_LoadPackage; 13 | import mobi.acpm.inspeckage.util.Util; 14 | 15 | import static de.robv.android.xposed.XposedHelpers.findAndHookConstructor; 16 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; 17 | 18 | /** 19 | * Created by acpm on 16/11/15. 20 | */ 21 | public class CryptoHook extends XC_MethodHook { 22 | 23 | public static final String TAG = "Inspeckage_Crypto:"; 24 | private static StringBuffer sb; 25 | 26 | public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) { 27 | 28 | findAndHookConstructor(SecretKeySpec.class, byte[].class, String.class, new XC_MethodHook() { 29 | 30 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 31 | 32 | sb = new StringBuffer(); 33 | sb.append("SecretKeySpec(" + Util.byteArrayToString((byte[]) param.args[0]) + ","+(String) param.args[1]+")"); 34 | } 35 | 36 | }); 37 | 38 | findAndHookMethod(Cipher.class, "doFinal", byte[].class, new XC_MethodHook() { 39 | 40 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 41 | 42 | if (sb == null) { 43 | sb = new StringBuffer(); 44 | } 45 | sb.append(" (" + Util.byteArrayToString((byte[]) param.args[0]) + " , "); 46 | sb.append(Util.byteArrayToString((byte[]) param.getResult()) + ")"); 47 | 48 | XposedBridge.log(TAG + sb.toString()); 49 | sb = new StringBuffer(); 50 | } 51 | 52 | }); 53 | 54 | findAndHookMethod(Cipher.class, "getIV", new XC_MethodHook() { 55 | 56 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 57 | 58 | if (sb == null) { 59 | sb = new StringBuffer(); 60 | } 61 | sb.append(" IV:" + (String) param.getResult()); 62 | } 63 | 64 | }); 65 | 66 | findAndHookConstructor(IvParameterSpec.class, byte[].class, new XC_MethodHook() { 67 | 68 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 69 | 70 | if (sb == null) { 71 | sb = new StringBuffer(); 72 | } 73 | sb.append(" IV: " + Util.byteArrayToString((byte[]) param.args[0])); 74 | } 75 | }); 76 | 77 | findAndHookMethod(SecureRandom.class, "setSeed", byte[].class, new XC_MethodHook() { 78 | 79 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 80 | 81 | if (sb == null) { 82 | sb = new StringBuffer(); 83 | } 84 | sb.append(" Seed:" + Util.byteArrayToString((byte[]) param.args[0])); 85 | } 86 | 87 | }); 88 | 89 | findAndHookMethod(Cipher.class, "getInstance", String.class, new XC_MethodHook() { 90 | 91 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 92 | 93 | if (sb == null) { 94 | sb = new StringBuffer(); 95 | } 96 | //Transformation ex AES/CBC/PKCS7Padding 97 | sb.append(" , Cipher[" + (String) param.args[0] + "] "); 98 | } 99 | 100 | }); 101 | 102 | findAndHookConstructor(PBEKeySpec.class, char[].class, byte[].class, int.class, int.class, new XC_MethodHook() { 103 | 104 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 105 | if (sb == null) 106 | sb = new StringBuffer(); 107 | 108 | sb.append("[PBEKeySpec] - Password: " + String.valueOf((char[])param.args[0]) + " || Salt: " + Util.byteArrayToString((byte[])param.args[1])); 109 | XposedBridge.log(TAG + sb.toString()); 110 | sb = new StringBuffer(); 111 | } 112 | }); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/hooks/FileSystemHook.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.hooks; 2 | 3 | import android.content.ContextWrapper; 4 | 5 | import java.io.File; 6 | import java.net.URI; 7 | 8 | import de.robv.android.xposed.XC_MethodHook; 9 | import de.robv.android.xposed.XposedBridge; 10 | import de.robv.android.xposed.callbacks.XC_LoadPackage; 11 | 12 | import static de.robv.android.xposed.XposedHelpers.findAndHookConstructor; 13 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; 14 | 15 | /** 16 | * Created by acpm on 27/11/15. 17 | */ 18 | public class FileSystemHook extends XC_MethodHook { 19 | 20 | public static final String TAG = "Inspeckage_FileSystem:"; 21 | 22 | public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) { 23 | 24 | 25 | findAndHookMethod(ContextWrapper.class, "openFileOutput", String.class, "int", new XC_MethodHook() { 26 | 27 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 28 | 29 | String name = (String) param.args[0]; 30 | int mode = (int) param.args[1]; 31 | 32 | if (name.contains("Inspeckage")) { 33 | XposedBridge.invokeOriginalMethod(param.method, param.thisObject, param.args); 34 | } else { 35 | 36 | String m; 37 | switch (mode) { 38 | 39 | case android.content.Context.MODE_PRIVATE: 40 | m = "MODE_PRIVATE"; 41 | break; 42 | //case android.content.Context.MODE_WORLD_WRITEABLE: 43 | // m = "MODE_WORLD_WRITEABLE"; 44 | //break; 45 | case android.content.Context.MODE_APPEND: 46 | m = "MODE_APPEND"; 47 | break; 48 | default: 49 | m = "?"; 50 | } 51 | 52 | XposedBridge.log(TAG + "openFileOutput("+name+", "+m+")"); 53 | } 54 | } 55 | }); 56 | 57 | findAndHookConstructor(File.class, String.class, new XC_MethodHook() { 58 | 59 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 60 | 61 | String str = (String) param.args[0]; 62 | if (str.contains("Inspeckage")) { 63 | XposedBridge.invokeOriginalMethod(param.method, param.thisObject, param.args); 64 | } else { 65 | XposedBridge.log(TAG + "R/W [new File(String)]: " + str); 66 | } 67 | } 68 | }); 69 | 70 | 71 | findAndHookConstructor(File.class, String.class, String.class, new XC_MethodHook() { 72 | 73 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 74 | 75 | String dir = (String) param.args[0]; 76 | String fileName = (String) param.args[1]; 77 | if(dir != null) { 78 | if (dir.contains("Inspeckage") || fileName.contains("Inspeckage")) { 79 | XposedBridge.invokeOriginalMethod(param.method, param.thisObject, param.args); 80 | } else { 81 | XposedBridge.log(TAG + "R/W Dir: " + dir + " File: " + fileName); 82 | } 83 | } 84 | } 85 | }); 86 | 87 | 88 | findAndHookConstructor(File.class, File.class, String.class, new XC_MethodHook() { 89 | 90 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 91 | 92 | File fileDir = (File) param.args[0]; 93 | String fileName = (String) param.args[1]; 94 | if(fileDir != null) { 95 | if (fileDir.getAbsolutePath().contains("Inspeckage") || fileName.contains("Inspeckage")) { 96 | XposedBridge.invokeOriginalMethod(param.method, param.thisObject, param.args); 97 | } else { 98 | XposedBridge.log(TAG + "R/W Dir: " + fileDir.getAbsolutePath() + " File: " + fileName); 99 | } 100 | } 101 | } 102 | }); 103 | 104 | findAndHookConstructor(File.class, URI.class, new XC_MethodHook() { 105 | 106 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 107 | 108 | URI uri = (URI) param.args[0]; 109 | if(uri!=null) { 110 | if (uri.toString().contains("Inspeckage")) { 111 | XposedBridge.invokeOriginalMethod(param.method, param.thisObject, param.args); 112 | } else { 113 | XposedBridge.log(TAG + "R/W [new File(URI)]: " + uri.toString()); 114 | } 115 | } 116 | } 117 | }); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/hooks/FlagSecureHook.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.hooks; 2 | 3 | import android.view.SurfaceView; 4 | import android.view.Window; 5 | import android.view.WindowManager; 6 | 7 | import de.robv.android.xposed.XC_MethodHook; 8 | import de.robv.android.xposed.XSharedPreferences; 9 | import de.robv.android.xposed.callbacks.XC_LoadPackage; 10 | import mobi.acpm.inspeckage.Module; 11 | 12 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; 13 | 14 | /** 15 | * Created by acpm on 20/11/15. 16 | */ 17 | public class FlagSecureHook extends XC_MethodHook { 18 | 19 | public static final String TAG = "Inspeckage_FlagSecure:"; 20 | private static XSharedPreferences sPrefs; 21 | 22 | public static void loadPrefs() { 23 | sPrefs = new XSharedPreferences(Module.class.getPackage().getName(), Module.PREFS); 24 | sPrefs.makeWorldReadable(); 25 | } 26 | 27 | public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) { 28 | 29 | findAndHookMethod(Window.class, "setFlags", 30 | "int", "int", new XC_MethodHook() { 31 | 32 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 33 | loadPrefs(); 34 | if (sPrefs.getBoolean("flag_secure", false)) { 35 | if ((Integer) param.args[0] == WindowManager.LayoutParams.FLAG_SECURE) { 36 | param.args[0] = 0; 37 | param.args[1] = 0; 38 | } 39 | } 40 | } 41 | }); 42 | 43 | //Build.VERSION.SDK_INT >= 17 44 | findAndHookMethod(SurfaceView.class, "setSecure", boolean.class, 45 | new XC_MethodHook() { 46 | @Override 47 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 48 | loadPrefs(); 49 | if (sPrefs.getBoolean("flag_secure", false)) { 50 | param.args[0] = false; 51 | } 52 | } 53 | }); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/hooks/HashHook.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.hooks; 2 | 3 | import java.nio.ByteBuffer; 4 | import java.security.MessageDigest; 5 | 6 | import de.robv.android.xposed.XC_MethodHook; 7 | import de.robv.android.xposed.XposedBridge; 8 | import de.robv.android.xposed.callbacks.XC_LoadPackage; 9 | import mobi.acpm.inspeckage.util.Util; 10 | 11 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; 12 | 13 | /** 14 | * Created by acpm on 21/11/15. 15 | */ 16 | public class HashHook extends XC_MethodHook { 17 | 18 | public static final String TAG = "Inspeckage_Hash:"; 19 | private static StringBuffer sb; 20 | 21 | public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) { 22 | 23 | findAndHookMethod(MessageDigest.class, "getInstance", String.class, new XC_MethodHook() { 24 | 25 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 26 | 27 | sb = new StringBuffer(); 28 | sb.append("Algorithm(" +param.args[0]+") ["); 29 | } 30 | }); 31 | 32 | findAndHookMethod(MessageDigest.class, "update", byte[].class, new XC_MethodHook() { 33 | 34 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 35 | 36 | sb.append("" + Util.byteArrayToString((byte[]) param.args[0])+" : "); 37 | } 38 | 39 | }); 40 | 41 | findAndHookMethod(MessageDigest.class, "update", byte[].class, "int", "int", new XC_MethodHook() { 42 | 43 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 44 | 45 | sb.append("" + Util.byteArrayToString((byte[]) param.args[0])+" : "); 46 | } 47 | 48 | }); 49 | 50 | findAndHookMethod(MessageDigest.class, "update", ByteBuffer.class, new XC_MethodHook() { 51 | 52 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 53 | 54 | ByteBuffer bb = (ByteBuffer) param.args[0]; 55 | 56 | sb.append("" + Util.byteArrayToString(bb.array()) + " : "); 57 | } 58 | }); 59 | 60 | //the computed one way hash value 61 | findAndHookMethod(MessageDigest.class, "digest", new XC_MethodHook() { 62 | 63 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 64 | 65 | sb.append(Util.toHexString((byte[]) param.getResult())+"]"); 66 | 67 | XposedBridge.log(TAG + sb.toString()); 68 | sb = new StringBuffer(); 69 | } 70 | }); 71 | 72 | findAndHookMethod(MessageDigest.class, "digest", byte[].class, new XC_MethodHook() { 73 | 74 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 75 | 76 | //XposedBridge.log(TAG + "digest2 = " + Util.byteArrayToString((byte[]) param.args[0])); 77 | 78 | //sb.append(" : " + Util.toHexString((byte[]) param.getResult())+"]"); 79 | 80 | //XposedBridge.log(TAG + sb.toString()); 81 | //sb = new StringBuffer(); 82 | } 83 | }); 84 | 85 | findAndHookMethod(MessageDigest.class, "digest", byte[].class, "int", "int", new XC_MethodHook() { 86 | 87 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 88 | 89 | //sb.append(" : " + (Integer) param.getResult()+"]"); 90 | //XposedBridge.log(TAG + sb.toString()); 91 | //sb = new StringBuffer(); 92 | } 93 | }); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/hooks/IPCHook.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.hooks; 2 | 3 | import android.app.Activity; 4 | import android.content.BroadcastReceiver; 5 | import android.content.ContextWrapper; 6 | import android.content.Intent; 7 | import android.content.IntentFilter; 8 | import android.os.Bundle; 9 | import android.os.Handler; 10 | 11 | import de.robv.android.xposed.XC_MethodHook; 12 | import de.robv.android.xposed.XposedBridge; 13 | import de.robv.android.xposed.callbacks.XC_LoadPackage; 14 | 15 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; 16 | 17 | /** 18 | * Created by acpm on 24/11/15. 19 | */ 20 | public class IPCHook extends XC_MethodHook { 21 | 22 | public static final String TAG = "Inspeckage_IPC:"; 23 | 24 | public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) { 25 | 26 | findAndHookMethod(ContextWrapper.class, "startActivities", 27 | Intent[].class, new XC_MethodHook() { 28 | 29 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 30 | Intent[] it = (Intent[]) param.args[0]; 31 | StringBuffer sb = new StringBuffer(); 32 | for(Intent i : it){ 33 | sb.append(i+","); 34 | } 35 | XposedBridge.log(TAG + "startActivities: "+sb.toString().substring(0,sb.length()-1)); 36 | } 37 | }); 38 | 39 | findAndHookMethod(ContextWrapper.class, "startService", 40 | Intent.class, new XC_MethodHook() { 41 | 42 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 43 | Intent intent = (Intent) param.args[0]; 44 | XposedBridge.log(TAG + "startService: "+intent); 45 | } 46 | }); 47 | 48 | findAndHookMethod(ContextWrapper.class, "startActivity", 49 | Intent.class, Bundle.class, new XC_MethodHook() { 50 | 51 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 52 | Intent intent = (Intent) param.args[0]; 53 | XposedBridge.log(TAG + "startActivity: "+intent); 54 | } 55 | }); 56 | 57 | //findAndHookMethod(ContextWrapper.class, "startActivity", 58 | findAndHookMethod(Activity.class, "startActivity", 59 | Intent.class, new XC_MethodHook() { 60 | 61 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 62 | Intent intent = (Intent) param.args[0]; 63 | XposedBridge.log(TAG + "startActivity: "+intent); 64 | } 65 | }); 66 | 67 | findAndHookMethod(ContextWrapper.class, "sendBroadcast", 68 | Intent.class, new XC_MethodHook() { 69 | 70 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 71 | Intent intent = (Intent) param.args[0]; 72 | if(intent !=null && !intent.getAction().contains("mobi.acpm.inspeckage")) { 73 | XposedBridge.log(TAG + "sendBroadcast: " + intent); 74 | } 75 | } 76 | }); 77 | 78 | findAndHookMethod(ContextWrapper.class, "sendBroadcast", 79 | Intent.class, String.class, new XC_MethodHook() { 80 | 81 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 82 | Intent intent = (Intent) param.args[0]; 83 | if(intent !=null && !intent.getAction().contains("mobi.acpm.inspeckage")) { 84 | XposedBridge.log(TAG + "sendBroadcast: " + intent); 85 | } 86 | } 87 | }); 88 | 89 | findAndHookMethod(ContextWrapper.class, "registerReceiver", 90 | BroadcastReceiver.class, IntentFilter.class, new XC_MethodHook() { 91 | 92 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 93 | IntentFilter intentFilter = (IntentFilter) param.args[1]; 94 | StringBuffer sb = new StringBuffer(); 95 | sb.append("Actions: "); 96 | for(int i=0; i classBuildVersion = XposedHelpers.findClass("com.google.android.gms.ads.identifier.AdvertisingIdClient$Info", loadPackageParam.classLoader); 32 | findAndHookMethod(classBuildVersion, "getId", new XC_MethodHook() { 33 | 34 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 35 | if(param.args!=null && param.args.length>0) { 36 | XposedBridge.log(TAG + "AdvertisingID: " + param.args[0] + ""); 37 | } 38 | } 39 | 40 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 41 | if(param.args!=null && param.args.length>0) { 42 | XposedBridge.log(TAG + "AdvertisingID before: " + param.args[0] + ""); 43 | } 44 | } 45 | }); 46 | }catch (XposedHelpers.ClassNotFoundError ex) {} 47 | } 48 | } -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/hooks/ProcessHook.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.hooks; 2 | 3 | import de.robv.android.xposed.XC_MethodHook; 4 | import de.robv.android.xposed.XposedBridge; 5 | import de.robv.android.xposed.callbacks.XC_LoadPackage; 6 | 7 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; 8 | 9 | /** 10 | * Created by acpm on 14/01/16. 11 | */ 12 | public class ProcessHook extends XC_MethodHook { 13 | 14 | public static final String TAG = "Inspeckage_Process:"; 15 | 16 | public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) { 17 | 18 | /** 19 | final Class build = XposedHelpers.findClass("android.os.Process", loadPackageParam.classLoader); 20 | 21 | hookMethod(XposedHelpers.findMethodBestMatch(build, "start", String.class, String.class, int.class, 22 | int.class, int[].class, int.class, int.class, int.class, 23 | String.class, String.class, String.class, String.class, String[].class), new XC_MethodHook() { 24 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 25 | 26 | int uid = (Integer) param.args[2]; 27 | 28 | if (uid == 10118) { 29 | int debugFlags = (Integer) param.args[5]; 30 | param.args[5] = (debugFlags | 0x1); 31 | XposedBridge.log(TAG + "debugFlags: " + String.valueOf(param.args[5])); 32 | } 33 | } 34 | });**/ 35 | 36 | 37 | try { 38 | findAndHookMethod("android.os.Process", loadPackageParam.classLoader, "start", 39 | String.class, String.class, int.class, int.class, int[].class, int.class, int.class, int.class, 40 | String.class, String.class, String.class, String.class, String[].class, new XC_MethodHook() { 41 | 42 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 43 | 44 | int uid = (Integer) param.args[2]; 45 | if (uid == 10066) { 46 | int debugFlags = (Integer) param.args[5]; 47 | param.args[5] = (debugFlags | 0x1); 48 | XposedBridge.log(TAG + "debugFlags: " + String.valueOf(param.args[5])); 49 | } 50 | } 51 | } 52 | 53 | ); 54 | }catch (Error e){ 55 | XposedBridge.log("ERROR_PROCESS: "+e.getMessage()); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/hooks/ProxyHook.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.hooks; 2 | 3 | import android.os.Build; 4 | 5 | import org.apache.http.HttpHost; 6 | import org.apache.http.conn.params.ConnRoutePNames; 7 | import org.apache.http.impl.client.DefaultHttpClient; 8 | 9 | import java.net.URI; 10 | 11 | import de.robv.android.xposed.XC_MethodHook; 12 | import de.robv.android.xposed.XSharedPreferences; 13 | import de.robv.android.xposed.XposedBridge; 14 | import de.robv.android.xposed.XposedHelpers; 15 | import de.robv.android.xposed.callbacks.XC_LoadPackage; 16 | import mobi.acpm.inspeckage.Module; 17 | 18 | import static de.robv.android.xposed.XposedBridge.hookAllConstructors; 19 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; 20 | 21 | /** 22 | * Created by acpm on 21/11/15. 23 | */ 24 | public class ProxyHook extends XC_MethodHook { 25 | 26 | public static final String TAG = "Inspeckage_Proxy:"; 27 | private static XSharedPreferences sPrefs; 28 | 29 | public static void loadPrefs() { 30 | sPrefs = new XSharedPreferences(Module.class.getPackage().getName(), Module.PREFS); 31 | sPrefs.makeWorldReadable(); 32 | } 33 | 34 | public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) { 35 | 36 | 37 | XC_MethodHook ProxySelectorHook = new XC_MethodHook() { 38 | @Override 39 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 40 | 41 | loadPrefs(); 42 | 43 | if (sPrefs.getBoolean("switch_proxy", false)) { 44 | 45 | System.setProperty("proxyHost", sPrefs.getString("host", null)); 46 | System.setProperty("proxyPort", sPrefs.getString("port", null)); 47 | 48 | System.setProperty("http.proxyHost", sPrefs.getString("host", null)); 49 | System.setProperty("http.proxyPort", sPrefs.getString("port", null)); 50 | 51 | System.setProperty("https.proxyHost", sPrefs.getString("host", null)); 52 | System.setProperty("https.proxyPort", sPrefs.getString("port", null)); 53 | 54 | System.setProperty("socksProxyHost", sPrefs.getString("host", null)); 55 | System.setProperty("socksProxyPort", sPrefs.getString("port", null)); 56 | 57 | 58 | URI uri = (URI) param.args[0]; 59 | 60 | XposedBridge.log(TAG + " [P:" + sPrefs.getString("host", null) + ":" + sPrefs.getString("port", null) + "] - URI = " + uri); 61 | } 62 | } 63 | }; 64 | 65 | try { 66 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) { 67 | findAndHookMethod("java.net.ProxySelectorImpl", loadPackageParam.classLoader, "select", URI.class, ProxySelectorHook); 68 | } else { 69 | findAndHookMethod("sun.net.spi.DefaultProxySelector", loadPackageParam.classLoader, "select", URI.class, ProxySelectorHook); 70 | } 71 | } catch (Error e) { 72 | Module.logError(e); 73 | } 74 | 75 | hookAllConstructors(XposedHelpers.findClass("org.apache.http.impl.client.DefaultHttpClient", loadPackageParam.classLoader), new XC_MethodHook() { 76 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 77 | 78 | loadPrefs(); 79 | 80 | if (sPrefs.getBoolean("switch_proxy", false)) { 81 | String proxyHost = sPrefs.getString("host", null); 82 | int proxyPort; 83 | try { 84 | proxyPort = Integer.parseInt(sPrefs.getString("port", null)); 85 | } catch (NumberFormatException ex) { 86 | proxyPort = -1; 87 | } 88 | 89 | DefaultHttpClient httpClient = (DefaultHttpClient) param.thisObject; 90 | HttpHost proxy = new HttpHost(proxyHost, proxyPort); 91 | httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy); 92 | } 93 | } 94 | }); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/hooks/SerializationHook.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.hooks; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.File; 5 | import java.io.FileInputStream; 6 | import java.io.IOException; 7 | import java.io.ObjectInputStream; 8 | import java.io.ObjectOutput; 9 | import java.io.ObjectOutputStream; 10 | 11 | import de.robv.android.xposed.XC_MethodHook; 12 | import de.robv.android.xposed.XposedBridge; 13 | import de.robv.android.xposed.callbacks.XC_LoadPackage; 14 | import mobi.acpm.inspeckage.util.Util; 15 | 16 | import static de.robv.android.xposed.XposedHelpers.findAndHookConstructor; 17 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; 18 | 19 | /** 20 | * Created by acpm on 17/01/16. 21 | */ 22 | public class SerializationHook extends XC_MethodHook { 23 | 24 | public static final String TAG = "Inspeckage_Serialization:"; 25 | 26 | static String f = ""; 27 | public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) { 28 | 29 | 30 | findAndHookConstructor(FileInputStream.class, File.class, new XC_MethodHook() { 31 | 32 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 33 | 34 | File file = (File) param.args[0]; 35 | if (file != null) { 36 | /// 37 | if (!file.getPath().contains("inspeckage") && (file.getPath().contains("data/data/") 38 | || file.getPath().contains("storage/emulated/") || file.getPath().contains("data/media/"))) { 39 | 40 | f = file.getPath(); 41 | } 42 | } 43 | 44 | } 45 | }); 46 | 47 | findAndHookMethod(ObjectInputStream.class, "readObject", new XC_MethodHook() { 48 | 49 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 50 | 51 | Object paramObject = param.getResult(); 52 | StringBuilder sb = new StringBuilder(); 53 | 54 | if (paramObject != null) { 55 | 56 | String name = paramObject.getClass().getCanonicalName(); 57 | if(name != null) { 58 | if (name.length() > 5 && name.substring(0, 5).contains("java.") || name.substring(0, 5).contains("byte")) { 59 | //do nothing 60 | } else { 61 | 62 | sb.append("Read Object[" + name + "] HEX = "); 63 | 64 | ByteArrayOutputStream bos = new ByteArrayOutputStream(); 65 | 66 | try { 67 | ObjectOutput out = new ObjectOutputStream(bos); 68 | out.writeObject(paramObject); 69 | byte[] yourBytes = bos.toByteArray(); 70 | String hex = Util.toHexString(yourBytes); 71 | 72 | sb.append(hex); 73 | XposedBridge.log(TAG + "Possible Path [" + f + "] " + sb.toString()); 74 | } catch (NullPointerException e) { 75 | // 76 | } catch (IOException i) { 77 | i.printStackTrace(); 78 | } 79 | } 80 | } 81 | } 82 | } 83 | }); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/hooks/UIHook.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.hooks; 2 | 3 | import android.app.Activity; 4 | import android.app.Fragment; 5 | import android.content.Context; 6 | import android.content.IntentFilter; 7 | import android.os.Bundle; 8 | 9 | import de.robv.android.xposed.XC_MethodHook; 10 | import de.robv.android.xposed.callbacks.XC_LoadPackage; 11 | import mobi.acpm.inspeckage.receivers.InspeckageReceiver; 12 | 13 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; 14 | 15 | /** 16 | * Created by acpm on 17/07/16. 17 | */ 18 | public class UIHook extends XC_MethodHook { 19 | 20 | public static final String TAG = "Inspeckage_GUI:"; 21 | 22 | public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) { 23 | 24 | findAndHookMethod(Activity.class, "onCreate", Bundle.class, new XC_MethodHook() { 25 | 26 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 27 | 28 | Activity appCompatActivity = (Activity) param.thisObject; 29 | 30 | Context context = (Context) appCompatActivity.getApplicationContext(); 31 | context.registerReceiver(new InspeckageReceiver(param.thisObject), 32 | new IntentFilter("mobi.acpm.inspeckage.INSPECKAGE_FILTER")); 33 | 34 | } 35 | }); 36 | 37 | findAndHookMethod(Fragment.class, "onCreate", Bundle.class, new XC_MethodHook() { 38 | 39 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 40 | 41 | Fragment fragment = (Fragment) param.thisObject; 42 | 43 | Context context = (Context) fragment.getActivity().getApplicationContext(); 44 | context.registerReceiver(new InspeckageReceiver(param.thisObject), 45 | new IntentFilter("mobi.acpm.inspeckage.INSPECKAGE_FILTER")); 46 | 47 | } 48 | }); 49 | 50 | //findAndHookMethod(Activity.class, "finish", new XC_MethodHook() { 51 | 52 | //protected void afterHookedMethod(MethodHookParam param) throws Throwable { 53 | 54 | //android.os.Process.killProcess(android.os.Process.myPid()); 55 | 56 | //} 57 | //}); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/hooks/UserHooks.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.hooks; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.GsonBuilder; 5 | import com.google.gson.JsonSyntaxException; 6 | 7 | import org.json.JSONArray; 8 | import org.json.JSONObject; 9 | 10 | import java.lang.reflect.Constructor; 11 | import java.lang.reflect.Method; 12 | import java.lang.reflect.Modifier; 13 | import java.util.List; 14 | 15 | import de.robv.android.xposed.XC_MethodHook; 16 | import de.robv.android.xposed.XSharedPreferences; 17 | import de.robv.android.xposed.XposedBridge; 18 | import de.robv.android.xposed.callbacks.XC_LoadPackage; 19 | import mobi.acpm.inspeckage.Module; 20 | import mobi.acpm.inspeckage.util.Config; 21 | import mobi.acpm.inspeckage.util.Replacement; 22 | import mobi.acpm.inspeckage.util.Util; 23 | 24 | import static de.robv.android.xposed.XposedBridge.log; 25 | import static de.robv.android.xposed.XposedHelpers.findClass; 26 | 27 | /** 28 | * Created by acpm on 19/04/16. 29 | */ 30 | public class UserHooks extends XC_MethodHook { 31 | 32 | public static final String TAG = "Inspeckage_UserHooks:"; 33 | private static Gson gson = new GsonBuilder().disableHtmlEscaping().create();//new Gson(); 34 | private static XSharedPreferences sPrefs; 35 | private static XC_LoadPackage.LoadPackageParam lpp; 36 | 37 | public static void loadPrefs() { 38 | sPrefs = new XSharedPreferences(Module.class.getPackage().getName(), Module.PREFS); 39 | sPrefs.makeWorldReadable(); 40 | } 41 | 42 | public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) { 43 | loadPrefs(); 44 | lpp = loadPackageParam; 45 | String json = "{\"hookJson\": " + sPrefs.getString(Config.SP_USER_HOOKS, "") + "}"; 46 | try { 47 | 48 | if(!json.trim().equals("{\"hookJson\":}")) { 49 | HookList hookList = gson.fromJson(json, HookList.class); 50 | for (HookItem hookItem : hookList.hookJson) { 51 | if(hookItem.state) { 52 | hook(hookItem, loadPackageParam.classLoader); 53 | } 54 | } 55 | } 56 | } catch (JsonSyntaxException ex) { } 57 | } 58 | 59 | static void hook(HookItem item, ClassLoader classLoader) { 60 | try { 61 | Class hookClass = findClass(item.className, classLoader); 62 | 63 | if (hookClass != null) { 64 | 65 | if (item.method != null && !item.method.equals("")) { 66 | for (Method method : hookClass.getDeclaredMethods()) { 67 | if (method.getName().equals(item.method) && !Modifier.isAbstract(method.getModifiers())) { 68 | XposedBridge.hookMethod(method, methodHook); 69 | } 70 | } 71 | } else { 72 | for (Method method : hookClass.getDeclaredMethods()) { 73 | if(!Modifier.isAbstract(method.getModifiers())) { 74 | XposedBridge.hookMethod(method, methodHook); 75 | } 76 | } 77 | } 78 | 79 | if (item.constructor) { 80 | for (Constructor constructor : hookClass.getDeclaredConstructors()) { 81 | XposedBridge.hookMethod(constructor, methodHook); 82 | } 83 | } 84 | 85 | } else { 86 | log(TAG + "class not found."); 87 | } 88 | } catch (Error e) { 89 | Module.logError(e); 90 | } 91 | } 92 | 93 | static XC_MethodHook methodHook = new XC_MethodHook() { 94 | 95 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 96 | loadPrefs(); 97 | Replacement.parameterReplace(param, sPrefs); 98 | } 99 | 100 | protected void afterHookedMethod(MethodHookParam param) throws Throwable { 101 | loadPrefs(); 102 | Replacement.resultReplace(param, sPrefs); 103 | parseParam(param); 104 | } 105 | }; 106 | 107 | static void parseParam(XC_MethodHook.MethodHookParam param) { 108 | try { 109 | JSONObject hookData = new JSONObject(); 110 | hookData.put("class", param.method.getDeclaringClass().getName()); 111 | 112 | if(param.method!=null) 113 | hookData.put("method", param.method.getName()); 114 | 115 | JSONArray args = new JSONArray(); 116 | 117 | if(param.args!=null) { 118 | for (Object object : (Object[]) param.args) { 119 | 120 | if (object != null) { 121 | if(object.getClass().equals(byte[].class)){ 122 | String result = Util.byteArrayToString((byte[])object); 123 | args.put(gson.toJson(result)); 124 | }else{ 125 | args.put(gson.toJson(object)); 126 | } 127 | } 128 | } 129 | hookData.put("args", args); 130 | } 131 | 132 | if(param.getResult()!=null){ 133 | String result = ""; 134 | if(param.getResult().getClass().equals(byte[].class)){ 135 | result = Util.byteArrayToString((byte[])param.getResult()); 136 | hookData.put("result", gson.toJson(result)); 137 | }else{ 138 | hookData.put("result", gson.toJson(param.getResult())); 139 | } 140 | 141 | } 142 | 143 | log(TAG + hookData.toString()); 144 | 145 | } catch (Exception e) { 146 | e.getMessage(); 147 | } 148 | } 149 | } 150 | 151 | class HookList { 152 | public List hookJson; 153 | } 154 | 155 | class HookItem { 156 | protected int id; 157 | protected String className; 158 | protected String method; 159 | protected boolean constructor; 160 | protected boolean state; 161 | } 162 | -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/hooks/WebViewHook.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.hooks; 2 | 3 | import android.webkit.WebChromeClient; 4 | import android.webkit.WebSettings; 5 | import android.webkit.WebView; 6 | import android.webkit.WebViewClient; 7 | 8 | import de.robv.android.xposed.XC_MethodHook; 9 | import de.robv.android.xposed.XposedBridge; 10 | import de.robv.android.xposed.callbacks.XC_LoadPackage; 11 | 12 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; 13 | 14 | /** 15 | * Created by acpm on 24/11/15. 16 | */ 17 | public class WebViewHook extends XC_MethodHook { 18 | 19 | public static final String TAG = "Inspeckage_WebView:"; 20 | 21 | static StringBuilder sb = null; 22 | 23 | public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) { 24 | 25 | //Injects the supplied Java object into this WebView. 26 | //http://developer.android.com/intl/pt-br/reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object, java.lang.String) 27 | findAndHookMethod(WebView.class, "addJavascriptInterface", 28 | Object.class, String.class, new XC_MethodHook() { 29 | 30 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 31 | String objName = (String) param.args[1]; 32 | XposedBridge.log(TAG + "addJavascriptInterface(Object, " + objName + ");"); 33 | } 34 | }); 35 | 36 | findAndHookMethod(WebView.class, "loadUrl", 37 | String.class, new XC_MethodHook() { 38 | 39 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 40 | 41 | sb = new StringBuilder(); 42 | WebView wv = (WebView) param.thisObject; 43 | sb.append("Load URL: " + param.args[0]); 44 | 45 | sb.append(checkSettings(wv)); 46 | 47 | XposedBridge.log(TAG + sb.toString()); 48 | } 49 | }); 50 | 51 | findAndHookMethod(WebView.class, "loadData", 52 | String.class, String.class, String.class, new XC_MethodHook() { 53 | 54 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 55 | 56 | sb = new StringBuilder(); 57 | WebView wv = (WebView) param.thisObject; 58 | 59 | sb.append("Load Data: " + param.args[0]); 60 | 61 | sb.append(checkSettings(wv)); 62 | 63 | XposedBridge.log(TAG + sb.toString()); 64 | 65 | } 66 | }); 67 | 68 | findAndHookMethod(WebView.class, "setWebChromeClient", WebChromeClient.class, new XC_MethodHook() { 69 | @Override 70 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 71 | 72 | XposedBridge.log(TAG + "Client: WebChrome"); 73 | } 74 | }); 75 | 76 | findAndHookMethod(WebView.class, "setWebViewClient", WebViewClient.class, new XC_MethodHook() { 77 | @Override 78 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 79 | 80 | //XposedBridge.log(TAG + "Client: WebView"); 81 | } 82 | }); 83 | 84 | findAndHookMethod(WebView.class, "setWebContentsDebuggingEnabled", "boolean", new XC_MethodHook() { 85 | @Override 86 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 87 | boolean value = (boolean) param.args[0]; 88 | XposedBridge.log(TAG + "Web Contents Debugging Enabled: " + String.valueOf(value)); 89 | } 90 | }); 91 | 92 | } 93 | 94 | static String checkSettings(WebView wv) { 95 | 96 | String r = "
"; 97 | //javascript 98 | if (wv.getSettings().getJavaScriptEnabled()) { 99 | r = r + " -- JavaScript: Enable
"; 100 | } else { 101 | r = r + " -- JavaScript: Disable
"; 102 | } 103 | //PluginState 104 | if (wv.getSettings().getPluginState() == WebSettings.PluginState.OFF) { 105 | r = r + " -- Plugin State: OFF
"; 106 | } else { 107 | r = r + " -- Plugin State: ON
"; 108 | } 109 | //AllowFileAccess 110 | if (wv.getSettings().getAllowFileAccess()) { 111 | r = r + " -- Allow File Access: Enable
"; 112 | } else { 113 | r = r + " -- Allow File Access: Disable
"; 114 | } 115 | return r; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/hooks/entities/FingerprintItem.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.hooks.entities; 2 | 3 | /** 4 | * Created by acpm on 29/04/17. 5 | */ 6 | 7 | public class FingerprintItem { 8 | 9 | public String type; 10 | public String name; 11 | public String value; 12 | public String newValue; 13 | public boolean enable; 14 | 15 | public FingerprintItem(String type, String name, String value, String newValue, boolean enable){ 16 | this.type = type; 17 | this.name = name; 18 | this.value = value; 19 | this.newValue = newValue; 20 | this.enable = enable; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/hooks/entities/FingerprintList.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.hooks.entities; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created by acpm on 29/04/17. 7 | */ 8 | 9 | public class FingerprintList { 10 | 11 | public List fingerprintItems; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/hooks/entities/LocationHook.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.hooks.entities; 2 | 3 | import de.robv.android.xposed.XC_MethodHook; 4 | import de.robv.android.xposed.XSharedPreferences; 5 | import de.robv.android.xposed.XposedHelpers; 6 | import de.robv.android.xposed.callbacks.XC_LoadPackage; 7 | import mobi.acpm.inspeckage.Module; 8 | 9 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; 10 | 11 | /** 12 | * Created by acpm on 21/05/17. 13 | */ 14 | 15 | public class LocationHook extends XC_MethodHook { 16 | 17 | public static final String TAG = "Inspeckage_Location: "; 18 | private static XSharedPreferences sPrefs; 19 | 20 | public static void loadPrefs() { 21 | sPrefs = new XSharedPreferences(Module.class.getPackage().getName(), Module.PREFS); 22 | sPrefs.makeWorldReadable(); 23 | } 24 | 25 | public static void initAllHooks(final XC_LoadPackage.LoadPackageParam loadPackageParam) { 26 | 27 | try { 28 | Class location = XposedHelpers.findClass("android.location.Location", loadPackageParam.classLoader); 29 | 30 | findAndHookMethod(location, "getLatitude", new XC_MethodHook() { 31 | 32 | @Override 33 | protected void afterHookedMethod(MethodHookParam param) 34 | throws Throwable { 35 | super.afterHookedMethod(param); 36 | 37 | loadPrefs(); 38 | String geolocation = sPrefs.getString("geoloc", ""); 39 | if (!geolocation.equals("") && geolocation.contains(",")) { 40 | final String[] latlng = geolocation.split(","); 41 | param.setResult(Double.valueOf(latlng[0])); 42 | } 43 | } 44 | }); 45 | 46 | findAndHookMethod(location, "getLongitude", new XC_MethodHook() { 47 | 48 | @Override 49 | protected void afterHookedMethod(MethodHookParam param) 50 | throws Throwable { 51 | super.afterHookedMethod(param); 52 | loadPrefs(); 53 | String geolocation = sPrefs.getString("geoloc", ""); 54 | if (!geolocation.equals("") && geolocation.contains(",")) { 55 | final String[] latlng = geolocation.split(","); 56 | param.setResult(Double.valueOf(latlng[1])); 57 | } 58 | } 59 | }); 60 | 61 | } catch (XposedHelpers.ClassNotFoundError ex) { 62 | } catch (Exception ex) { 63 | ex.printStackTrace(); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/log/LogService.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.log; 2 | 3 | import android.app.Service; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.content.SharedPreferences; 7 | import android.os.IBinder; 8 | import android.util.Log; 9 | import android.widget.Toast; 10 | 11 | import java.io.BufferedReader; 12 | import java.io.IOException; 13 | import java.io.InputStreamReader; 14 | import java.nio.channels.NotYetConnectedException; 15 | 16 | import mobi.acpm.inspeckage.Module; 17 | import mobi.acpm.inspeckage.util.Config; 18 | 19 | /** 20 | * Created by acpm on 14/03/16. 21 | */ 22 | public class LogService extends Service { 23 | 24 | public static final String TAG = "Inspeckage_Log"; 25 | private boolean isStarted = false; 26 | private String pid = ""; 27 | private Thread logThread; 28 | private Thread pidThread; 29 | private java.lang.Process logProcess; 30 | private WSocketServer wss; 31 | private SharedPreferences mPrefs; 32 | 33 | @Override 34 | public IBinder onBind(Intent intent) { 35 | return null; 36 | } 37 | 38 | @Override 39 | public void onCreate() { 40 | super.onCreate(); 41 | } 42 | 43 | public int onStartCommand(Intent intent, int flags, int startId) { 44 | // Let it continue running until it is stopped. 45 | Context context = getApplicationContext(); 46 | 47 | try { 48 | 49 | int port = 8887; 50 | String filter = ""; 51 | 52 | if (intent != null && intent.getExtras() != null) { 53 | port = intent.getIntExtra("port", 8887); 54 | filter = intent.getStringExtra("filter"); 55 | } 56 | 57 | mPrefs = context.getSharedPreferences(Module.PREFS, context.MODE_PRIVATE); 58 | 59 | wss = new WSocketServer(port); 60 | wss.start(); 61 | 62 | startLogger(filter); 63 | 64 | Toast.makeText(this, "LogService started on port " + port, Toast.LENGTH_LONG).show(); 65 | 66 | } catch (Exception e) { 67 | e.printStackTrace(); 68 | } 69 | return START_STICKY; 70 | } 71 | 72 | @Override 73 | public void onDestroy() { 74 | super.onDestroy(); 75 | if (wss != null) 76 | try { 77 | stopLogger(); 78 | wss.stop(); 79 | Toast.makeText(this, "LogService stopped", Toast.LENGTH_LONG).show(); 80 | } catch (IOException | InterruptedException e) { 81 | e.printStackTrace(); 82 | } 83 | } 84 | 85 | private void startLogger(final String filter) { 86 | if (!isStarted) { 87 | logThread = new Thread(new Runnable() { 88 | @Override 89 | public void run() { 90 | 91 | try { 92 | 93 | Runtime.getRuntime().exec("su -c logcat -c"); 94 | String cmd = "su -c logcat |grep -v Xposed |grep -v Inspeckage |grep -v E/ |grep -v I/ |grep -v W/ |grep -v F/ |grep -v V/ |grep -v W/ |grep -v D/"; 95 | 96 | String[] filters = filter.split(","); 97 | 98 | for (String filter1 : filters) { 99 | if (cmd.contains(filter1 + "/")) { 100 | cmd = cmd.replace("|grep -v " + filter1 + "/", ""); 101 | } 102 | } 103 | 104 | 105 | logProcess = Runtime.getRuntime().exec(cmd); 106 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(logProcess.getInputStream())); 107 | 108 | String line; 109 | while (isStarted && (line = bufferedReader.readLine()) != null) { 110 | 111 | if (pid.trim().length() > 2 && line.contains(pid.trim())) { 112 | wss.sendToClient(line); 113 | } 114 | } 115 | logProcess.destroy(); 116 | } catch (IOException | NotYetConnectedException e) { 117 | Log.e(TAG, "LogService failed: " + e.getMessage()); 118 | } 119 | } 120 | }, "Logger_Thread"); 121 | logThread.start(); 122 | isStarted = true; 123 | //---PID 124 | pidThread = new Thread(new Runnable() { 125 | @Override 126 | public void run() { 127 | 128 | try { 129 | 130 | while (isStarted) { 131 | 132 | String name = mPrefs.getString(Config.SP_PACKAGE, "null"); 133 | String ps = "su -c ps |grep "+name; 134 | Process p = Runtime.getRuntime().exec(ps); 135 | BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream())); 136 | String var = ""; 137 | String psline; 138 | while ((psline = br.readLine()) != null) { 139 | if (psline.contains(" " + name)) { 140 | var = psline; 141 | } 142 | } 143 | 144 | if (var.length() > 10) { 145 | String tmp = var.replaceAll("\\s+", " "); 146 | pid = tmp.split(" ")[1]; 147 | } 148 | 149 | synchronized (this) { 150 | try { 151 | wait(3000); 152 | } catch (InterruptedException e) { 153 | } 154 | } 155 | } 156 | } catch (IOException | NotYetConnectedException e) { 157 | Log.e(TAG, "LogService failed: " + e.getMessage()); 158 | } 159 | } 160 | }, "Logger_Thread"); 161 | pidThread.start(); 162 | 163 | } 164 | } 165 | 166 | public void stopLogger() { 167 | if (isStarted) { 168 | isStarted = false; 169 | try { 170 | logProcess.destroy(); 171 | pidThread.join(); 172 | logThread.join(); 173 | } catch (InterruptedException e) { 174 | e.printStackTrace(); 175 | } 176 | } 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/log/WSocketServer.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.log; 2 | 3 | import org.java_websocket.WebSocket; 4 | import org.java_websocket.handshake.ClientHandshake; 5 | import org.java_websocket.server.WebSocketServer; 6 | 7 | import java.net.InetSocketAddress; 8 | import java.net.UnknownHostException; 9 | import java.util.Collection; 10 | 11 | /** 12 | * Created by acpm on 13/03/16. 13 | */ 14 | public class WSocketServer extends WebSocketServer { 15 | 16 | public WSocketServer( int port ) throws UnknownHostException { 17 | super( new InetSocketAddress( port ) ); 18 | } 19 | 20 | public WSocketServer( InetSocketAddress address ) { 21 | super( address ); 22 | } 23 | 24 | @Override 25 | public void onOpen(WebSocket webSocket, ClientHandshake clientHandshake) { 26 | this.sendToClient( "[Handshake Ok]"); 27 | } 28 | 29 | @Override 30 | public void onClose(WebSocket webSocket, int i, String s, boolean b) { 31 | this.sendToClient(webSocket + " close" ); 32 | } 33 | 34 | @Override 35 | public void onMessage(WebSocket webSocket, String message) { 36 | this.sendToClient(message ); 37 | } 38 | 39 | @Override 40 | public void onError(WebSocket webSocket, Exception e) { 41 | e.printStackTrace(); 42 | if( webSocket != null ) { 43 | // some errors like port binding failed may not be assignable to a specific websocket 44 | } 45 | } 46 | 47 | public void sendToClient( String text ) { 48 | Collection con = connections(); 49 | synchronized ( con ) { 50 | for( WebSocket c : con ) { 51 | c.send( text ); 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/receivers/InspeckageWebReceiver.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.receivers; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.content.SharedPreferences; 7 | 8 | import mobi.acpm.inspeckage.Module; 9 | import mobi.acpm.inspeckage.util.Config; 10 | 11 | /** 12 | * Created by acpm on 20/01/16. 13 | */ 14 | public class InspeckageWebReceiver extends BroadcastReceiver { 15 | 16 | private Context mContext; 17 | public InspeckageWebReceiver(){ 18 | 19 | } 20 | public InspeckageWebReceiver(Context ctx){ 21 | mContext = ctx; 22 | } 23 | @Override 24 | public void onReceive(Context context, Intent intent) { 25 | 26 | SharedPreferences mPrefs = context.getSharedPreferences(Module.PREFS, mContext.MODE_PRIVATE); 27 | SharedPreferences.Editor edit = mPrefs.edit(); 28 | 29 | String action = intent.getExtras().getString("action"); 30 | 31 | if(action.equals("fileTree")){ 32 | 33 | String sub1 = intent.getExtras().getString("tree"); 34 | 35 | String script = ""; 42 | 43 | String tree = script+"
    "+sub1+"
"; 44 | edit.putString(Config.SP_DATA_DIR_TREE, tree); 45 | edit.apply(); 46 | }else if(action.equals("checkApp")){ 47 | 48 | boolean isRunning = intent.getExtras().getBoolean("isRunning"); 49 | int pid = intent.getExtras().getInt("PID"); 50 | edit.putBoolean(Config.SP_APP_IS_RUNNING, isRunning); 51 | edit.putInt(Config.SP_APP_PID, pid); 52 | edit.apply(); 53 | }else if(action.equals("clipboard")){ 54 | 55 | String value = intent.getExtras().getString("value"); 56 | 57 | android.content.ClipboardManager clipboard = (android.content.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); 58 | android.content.ClipData clip = android.content.ClipData 59 | .newPlainText("simple text", value); 60 | clipboard.setPrimaryClip(clip); 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/ui/ExpandableListAdapter.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.ui; 2 | 3 | import android.content.Context; 4 | import android.graphics.Typeface; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.BaseExpandableListAdapter; 9 | import android.widget.ImageView; 10 | import android.widget.LinearLayout; 11 | import android.widget.TextView; 12 | 13 | import java.util.HashMap; 14 | import java.util.List; 15 | 16 | import mobi.acpm.inspeckage.R; 17 | 18 | /** 19 | * Created by acpm on 17/11/15. 20 | */ 21 | public class ExpandableListAdapter extends BaseExpandableListAdapter { 22 | 23 | private Context mContext; 24 | private List mListDataHeader; 25 | private HashMap> mListDataChild; 26 | 27 | public ExpandableListAdapter(Context context, List listDataHeader, 28 | HashMap> listChildData) { 29 | this.mContext = context; 30 | this.mListDataHeader = listDataHeader; 31 | this.mListDataChild = listChildData; 32 | } 33 | 34 | @Override 35 | public Object getChild(int groupPosition, int childPosititon) { 36 | return this.mListDataChild.get(this.mListDataHeader.get(groupPosition)) 37 | .get(childPosititon); 38 | } 39 | 40 | @Override 41 | public long getChildId(int groupPosition, int childPosition) { 42 | return childPosition; 43 | } 44 | 45 | @Override 46 | public View getChildView(int groupPosition, final int childPosition, 47 | boolean isLastChild, View convertView, ViewGroup parent) { 48 | 49 | final ExpandableListItem childText = (ExpandableListItem) getChild(groupPosition, childPosition); 50 | 51 | if (convertView == null) { 52 | LayoutInflater infalInflater = (LayoutInflater) this.mContext 53 | .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 54 | 55 | convertView = infalInflater.inflate(R.layout.list_item, null); 56 | } 57 | 58 | ImageView iconImage = (ImageView)convertView.findViewById(R.id.imageViewIcon); 59 | iconImage.setImageDrawable(childText.getIcon()); 60 | 61 | LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(90, 90); 62 | iconImage.setLayoutParams(layoutParams); 63 | 64 | TextView txtListChild = (TextView) convertView.findViewById(R.id.txtListItem); 65 | txtListChild.setText(childText.getAppName()); 66 | 67 | TextView txtListPkg = (TextView) convertView.findViewById(R.id.txtListPkg); 68 | txtListPkg.setText(childText.getPckName()); 69 | 70 | /** 71 | if(childText.isSelected()) { 72 | txtListChild.setTextColor(0xFF00BFA5); 73 | txtListPkg.setTextColor(0xFF00BFA5); 74 | }else{ 75 | txtListChild.setTextColor(Color.BLACK); 76 | txtListPkg.setTextColor(Color.BLACK); 77 | txtListChild.setBackgroundColor(Color.WHITE); 78 | txtListPkg.setBackgroundColor(Color.WHITE); 79 | }**/ 80 | 81 | return convertView; 82 | } 83 | 84 | @Override 85 | public int getChildrenCount(int groupPosition) { 86 | return this.mListDataChild.get(this.mListDataHeader.get(groupPosition)) 87 | .size(); 88 | } 89 | 90 | @Override 91 | public Object getGroup(int groupPosition) { 92 | return this.mListDataHeader.get(groupPosition); 93 | } 94 | 95 | @Override 96 | public int getGroupCount() { 97 | return this.mListDataHeader.size(); 98 | } 99 | 100 | @Override 101 | public long getGroupId(int groupPosition) { 102 | return groupPosition; 103 | } 104 | 105 | @Override 106 | public View getGroupView(int groupPosition, boolean isExpanded, 107 | View convertView, ViewGroup parent) { 108 | String headerTitle = (String) getGroup(groupPosition); 109 | if (convertView == null) { 110 | LayoutInflater infalInflater = (LayoutInflater) this.mContext 111 | .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 112 | convertView = infalInflater.inflate(R.layout.list_group, null); 113 | } 114 | 115 | TextView lblListHeader = (TextView) convertView 116 | .findViewById(R.id.lblListHeader); 117 | lblListHeader.setTypeface(null, Typeface.BOLD); 118 | lblListHeader.setText(headerTitle); 119 | 120 | return convertView; 121 | } 122 | 123 | @Override 124 | public boolean hasStableIds() { 125 | return false; 126 | } 127 | 128 | @Override 129 | public boolean isChildSelectable(int groupPosition, int childPosition) { 130 | return true; 131 | } 132 | } -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/ui/ExpandableListItem.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.ui; 2 | 3 | import android.graphics.drawable.Drawable; 4 | 5 | /** 6 | * Created by acpm on 17/11/15. 7 | */ 8 | public class ExpandableListItem { 9 | 10 | private String mAppName = ""; 11 | private String mPackageName = ""; 12 | private boolean mIsSelected = false; 13 | private Drawable mIcon; 14 | 15 | public String getAppName() { 16 | return mAppName; 17 | } 18 | 19 | public void setAppName(String mAppName) { 20 | this.mAppName = mAppName; 21 | } 22 | 23 | public String getPckName() { 24 | return mPackageName; 25 | } 26 | 27 | public void setPckName(String packName) { 28 | this.mPackageName = packName; 29 | } 30 | 31 | public Drawable getIcon() { 32 | return mIcon; 33 | } 34 | 35 | public void setIcon(Drawable icon) { 36 | this.mIcon = icon; 37 | } 38 | 39 | public boolean isSelected() { 40 | return mIsSelected; 41 | } 42 | 43 | public void setSelected(boolean bypassed) { 44 | this.mIsSelected = bypassed; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/ui/SplashActivity.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.ui; 2 | 3 | import android.content.Intent; 4 | import android.content.SharedPreferences; 5 | import android.os.Bundle; 6 | import android.os.Handler; 7 | import android.support.v7.app.AppCompatActivity; 8 | 9 | import mobi.acpm.inspeckage.Module; 10 | import mobi.acpm.inspeckage.R; 11 | import mobi.acpm.inspeckage.util.FileUtil; 12 | 13 | public class SplashActivity extends AppCompatActivity { 14 | 15 | private static int TIME_OUT = 2000; 16 | private SharedPreferences mPrefs; 17 | 18 | @Override 19 | protected void onCreate(Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | setContentView(R.layout.activity_splash); 22 | 23 | mPrefs = getSharedPreferences(Module.PREFS, MODE_PRIVATE); 24 | FileUtil.fixSharedPreference(this); 25 | 26 | new Handler().postDelayed(new Runnable() { 27 | 28 | @Override 29 | public void run() { 30 | Intent intent = new Intent(SplashActivity.this, MainActivity.class); 31 | startActivity(intent); 32 | finish(); 33 | } 34 | }, TIME_OUT); 35 | } 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/util/Config.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.util; 2 | 3 | /** 4 | * Created by acpm on 19/11/15. 5 | */ 6 | public class Config { 7 | 8 | //Paths 9 | public static final String P_INSPECKAGE_PATH = "/data/data/mobi.acpm.inspeckage"; 10 | public static final String P_SHARED_PATH = "/shared_prefs/"; 11 | public static final String P_ROOT = "/Inspeckage"; 12 | 13 | public static final String P_LOG = "/log"; 14 | public static final String P_PREFS = "/prefs"; 15 | public static final String P_CRYPTO = "/crypto"; 16 | public static final String P_SQLITE = "/sqlite"; 17 | public static final String P_HASH = "/hash"; 18 | public static final String P_PACKAGE_DETAIL = "/package_detail"; 19 | public static final String P_CLIPB = "/clipb"; 20 | public static final String P_IPC = "/ipc"; 21 | public static final String P_WEBVIEW = "/webview"; 22 | public static final String P_FILESYSTEM = "/filesystem"; 23 | public static final String P_MISC = "/miscellaneous"; 24 | public static final String P_SERIALIZATION = "/serialization"; 25 | public static final String P_HTTP = "/http"; 26 | public static final String P_USERHOOKS = "/user_hooks"; 27 | public static final String P_APP_STRUCT = "/struct"; 28 | public static final String P_REPLACEMENT = "/replacement"; 29 | public static final String PREFS_BKP = "/prefs_bkp/"; 30 | 31 | //Shared Preferences 32 | public static final String SP_PACKAGE = "package"; 33 | public static final String SP_APP_NAME = "app_name"; 34 | public static final String SP_APP_ICON_BASE64 = "app_icon_base64"; 35 | public static final String SP_PROCESS_NAME = "process"; 36 | public static final String SP_APP_VERSION = "app_version"; 37 | public static final String SP_DEBUGGABLE = "isDebuggable"; 38 | public static final String SP_ALLOW_BACKUP = "allowBackup"; 39 | public static final String SP_APK_DIR = "apk_dir"; 40 | public static final String SP_UID = "uid"; 41 | public static final String SP_GIDS = "gids"; 42 | public static final String SP_DATA_DIR = "path"; 43 | public static final String SP_DATA_DIR_TREE = "tree"; 44 | public static final String SP_APP_IS_RUNNING = "isRunning"; 45 | public static final String SP_APP_PID = "pid"; 46 | 47 | public static final String SP_SERVER_STARTED = "server_started"; 48 | public static final String SP_SERVER_INTERFACES = "server_interfaces"; 49 | public static final String SP_SERVER_HOST = "server_host"; 50 | public static final String SP_SERVER_PORT = "server_port"; 51 | public static final String SP_SERVER_IP = "server_ip"; 52 | 53 | public static final String SP_WSOCKET_PORT = "wsocket_port"; 54 | 55 | public static final String SP_REQ_PERMISSIONS = "req_permissions"; 56 | public static final String SP_APP_PERMISSIONS = "app_permissions"; 57 | 58 | public static final String SP_EXP_ACTIVITIES = "exported_act"; 59 | public static final String SP_N_EXP_ACTIVITIES = "non_exported_act"; 60 | 61 | public static final String SP_EXP_SERVICES = "exported_services"; 62 | public static final String SP_N_EXP_SERVICES = "non_exported_services"; 63 | 64 | public static final String SP_EXP_BROADCAST = "exported_broadcast"; 65 | public static final String SP_N_EXP_BROADCAST = "non_exported_broadcast"; 66 | 67 | public static final String SP_EXP_PROVIDER = "exported_provider"; 68 | public static final String SP_N_EXP_PROVIDER = "non_exported_provider"; 69 | 70 | public static final String SP_SHARED_LIB = "shared_libraries"; 71 | 72 | public static final String SP_REPLACE_SP = "prefs_replace"; 73 | 74 | public static final String SP_SWITCH_OUA = "switch"; //Only-User-Apps 75 | public static final String SP_PROXY_HOST = "host"; 76 | public static final String SP_PROXY_PORT = "port"; 77 | public static final String SP_SWITCH_PROXY = "switch_proxy"; 78 | public static final String SP_FLAG_SECURE = "flag_secure"; 79 | 80 | public static final String SP_UNPINNING = "sslunpinning"; 81 | public static final String SP_EXPORTED = "exported"; 82 | 83 | public static final String SP_HAS_W_PERMISSION = "write_permission"; 84 | 85 | public static final String SP_USER_HOOKS = "user_hooks"; 86 | public static final String SP_USER_REPLACES = "user_param_replaces"; 87 | public static final String SP_USER_RETURN_REPLACES = "user_return_replaces"; 88 | 89 | public static final String SP_TAB_ENABLE_SHAREDP = "enable_sharedp"; 90 | public static final String SP_TAB_ENABLE_SERIALIZATION = "enable_serialization"; 91 | public static final String SP_TAB_ENABLE_CRYPTO = "enable_crypto"; 92 | public static final String SP_TAB_ENABLE_HASH = "enable_hash"; 93 | public static final String SP_TAB_ENABLE_SQLITE = "enable_sqlite"; 94 | public static final String SP_TAB_ENABLE_HTTP = "enable_http"; 95 | public static final String SP_TAB_ENABLE_FS = "enable_fs"; 96 | public static final String SP_TAB_ENABLE_MISC = "enable_misc"; 97 | public static final String SP_TAB_ENABLE_WV = "enable_webview"; 98 | public static final String SP_TAB_ENABLE_IPC = "enable_ipc"; 99 | public static final String SP_TAB_ENABLE_PHOOKS = "enable_plus_hooks"; 100 | 101 | public static final String SP_USER_PASS = "login_pass"; 102 | public static final String SP_SWITCH_AUTH = "switch_auth"; 103 | 104 | public static final String KEYPAIR_ALIAS = "alias"; 105 | 106 | public static final String SP_FINGERPRINT_HOOKS = "fingerprint_hooks"; 107 | public static final String SP_ADS_ID = "ads_id"; 108 | 109 | public static final String SP_GEOLOCATION = "geoloc"; 110 | public static final String SP_GEOLOCATION_SW = "geoloc_switch"; 111 | } 112 | -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/util/DexUtil.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.util; 2 | 3 | import android.content.SharedPreferences; 4 | import android.util.Log; 5 | 6 | import com.google.gson.Gson; 7 | import com.google.gson.GsonBuilder; 8 | import com.google.gson.JsonElement; 9 | import com.google.gson.JsonObject; 10 | 11 | import java.lang.reflect.Method; 12 | import java.lang.reflect.Modifier; 13 | import java.util.ArrayList; 14 | import java.util.Enumeration; 15 | import java.util.HashMap; 16 | import java.util.List; 17 | import java.util.Map; 18 | 19 | import dalvik.system.DexFile; 20 | import de.robv.android.xposed.callbacks.XC_LoadPackage; 21 | 22 | import static android.text.TextUtils.isDigitsOnly; 23 | 24 | /** 25 | * Created by acpm on 19/09/16. 26 | */ 27 | public class DexUtil { 28 | 29 | 30 | public static Map> getClassesWithMethods(XC_LoadPackage.LoadPackageParam loadPackageParam, String packageName) throws Throwable { 31 | 32 | Map> classes = new HashMap>(); 33 | 34 | if (!packageName.trim().equals("") && loadPackageParam.appInfo.sourceDir.contains(packageName)) { 35 | 36 | DexFile dexFile = new DexFile(loadPackageParam.appInfo.sourceDir); 37 | 38 | Enumeration classNames = dexFile.entries(); 39 | 40 | while (classNames.hasMoreElements()) { 41 | final String className = classNames.nextElement(); 42 | 43 | //if (!packageName.trim().equals("") && className.contains(packageName)) { 44 | 45 | boolean subMethod = false; 46 | if (className.contains("$")) { 47 | String v = className.split("\\$")[1]; 48 | if (isDigitsOnly(v)) { 49 | subMethod = true; 50 | } 51 | } 52 | 53 | if (!subMethod && !className.contains(".R$")) { 54 | 55 | try { 56 | final Class cls = Class.forName(className, false, loadPackageParam.classLoader); 57 | 58 | if (cls != null && cls.getDeclaredMethods().length > 0) { 59 | ArrayList methods = new ArrayList<>(); 60 | for (final Method method : cls.getDeclaredMethods()) { 61 | if (!Modifier.isAbstract(method.getModifiers()) && !methods.contains(method.getName())) { 62 | methods.add(method.getName()); 63 | } 64 | } 65 | classes.put(className, methods); 66 | } 67 | } catch (NoClassDefFoundError ex) { 68 | Log.e("Error", ex.getMessage()); 69 | } catch (ClassNotFoundException ex) { 70 | Log.e("Error", ex.getMessage()); 71 | } 72 | 73 | } 74 | //} 75 | } 76 | } 77 | return classes; 78 | } 79 | 80 | public static void saveClassesWithMethodsJson(XC_LoadPackage.LoadPackageParam loadPackageParam, SharedPreferences prefs) throws Throwable { 81 | 82 | String packageName = prefs.getString("package", ""); 83 | Map> classes = DexUtil.getClassesWithMethods(loadPackageParam, packageName); 84 | 85 | //RAIZ 86 | ClassMethod root = new ClassMethod(); 87 | root.setID("p_" + packageName); 88 | root.setName(packageName); 89 | 90 | int c_id = 0; 91 | for (String classNameComplete : classes.keySet()) { 92 | 93 | if (classNameComplete.contains(packageName)) { 94 | c_id++; 95 | String pack_name = classNameComplete.substring(0, classNameComplete.lastIndexOf(".")); 96 | String class_name = classNameComplete.substring(classNameComplete.lastIndexOf(".") + 1); 97 | 98 | //pacote 99 | ClassMethod package_class = new ClassMethod(); 100 | package_class.setID(pack_name); 101 | package_class.setName(pack_name); 102 | 103 | if (!root.contains(package_class)) { 104 | root.getClassMethods().add(package_class); 105 | } 106 | 107 | //classe 108 | ClassMethod class_leaf = new ClassMethod(); 109 | class_leaf.setID(classNameComplete); 110 | class_leaf.setName(class_name); 111 | 112 | //adiciona metodos nas folhas(ultimas classes) 113 | ArrayList methods = classes.get(classNameComplete); 114 | int m_id = 0; 115 | for (String method : methods) { 116 | m_id++; 117 | ClassMethod m = new ClassMethod(); 118 | m.setID("m_" + c_id+"_"+m_id);// 119 | m.setName(method); 120 | m.setIcon("jstree-file"); 121 | if (!class_leaf.contains(m)) { 122 | class_leaf.getClassMethods().add(m); 123 | } 124 | } 125 | 126 | package_class.getClassMethods().add(class_leaf); 127 | root.update(package_class); 128 | 129 | } else { 130 | 131 | /**String name = classNameComplete.substring(0,classNameComplete.lastIndexOf(".")); 132 | 133 | ClassMethod cx = new ClassMethod(); 134 | cx.setID(name); 135 | cx.setName(name); 136 | 137 | if(!array.contains(cx)){ 138 | //c.getClassMethods().add(cx); 139 | }**/ 140 | } 141 | } 142 | 143 | Gson gson = new GsonBuilder().create(); 144 | JsonElement jsonElement = gson.toJsonTree(root); 145 | JsonObject jsonObject = jsonElement.getAsJsonObject(); 146 | 147 | FileUtil.writeToFile(prefs, jsonObject.toString(), FileType.APP_STRUCT, ""); 148 | } 149 | 150 | 151 | public static class ClassMethod { 152 | private String id; 153 | private String text; 154 | private String icon; 155 | 156 | private List children = new ArrayList(); 157 | 158 | public String getID() { 159 | return id; 160 | } 161 | 162 | public void setID(String id) { 163 | this.id = id; 164 | } 165 | 166 | public String getName() { 167 | return text; 168 | } 169 | 170 | public void setName(String name) { 171 | this.text = name; 172 | } 173 | 174 | public String getIcon() { 175 | return icon; 176 | } 177 | 178 | public void setIcon(String icon) { 179 | this.icon = icon; 180 | } 181 | 182 | 183 | public List getClassMethods() { 184 | return children; 185 | } 186 | 187 | public void setClassMethods(List children) { 188 | this.children = children; 189 | } 190 | 191 | public boolean contains(ClassMethod cm) { 192 | boolean x = false; 193 | 194 | for (ClassMethod c : getClassMethods()) { 195 | if (c.getID().equals(cm.getID())) { 196 | x = true; 197 | } 198 | } 199 | 200 | return x; 201 | } 202 | 203 | //se ja existir a classe entao pega os metodos da nova e atualiza a que ja existe 204 | public boolean update(ClassMethod cm) { 205 | boolean x = false; 206 | 207 | for (ClassMethod c : getClassMethods()) { 208 | if (c.getID().equals(cm.getID())) { 209 | for (ClassMethod cm2 : cm.getClassMethods()) { 210 | if (!c.contains(cm2)) { 211 | c.getClassMethods().add(cm2); 212 | } 213 | } 214 | x = true; 215 | } 216 | } 217 | 218 | 219 | return x; 220 | } 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/util/FileType.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.util; 2 | 3 | /** 4 | * Created by acpm on 16/11/15. 5 | */ 6 | public enum FileType { 7 | CRYPTO, 8 | HASH, 9 | PREFS, 10 | PREFS_BKP, 11 | LOG, 12 | PACKAGE, 13 | SQLITE, 14 | IPC, 15 | WEBVIEW, 16 | CLIPB, 17 | FILESYSTEM, 18 | MISC, 19 | SERIALIZATION, 20 | HTTP, 21 | USERHOOKS, 22 | APP_STRUCT, 23 | REPLACEMENT 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/mobi/acpm/inspeckage/webserver/InspeckageService.java: -------------------------------------------------------------------------------- 1 | package mobi.acpm.inspeckage.webserver; 2 | 3 | import android.app.Service; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.os.IBinder; 7 | import android.widget.Toast; 8 | 9 | import java.io.IOException; 10 | 11 | /** 12 | * Created by acpm on 17/11/15. 13 | */ 14 | public class InspeckageService extends Service { 15 | 16 | @Override 17 | public IBinder onBind(Intent intent) { 18 | return null; 19 | } 20 | 21 | @Override 22 | public void onCreate() { 23 | super.onCreate(); 24 | } 25 | 26 | private WebServer ws; 27 | @Override 28 | public int onStartCommand(Intent intent, int flags, int startId) { 29 | // Let it continue running until it is stopped. 30 | Context context = getApplicationContext(); 31 | 32 | String host = null; 33 | int port = 8008; 34 | if (intent != null && intent.getExtras() != null) { 35 | host = intent.getStringExtra("host"); 36 | port = intent.getIntExtra("port", 8008); 37 | } 38 | 39 | try { 40 | 41 | ws = new WebServer(host, port, context); 42 | 43 | 44 | } catch (IOException e) { 45 | e.printStackTrace(); 46 | } 47 | 48 | Toast.makeText(this, "Service started on port " + port, Toast.LENGTH_LONG).show(); 49 | return START_STICKY; 50 | } 51 | 52 | @Override 53 | public void onDestroy() { 54 | super.onDestroy(); 55 | if(ws!=null) 56 | ws.stop(); 57 | 58 | Toast.makeText(this, "Service stopped", Toast.LENGTH_LONG).show(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi-v11/inspectorw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ac-pm/Inspeckage/d8806c9e5f14d44c2e19a331e929d72d6faa4c54/app/src/main/res/drawable-hdpi-v11/inspectorw.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi-v9/inspectorw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ac-pm/Inspeckage/d8806c9e5f14d44c2e19a331e929d72d6faa4c54/app/src/main/res/drawable-hdpi-v9/inspectorw.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/inspectorw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ac-pm/Inspeckage/d8806c9e5f14d44c2e19a331e929d72d6faa4c54/app/src/main/res/drawable-hdpi/inspectorw.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi-v11/inspectorw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ac-pm/Inspeckage/d8806c9e5f14d44c2e19a331e929d72d6faa4c54/app/src/main/res/drawable-mdpi-v11/inspectorw.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi-v9/inspectorw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ac-pm/Inspeckage/d8806c9e5f14d44c2e19a331e929d72d6faa4c54/app/src/main/res/drawable-mdpi-v9/inspectorw.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/inspectorw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ac-pm/Inspeckage/d8806c9e5f14d44c2e19a331e929d72d6faa4c54/app/src/main/res/drawable-mdpi/inspectorw.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi-v11/inspectorw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ac-pm/Inspeckage/d8806c9e5f14d44c2e19a331e929d72d6faa4c54/app/src/main/res/drawable-xhdpi-v11/inspectorw.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi-v9/inspectorw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ac-pm/Inspeckage/d8806c9e5f14d44c2e19a331e929d72d6faa4c54/app/src/main/res/drawable-xhdpi-v9/inspectorw.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/inspectorw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ac-pm/Inspeckage/d8806c9e5f14d44c2e19a331e929d72d6faa4c54/app/src/main/res/drawable-xhdpi/inspectorw.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi-v11/inspectorw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ac-pm/Inspeckage/d8806c9e5f14d44c2e19a331e929d72d6faa4c54/app/src/main/res/drawable-xxhdpi-v11/inspectorw.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi-v9/inspectorw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ac-pm/Inspeckage/d8806c9e5f14d44c2e19a331e929d72d6faa4c54/app/src/main/res/drawable-xxhdpi-v9/inspectorw.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/inspectorw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ac-pm/Inspeckage/d8806c9e5f14d44c2e19a331e929d72d6faa4c54/app/src/main/res/drawable-xxhdpi/inspectorw.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/background_splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_shape.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_autorenew_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_check_box_outline_blank_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_exit_to_app_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_play_circle_fill_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_settings_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_vpn_key_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/inspeckage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ac-pm/Inspeckage/d8806c9e5f14d44c2e19a331e929d72d6faa4c54/app/src/main/res/drawable/inspeckage.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/side_nav_bar.xml: -------------------------------------------------------------------------------- 1 | 3 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/sponsored.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ac-pm/Inspeckage/d8806c9e5f14d44c2e19a331e929d72d6faa4c54/app/src/main/res/drawable/sponsored.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_inspeckage.xml: -------------------------------------------------------------------------------- 1 | 11 | 12 | 17 | 18 | 26 | 27 | 34 | 35 | 41 | 42 | 48 | 49 | 55 | 56 |