diff --git a/plugins/android-reverse-engineering/skills/android-reverse-engineering/references/call-flow-analysis.md b/plugins/android-reverse-engineering/skills/android-reverse-engineering/references/call-flow-analysis.md index 0e26df1..fa8be66 100644 --- a/plugins/android-reverse-engineering/skills/android-reverse-engineering/references/call-flow-analysis.md +++ b/plugins/android-reverse-engineering/skills/android-reverse-engineering/references/call-flow-analysis.md @@ -84,9 +84,9 @@ Look for: - Firebase/analytics initialization - Base URL configuration -## 5. Dependency Injection (Dagger / Hilt) +## 5. Dependency Injection -Modern Android apps use DI. Trace bindings to find implementations: +### Dagger / Hilt ```bash # Hilt modules @@ -102,10 +102,43 @@ grep -rn '@Component\|@Subcomponent' sources/ grep -rn '@Inject' sources/ ``` -To trace a call flow through DI: -1. Find where an interface is used (e.g., `ApiService` injected into a repository) -2. Find the `@Provides` or `@Binds` method that creates the implementation -3. Follow the implementation to the actual HTTP call +### Koin + +Koin is the dominant DI framework in Kotlin Multiplatform and a large +share of Kotlin-only Android apps. It uses a runtime DSL rather than +compile-time generated factories, so the search patterns are different: + +```bash +# Confirm Koin is actually wired up +grep -rn 'org\.koin\.' sources/ + +# DI module declarations +grep -rn 'fun [A-Za-z]\+Module\|module\s*{\|module(' sources/ + +# Bindings inside a module DSL +grep -rn 'single\s*[<{(]\|factory\s*[<{(]\|viewModel\s*[<{(]\|scoped\s*[<{(]\|singleOf\|factoryOf' sources/ + +# Resolution call-sites (where a binding is consumed) +grep -rn '\bget\s*<\|\binject\s*<\|by\s\+inject\b\|by\s\+viewModel\b\|getKoin' sources/ +``` + +After R8, every binding lambda becomes an anonymous +`Function2` impl. To find the binding for an +interface `Foo`, look for files that contain both a Koin import / module +DSL marker and a reference to `Foo`: + +```bash +grep -rln 'org\.koin\.core\.module' sources/ | xargs grep -l 'Foo' +``` + +### Trace through DI + +1. Find where an interface is used (e.g. `ApiService` injected into a + repository). +2. Find the `@Provides` / `@Binds` method (Hilt) **or** the + `single { ... }` / `factory { ... }` block (Koin) that creates the + implementation. +3. Follow the implementation to the actual HTTP call. ## 6. Find Constants and Configuration diff --git a/plugins/android-reverse-engineering/skills/android-reverse-engineering/scripts/find-api-calls.sh b/plugins/android-reverse-engineering/skills/android-reverse-engineering/scripts/find-api-calls.sh index d557d15..c0243a0 100755 --- a/plugins/android-reverse-engineering/skills/android-reverse-engineering/scripts/find-api-calls.sh +++ b/plugins/android-reverse-engineering/skills/android-reverse-engineering/scripts/find-api-calls.sh @@ -226,9 +226,27 @@ fi # --- Auth patterns --- if [[ "$SEARCH_ALL" == true || "$SEARCH_AUTH" == true ]]; then section "Authentication & API Keys" - run_grep -i '(api[_-]?key|auth[_-]?token|bearer|authorization|x-api-key|client[_-]?secret|access[_-]?token)' + run_grep -i '(api[_-]?key|auth[_-]?token|bearer|authorization|x-api-key|client[_-]?secret|access[_-]?token|refresh[_-]?token)' + + # Request-signing schemes: a hardcoded HMAC / RSA secret in an APK is a + # security finding worth surfacing prominently. These patterns catch the + # common shapes of homegrown / SDK-issued request signers. + section "Request Signing (HMAC / signature schemes)" + run_grep '(HmacSHA(1|256|512)|Mac\.getInstance\("Hmac|SecretKeySpec\(|Signature\.getInstance\()' + run_grep -i '(x-signature|x-client-authorization|x-amz-signature|x-hmac|aws4-hmac|signRequest|signatureFor|computeSignature|signaturev[0-9])' + + # Hardcoded high-entropy strings adjacent to "secret"/"key" assignments + # are the canonical leaked-credential pattern. + section "Possible Hardcoded Secrets / Keys" + run_grep -i '(app[_-]?secret|client[_-]?secret|signing[_-]?key|hmac[_-]?secret|consumer[_-]?secret|private[_-]?key)' + section "Base URLs and Constants" run_grep -i '(BASE_URL|API_URL|SERVER_URL|ENDPOINT|API_BASE|HOST_NAME)' + + # Ktor BearerTokens / refresh DSL — common on Kotlin apps and lives on + # Ktor's public API, so it survives R8 unchanged. + section "Ktor Auth (Bearer + Refresh)" + run_grep '(BearerTokens|loadTokens\s*\{|refreshTokens\s*\{|\bbearer\s*\{)' fi echo