From 627889a4c6070354030ff1970ef510e779f7a07b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Tajchert?= Date: Wed, 29 Apr 2026 01:39:55 +0200 Subject: [PATCH] feat: add summary header to find-api-calls.sh Without an overview the script dumps thousands of file:line: matches across many sections, leaving the reader to figure out which framework even applies. A short summary at the top makes the rest of the output actionable. The summary counts hits per framework / DI / auth-signal category in a single grep pass over the source tree (8 separate greps would have roughly octupled the runtime on a large decompile). Output is a 3-line table: HTTP framework: Retrofit=N OkHttp=N Ktor=N Apollo=N Volley=N DI framework: Hilt/Dagger=N Koin=N Auth signals: Bearer=N HMAC/Sign=N A reader can immediately see which framework the app actually uses, whether auth is bearer-token or signed, and whether to spend time on a section or skip it. The summary is suppressed when a single section flag (--retrofit, --ktor, --paths, ...) is given, so the existing single-section workflows are unchanged. A reminder of the available section flags is printed below the counts so the agent does not have to consult --help. --- .../scripts/find-api-calls.sh | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) 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 c0243a0..22f5ed6 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 @@ -82,6 +82,58 @@ run_grep() { grep $GREP_OPTS -E "$pattern" "$SOURCE_DIR" 2>/dev/null || true } +# Print a one-screen summary FIRST so a reader knows what to expect from +# the long output that follows. Skipped when a single section flag was +# requested (the user wants raw matches, not an overview). One pass over +# the tree, counts bucketed by tag — running 8 separate greps was too slow. +if [[ "$SEARCH_ALL" == true ]]; then + section "Summary (counted in a single pass)" + declare -A H=( + [retrofit]=0 [okhttp]=0 [ktor]=0 [apollo]=0 [volley]=0 + [hilt]=0 [koin]=0 [bearer]=0 [hmac]=0 + ) + while IFS= read -r line; do + case "$line" in + *"@GET("*|*"@POST("*|*"@PUT("*|*"@DELETE("*|*"@PATCH("*|*"@HTTP("*) H[retrofit]=$((H[retrofit]+1));; + esac + case "$line" in + *"Request.Builder"*|*"HttpUrl"*|*".newCall("*) H[okhttp]=$((H[okhttp]+1));; + esac + case "$line" in + *"BearerTokens"*|*"defaultRequest {"*|*"client.get("*|*"client.post("*|*"httpClient.get("*|*"httpClient.post("*|*"HttpClient.get("*) H[ktor]=$((H[ktor]+1));; + esac + case "$line" in + *"ApolloClient"*|*".serverUrl("*) H[apollo]=$((H[apollo]+1));; + esac + case "$line" in + *"StringRequest"*|*"JsonObjectRequest"*|*"RequestQueue"*) H[volley]=$((H[volley]+1));; + esac + case "$line" in + *"@HiltAndroidApp"*|*"@AndroidEntryPoint"*|*"@HiltViewModel"*|*"@Provides"*|*"@Binds"*) H[hilt]=$((H[hilt]+1));; + esac + case "$line" in + *"org.koin."*|*"module {"*|*"single<"*|*"factory<"*|*"singleOf("*|*"factoryOf("*) H[koin]=$((H[koin]+1));; + esac + case "$line" in + *'"Bearer '*|*'"bearer '*|*"BearerTokens"*) H[bearer]=$((H[bearer]+1));; + esac + case "$line" in + *"HmacSHA"*|*'Mac.getInstance("Hmac'*) H[hmac]=$((H[hmac]+1));; + esac + done < <(grep -rEh --include='*.java' --include='*.kt' \ + '@(GET|POST|PUT|DELETE|PATCH|HTTP)\(|Request\.Builder|HttpUrl|\.newCall\(|BearerTokens|defaultRequest \{|client\.(get|post)\(|httpClient\.(get|post)\(|ApolloClient|\.serverUrl\(|StringRequest|JsonObjectRequest|RequestQueue|@HiltAndroidApp|@AndroidEntryPoint|@HiltViewModel|@Provides|@Binds|org\.koin\.|module \{|single<|factory<|"[Bb]earer |HmacSHA|Mac\.getInstance' \ + "$SOURCE_DIR" 2>/dev/null || true) + printf ' HTTP framework: Retrofit=%-5s OkHttp=%-5s Ktor=%-5s Apollo=%-5s Volley=%-5s\n' \ + "${H[retrofit]}" "${H[okhttp]}" "${H[ktor]}" "${H[apollo]}" "${H[volley]}" + printf ' DI framework: Hilt/Dagger=%-5s Koin=%-5s\n' \ + "${H[hilt]}" "${H[koin]}" + printf ' Auth signals: Bearer=%-5s HMAC/Sign=%-5s\n' \ + "${H[bearer]}" "${H[hmac]}" + echo + echo " Run with one of --retrofit / --okhttp / --ktor / --apollo / --volley /" + echo " --paths / --urls / --auth to inspect a single section." +fi + # --- Retrofit --- if [[ "$SEARCH_ALL" == true || "$SEARCH_RETROFIT" == true ]]; then section "Retrofit Annotations"