{"id":28431754,"url":"https://github.com/block/stoic","last_synced_at":"2025-08-14T21:06:50.361Z","repository":{"id":243118201,"uuid":"808742641","full_name":"block/stoic","owner":"block","description":"Run code within any debuggable Android process, without modifying its APK","archived":false,"fork":false,"pushed_at":"2025-07-28T09:27:55.000Z","size":1383,"stargazers_count":113,"open_issues_count":11,"forks_count":10,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-28T11:31:17.059Z","etag":null,"topics":["android","debug","jvmti"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/block.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-05-31T18:06:42.000Z","updated_at":"2025-07-28T09:28:01.000Z","dependencies_parsed_at":"2024-07-17T03:12:45.487Z","dependency_job_id":"86f81ac5-66f0-420a-b695-5743e5ebadfd","html_url":"https://github.com/block/stoic","commit_stats":null,"previous_names":["square/stoic","block/stoic"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/block/stoic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/block%2Fstoic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/block%2Fstoic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/block%2Fstoic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/block%2Fstoic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/block","download_url":"https://codeload.github.com/block/stoic/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/block%2Fstoic/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270482320,"owners_count":24591340,"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","status":"online","status_checked_at":"2025-08-14T02:00:10.309Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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","debug","jvmti"],"created_at":"2025-06-05T16:08:17.514Z","updated_at":"2025-08-14T21:06:50.355Z","avatar_url":"https://github.com/block.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Stoic \u003cimg src=\"./assets/logo.svg\" alt=\"App logo\" width=\"25\"\u003e\n\n\u003e *\"Σκόπει εἰς σεαυτόν. Ἐντὸς σοῦ πηγὴ ἀγαθοῦ ἐστιν, ἡ ἀεὶ ἐκβρύειν ἑτοίμη, ἐὰν ἀεὶ σκάπτῃς.\"*\n\u003e\n\u003e \"Look within. Within is the fountain of good, and it will ever bubble up, if you will ever dig.\"\n\n*- Marcus Aurelius (121-180 AD), Roman Emperor and Stoic philosopher*\n\n\u003e *\"Ignis aurum probat, miseria fortes.\"*\n\u003e\n\u003e \"Fire tests gold and adversity tests the brave.\"\n\n*-Seneca the Younger (c. 4 BC - AD 65), Roman statesman and Stoic philosopher*\n\n\n\n\n## Introduction\n\nStoic lets you look within your Android processes, giving you the courage to\ntake on difficult bugs.\n\nStoic is a tool for\n1. running code inside another process - without any modifications to its APK,\n2. exposing extra capabilities to code, normally only available to a debugger, and\n3. blurring the lines between code and debugger\n\nYou can write plugins that\n1. provide command-line access to APIs normally only available inside the process\n2. leverage debugger functionality (e.g. use breakpoints to hook arbitrary methods)\n3. examine the internal state of a process without restarting the process\n\nStoic is fast. The first time you run a Stoic plugin in a process it will take 2-3\nseconds to attach. Thereafter, Stoic plugins typically run in less than a second.\n\n\n## Getting started\n\n1. Install with [Homebrew](https://brew.sh/): `brew install block/tap/stoic`\n2. Run your first Stoic plugin: `stoic helloworld`\n3. When you don't specify a package, Stoic injects itself into `com.squareup.stoic.demoapp.withoutsdk`\n   by default - a simple app bundled with Stoic. Run `stoic --pkg \u003cyour-app\u003e helloworld` to inject into your\n   own app instead.\n4. Create a new plugin: `stoic plugin --new scratch`\n5. Run your plugin with: `stoic scratch`\n6. Open up `~/.config/stoic/plugin/scratch` with Android Studio to modify this plugin and explore what Stoic can do.\n\nStoic works on any API 26+ Android device / emulator, with any debuggable app (that I've tested so far).\n\n\n## Bundled Plugins\n\nStoic bundles a few plugins:\n1. [appexitinfo](https://github.com/square/stoic/blob/main/docs/APPEXITINFO.md) - command-line access to the ApplicationExitInfo API\n2. breakpoint - print when methods get called, optionally with arguments/return-value/stack-trace\n3. crasher - see how your app handles various types of crashes\n\n\n## Authoring Plugins\n\nEach plugin is a normal Java `main` function. You access debugger functionality via the `com.squareup.stoic.jvmti` package. e.g.\n```\n// get callbacks whenever any method of interest is called\nval method = jvmti.virtualMachine.methodBySig(\"android/view/InputEventReceiver.dispatchInputEvent(ILandroid/view/InputEvent;)V\")\njvmti.breakpoint(method.startLocation) { frame -\u003e\n  println(\"dispatchInputEvent called\")\n}\n\n// iterate over each bitmap in the heap\nfor (bitmap in jvmti.instances(Bitmap::class.java)) {\n  println(\"$bitmap: size=${bitmap.allocationByteCount}\")\n}\n```\n\n## Architecture\n\nThe primary technologies powering Stoic are\n[JVMTI](https://en.wikipedia.org/wiki/Java_Virtual_Machine_Tools_Interface),\n[Unix Domain Sockets](https://en.wikipedia.org/wiki/Unix_domain_socket), and\n[run-as](https://cs.android.com/android/platform/superproject/main/+/main:system/core/run-as/run-as.cpp).\nStoic is written in Kotlin and uses\n[Clikt](https://ajalt.github.io/clikt/) for command-line parsing and\n[GraalVM](https://www.graalvm.org/) for snappy start-ups.\n\nThe first time you run Stoic on a process it will attach a jvmti agent which\nwill start a server inside the process. We connect to this server through a\nunix domain socket, and multiplex stdin/stdout/stderr over this connection. See\nhttps://github.com/square/stoic/blob/main/docs/ARCHITECTURE.md for more details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblock%2Fstoic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblock%2Fstoic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblock%2Fstoic/lists"}