{"id":21390362,"url":"https://github.com/pakerwreah/inspector","last_synced_at":"2025-07-04T09:07:41.825Z","repository":{"id":48081750,"uuid":"248598033","full_name":"pakerwreah/Inspector","owner":"pakerwreah","description":"Tool to inspect SQLite databases and intercept network requests from mobile applications.","archived":false,"fork":false,"pushed_at":"2022-09-11T21:22:40.000Z","size":9652,"stargazers_count":21,"open_issues_count":2,"forks_count":3,"subscribers_count":6,"default_branch":"develop","last_synced_at":"2025-07-04T09:07:40.908Z","etag":null,"topics":["android","cpp","cross-platform","database","debug","debugging","flipper","http","inspect","ios","jni","mobile","ndk","okhttp","socket","sqlcipher","sqlite","stetho","websocket"],"latest_commit_sha":null,"homepage":"https://pakerwreah.github.io/InspectorWeb","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pakerwreah.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-19T20:25:36.000Z","updated_at":"2025-06-20T05:30:49.000Z","dependencies_parsed_at":"2022-08-12T18:10:50.252Z","dependency_job_id":null,"html_url":"https://github.com/pakerwreah/Inspector","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/pakerwreah/Inspector","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pakerwreah%2FInspector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pakerwreah%2FInspector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pakerwreah%2FInspector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pakerwreah%2FInspector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pakerwreah","download_url":"https://codeload.github.com/pakerwreah/Inspector/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pakerwreah%2FInspector/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263480892,"owners_count":23473165,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","cpp","cross-platform","database","debug","debugging","flipper","http","inspect","ios","jni","mobile","ndk","okhttp","socket","sqlcipher","sqlite","stetho","websocket"],"created_at":"2024-11-22T13:17:14.797Z","updated_at":"2025-07-04T09:07:41.665Z","avatar_url":"https://github.com/pakerwreah.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Inspector\n[![release](https://img.shields.io/github/v/release/pakerwreah/Inspector)](https://github.com/pakerwreah/Inspector/releases/latest)\n![c++](https://img.shields.io/badge/C++-17-blue.svg?style=flat\u0026logo=c%2B%2B)\n![android](https://img.shields.io/badge/Android-grey.svg?style=flat\u0026logo=android)\n![ios](https://img.shields.io/badge/iOS-grey.svg?style=flat\u0026logo=apple)\n[![codecov](https://img.shields.io/codecov/c/gh/pakerwreah/Inspector?label=codecov\u0026logo=codecov)](https://codecov.io/gh/pakerwreah/Inspector)\n[![ci](https://github.com/pakerwreah/Inspector/workflows/Unit%20Tests/badge.svg)](https://github.com/pakerwreah/Inspector/actions)\n[![ci](https://github.com/pakerwreah/Inspector/workflows/Android%20CI/badge.svg)](https://github.com/pakerwreah/Inspector/actions)\n[![ci](https://github.com/pakerwreah/Inspector/workflows/iOS%20CI/badge.svg)](https://github.com/pakerwreah/Inspector/actions)\n\n### Tool to inspect SQLite databases and intercept network requests from mobile applications.\n\nProject targeting Android, iOS and Web using C/C++, Java, Objective-C, Vue.js, WebSocket, SQLite and IndexedDB.\nThe data is shown in a web interface and uses WebSocket to communicate directly with the app via local network.\nTo keep network log history the web system uses the built-in IndexedDB from the browser.\n\n#### Frontend repository\nhttps://github.com/pakerwreah/InspectorWeb\n\n## Android\n[![Version](https://jitpack.io/v/pakerwreah/Inspector.svg)](https://jitpack.io/#pakerwreah/Inspector)\n\n\u003cdetails\u003e\n    \u003csummary\u003eSetup\u003c/summary\u003e\n\n#### Gradle\n```gradle\nrepositories {\n    maven { url \"https://jitpack.io\" }\n}\n```\n```gradle\ndependencies {\n    implementation \"com.github.pakerwreah:Inspector:\u003crelease-tag\u003e\"\n}\n```\n\n#### Proguard\n```\n-keep class br.newm.inspector.* { *; }\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003eUsage\u003c/summary\u003e\n\n#### Application\n```java\nimport br.newm.inspector.Inspector;\n\npublic class Application extends android.app.Application {\n    @Override\n    public void onCreate() {\n        super.onCreate();\n\n        Inspector.initializeWith(this);\n\n        // SQLCipher support\n        // database name, password, sqlcipher major version\n        Inspector.setCipherKey(\"database_cipher3.db\", \"123456\", 3);\n        Inspector.setCipherKey(\"database_cipher4.db\", \"123456\", 4);\n    }\n\n    // Optional: if you want to specify databases names to show\n    @Override\n    public String[] databaseList() {\n        return new String[]{\"database.db\", \"database_cipher3.db\", \"database_cipher4.db\"};\n    }\n}\n```\n\n#### Intercept network requests\n\u003csub\u003e:warning: if you use addNetworkInterceptor it won't intercept timeouts\u003c/sub\u003e\n```java\nimport br.newm.inspector.NetworkInterceptor;\n\nnew OkHttpClient.Builder().addInterceptor(new NetworkInterceptor());\n```\n\n#### Static plugins\nAccepts returning JSON, HTML or plain text\n```java\nInspector.addPlugin(\"prefs\", \"Shared Preferences\", new PluginAction() {\n    @Override\n    public String action() {\n        return new JSONObject(prefs.getAll()).toString();\n    }\n});\n```\n\n#### Live plugins\nAccepts complex HTML frontend with javascript support\n\u003cbr /\u003e\n\u003csub\u003eCheck ExplorerPlugin.java for a full example\u003c/sub\u003e\n```java\nInspector.addLivePlugin(\"explorer\", \"Explorer\", new PluginAction() {\n    @Override\n    public String action() {\n        // return plugin frontend\n    }\n});\n```\n\n#### Plugin API\nRoute with parameters to be used as a plugin or standalone api\n\u003cbr /\u003e\n\u003csub\u003eCheck ExplorerPlugin.java for a full example\u003c/sub\u003e\n```java\nInspector.addPluginAPI(\"GET\", \"filesystem/list\", new PluginAPIAction() {\n    @Override\n    public String action(Map\u003cString, String\u003e params) {\n        // return json array with list of files\n    }\n});\n\nInspector.addPluginAPI(\"GET\", \"filesystem/open\", new PluginAPIActionBinary() {\n    @Override\n    public byte[] action(Map\u003cString, String\u003e params) {\n        // return file contents\n    }\n});\n```\n\n#### Websockets\nSend messages to your live plugins\n```javascript\nnew WebSocket(`ws://${location.hostname}:${location.port}/plugins/ws/mykey`)\n```\n```java\nInspector.sendMessage(\"mykey\", \"Hello world!\");\n```\n#\n:warning: You should run this command to work with emulators\n```bash\n# same port number used to initialize the plugin\nadb forward tcp:30000 tcp:30000\n```\nOr configure its network as bridge and use the device's IP\n\u003c/details\u003e\n\n## iOS\n[![Version](https://img.shields.io/cocoapods/v/IOSInspector.svg)](https://cocoapods.org/pods/IOSInspector)\n\n\u003cdetails\u003e\n    \u003csummary\u003eSetup\u003c/summary\u003e\n\n#### CocoaPods\n```gradle\ntarget 'MyApp' do\n   pod \"IOSInspector\"\nend\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003eUsage\u003c/summary\u003e\n\n#### AppDelegate\n```swift\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate, IOSInspectorProtocol {\n\n    func applicationDidFinishLaunching(_ application: UIApplication) {\n\n        IOSInspector.initialize(withDelegate: self)\n\n        // SQLCipher support\n        IOSInspector.setCipherKey(\"database_cipher3.db\", password: \"123456\", version: 3)\n        IOSInspector.setCipherKey(\"database_cipher4.db\", password: \"123456\", version: 4)\n    }\n\n    // Required: specify databases paths\n    func databaseList() -\u003e [String] {\n        let documentsPathURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!\n\n        return [\"database.db\", \"database_cipher3.db\", \"database_cipher4.db\"].map {\n            documentsPathURL.appendingPathComponent($0).absoluteString\n        }\n    }\n}\n```\n\n#### Intercept network requests\n```swift\nlet uid = UUID().uuidString\n\nlet request = URLRequest(url: url)\n\n// send request to the frontend\nIOSInspector.sendRequest(withUID: uid, request: request)\n\nURLSession.shared.dataTask(with: request) { data, response, error in\n\n    if let data = data, let response = response as? HTTPURLResponse {\n        // send response to the frontend\n        IOSInspector.sendResponse(withUID: uid, response: response, body: data)\n    }\n\n}.resume()\n```\n\n#### Static plugins\nAccepts returning JSON, HTML or plain text\n```swift\nIOSInspector.addPlugin(\"prefs\", name: \"User Defaults\") {\n    let dict = UserDefaults.standard.dictionaryRepresentation()\n    if let data = try? JSONSerialization.data(withJSONObject: dict),\n        let json = String(data: data, encoding: .utf8) {\n        return json\n    }\n    return \"No data\"\n}\n```\n\n#### Live plugins\nAccepts complex HTML frontend with javascript support\n\u003cbr /\u003e\n\u003csub\u003eCheck ExplorerPlugin.swift for a full example\u003c/sub\u003e\n```swift\nIOSInspector.addLivePlugin(\"explorer\", name: \"Explorer\") {\n    // return plugin frontend\n}\n```\n\n#### Plugin API\nRoute with parameters to be used as a plugin or standalone api\n\u003cbr /\u003e\n\u003csub\u003eCheck ExplorerPlugin.swift for a full example\u003c/sub\u003e\n```swift\nIOSInspector.addPluginAPI(forMethod: \"GET\", path: \"filesystem/list\") { params -\u003e String in\n    // return json array with list of files\n}\n\nIOSInspector.addPluginAPI(forMethod: \"GET\", path: \"filesystem/open\") { params -\u003e Data? in\n    // return file contents\n}\n```\n\n#### Websockets\nSend messages to your live plugins\n```javascript\nnew WebSocket(`ws://${location.hostname}:${location.port}/plugins/ws/mykey`)\n```\n```swift\nIOSInspector.sendMessage(to: \"mykey\", message: \"Hello world!\")\n```\n\u003c/details\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpakerwreah%2Finspector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpakerwreah%2Finspector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpakerwreah%2Finspector/lists"}