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"