skills/covagent-overcoming-30-curse/SKILL.md
Boost Android app test coverage beyond the 30% activity ceiling using agentic static analysis of Smali code, component transition graphs, activation condition inference, and Frida dynamic instrumentation script generation. Use when: 'increase Android app test coverage', 'generate Frida scripts for unreachable activities', 'analyze APK activation conditions', 'break through coverage barriers in mobile testing', 'instrument Android app for GUI fuzzing', 'find unreachable activities in Android app'.
npx skillsauth add ndpvt-web/arxiv-claude-skills covagent-overcoming-30-curseInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill enables Claude to act as a two-phase agentic system for Android app test coverage improvement. Following the CovAgent framework, Claude analyzes decompiled APK code (Smali bytecode) and component transition graphs to identify why GUI fuzzers cannot reach certain activities, then generates Frida dynamic instrumentation scripts that satisfy those activation conditions at runtime -- without modifying the app's source code. This approach consistently doubles or triples activity coverage compared to state-of-the-art fuzzers alone.
The 30% Problem. Standard GUI fuzzers explore Android apps by generating random or guided UI events. They consistently plateau at ~30% activity coverage because many activities are gated by activation conditions -- programmatic checks in onCreate/onStart/onResume that terminate the activity if prerequisites are unmet. These include: Intent extras with specific values, SharedPreferences flags set by prior workflows, external resource checks (SD card, network, GPS), authentication tokens, and server-side state. No amount of random clicking can satisfy a if (!hasCompletedPayment) finish() guard.
Two-Agent Architecture. CovAgent uses an Analyzer Agent and an Instrumenter Agent in sequence. The Analyzer performs bidirectional static analysis on decompiled Smali code: forward analysis inspects lifecycle methods (onCreate, onResume) to find guard conditions and exception-raising sub-procedures; backward analysis traces startActivity/startActivityForResult call sites to understand how Intents are constructed and what extras they carry. The agent reasons via chain-of-thought about what conditions must hold for the activity to survive initialization. The Instrumenter Agent then takes these inferred conditions and generates Frida JavaScript scripts that hook target methods in memory -- overriding return values, injecting Intent extras, or faking device state -- so the activity launches successfully without any source code changes.
Fuzzer-Agnostic Integration. The generated Frida scripts are injected via a pop-up widget overlay: for each unreachable target activity, a button is added to its nearest reachable source activity (determined from the component transition graph). The GUI fuzzer runs concurrently and can tap these buttons to trigger instrumented transitions. This preserves realistic navigation paths while making previously impossible transitions accessible.
Decompile the APK to Smali. Use apktool d target.apk -o output_dir to obtain Smali bytecode and AndroidManifest.xml. Parse the manifest to extract the full list of declared activities, their intent filters, and exported status.
Build the Component Transition Graph (CTG). Run ICCBot or a similar ICC analysis tool to extract caller-callee relationships between components. Alternatively, grep Smali code for startActivity, startActivityForResult, and startService invocations to build a lightweight CTG mapping source activities to target activities and the methods that trigger transitions.
Identify unreachable activities. Run the baseline fuzzer for a fixed duration and collect its activity coverage log. Diff against the manifest's declared activities to produce the set of unreachable activities. Prioritize activities with no incoming edges in the CTG (isolated nodes) and those with complex activation conditions.
Forward-analyze lifecycle methods for guard conditions. For each unreachable activity, read its onCreate, onStart, and onResume Smali methods. Identify conditional branches (if-eqz, if-nez, if-eq) that lead to finish(), System.exit(), or exception throws. Trace the checked variables backward to their source: Intent extras (getStringExtra, getIntExtra), SharedPreferences reads, permission checks, hardware state queries, or network calls.
Backward-analyze Intent construction at call sites. For each unreachable activity, find all startActivity calls targeting it (from the CTG). Read the calling method's Smali to determine what extras are putExtra'd into the Intent, what conditions gate the startActivity call itself, and what preceding user flows populate required state.
Infer activation conditions in natural language. Synthesize findings into a structured description: (a) what the activity expects in its Intent bundle, (b) what SharedPreferences or global state must exist, (c) what external resources or device features are checked, (d) what authentication or authorization is required. Classify each condition by type: data dependency, external resource, device state, authentication, or usage pattern.
Generate a Frida instrumentation script. Write a Frida JavaScript snippet that hooks the identified guard methods and overrides their behavior. The script should: hook the class containing the guard, replace the return value of the check method (e.g., force isSDCardConnected() to return true), inject required Intent extras via Intent.putExtra hooks, and then trigger navigation to the target activity via startActivity. Wrap everything in Java.perform() with proper error handling.
Validate the script with a feedback loop (up to 5 iterations). Inject the script using frida -U -f <package> -l script.js. Check three failure modes: (a) Frida runtime errors (class/method not found -- fix the hook target), (b) app crashes with stack traces (unhandled null or state issue -- add more hooks), (c) silent failure to transition (wrong condition identified -- revisit analysis). Refine the script based on logcat and Frida console output.
Build the widget injection map. Using the CTG, assign each unreachable target to its nearest reachable source activity. If no reachable source exists, assign it to the app's main/launcher activity. Generate a Frida script that injects a floating button overlay into each source activity; tapping the button executes the target's instrumentation script.
Run the augmented fuzzing session. Launch the GUI fuzzer concurrently with Frida instrumentation active. The fuzzer explores normally but can now also tap injected buttons to reach previously unreachable activities. Collect coverage metrics (activity, class, method, line) and compare against the baseline.
Example 1: Bypassing an SD Card Check
User: "My Fastbot run only covers 18% of activities in this file manager app. The FileTransferActivity never gets reached. Here's the decompiled Smali for its onCreate."
Approach:
onCreate Smali. Find the guard: invoke-virtual {v0}, Lcom/app/util/DeviceUtils;->isSDCardMounted()Z followed by if-eqz v1, :cond_finish leading to invoke-virtual {p0}, Landroid/app/Activity;->finish()V.SettingsActivity.onItemClick calls startActivity with Intent("com.app.FILE_TRANSFER") and putExtra("source_path", selectedPath).source_path string extra.Java.perform(function() {
var DeviceUtils = Java.use("com.app.util.DeviceUtils");
DeviceUtils.isSDCardMounted.implementation = function() {
console.log("[*] Hooked isSDCardMounted -> true");
return true;
};
var Activity = Java.use("android.app.Activity");
var Intent = Java.use("android.content.Intent");
var currentApp = Java.use("android.app.ActivityThread")
.currentApplication().getApplicationContext();
var intent = Intent.$new(currentApp,
Java.use("com.app.FileTransferActivity").class);
intent.putExtra("source_path", "/sdcard/Documents");
intent.addFlags(0x10000000); // FLAG_ACTIVITY_NEW_TASK
currentApp.startActivity(intent);
});
FileTransferActivity opens without crash. Coverage now includes 3 additional activities reachable from FileTransferActivity.Example 2: Bypassing Authentication Gate for Order History
User: "The OrderHistoryActivity in this food delivery app is unreachable during testing. How can I instrument past the login check?"
Approach:
onCreate: finds invoke-virtual {v0}, Lcom/app/auth/SessionManager;->isLoggedIn()Z with if-eqz branching to finish(). Also checks getIntent().getStringExtra("user_id") with null check.HomeActivity.onOrderHistoryClick constructs Intent with putExtra("user_id", currentUser.getId()).SessionManager.isLoggedIn() must return true, (b) Intent must contain non-null user_id extra.Java.perform(function() {
// Bypass authentication check
var SessionManager = Java.use("com.app.auth.SessionManager");
SessionManager.isLoggedIn.implementation = function() {
console.log("[*] Hooked isLoggedIn -> true");
return true;
};
// Also hook getToken to prevent NPE downstream
SessionManager.getToken.implementation = function() {
return "instrumented_test_token_001";
};
// Launch with required extras
var ctx = Java.use("android.app.ActivityThread")
.currentApplication().getApplicationContext();
var Intent = Java.use("android.content.Intent");
var intent = Intent.$new(ctx,
Java.use("com.app.OrderHistoryActivity").class);
intent.putExtra("user_id", "test_user_42");
intent.addFlags(0x10000000);
ctx.startActivity(intent);
});
Example 3: Analyzing Activation Conditions from Smali Without Script Generation
User: "Can you analyze this Smali code and tell me why PromoActivity is unreachable?"
Approach:
onCreate method. Identify three guards:
SharedPreferences.getBoolean("has_first_purchase", false) -- must be truegetIntent().getLongExtra("promo_expiry", 0) compared against System.currentTimeMillis() -- promo must not be expiredinvoke-static {}, Lcom/app/FeatureFlags;->isPromoEnabled()Z -- feature flag must be onActivation Conditions for PromoActivity:
1. [Data Dependency] SharedPreferences key "has_first_purchase" must be true
-> Set during CheckoutActivity.onPaymentSuccess()
2. [Data Dependency] Intent extra "promo_expiry" (long) must be > current time
-> Constructed in HomeActivity.showPromoCard() with server-provided timestamp
3. [Feature Flag] FeatureFlags.isPromoEnabled() must return true
-> Reads from remote config; defaults to false
SharedPreferences.getBoolean for the specific key, set promo_expiry to a future timestamp, and hook isPromoEnabled to return true.try/catch blocks in every Frida script and log errors to console. Silent failures are the hardest to debug.onCreate alone. Analyze the entire method before scripting.onCreate alone.| Failure Mode | Symptom | Resolution |
|---|---|---|
| Class not found in Frida | Error: java.lang.ClassNotFoundException | The class may be obfuscated or loaded dynamically. Check the actual class name in the running process with Java.enumerateLoadedClasses(). |
| Method signature mismatch | Error: method not found | Smali uses JNI-style signatures. Verify parameter types match exactly: overload('java.lang.String', 'int'). |
| App crashes after hook | NullPointerException in logcat | The hooked method's caller may depend on side effects. Hook additional downstream methods that expect real return objects. |
| Activity launches but immediately finishes | No error, activity disappears | There are additional guard conditions in onStart or onResume not caught in onCreate analysis. Analyze all lifecycle methods. |
| Frida detaches from process | Process terminated | The app may have anti-instrumentation (root detection, Frida detection). Hook common detection methods like detectFrida() or isRooted() first. |
.so libraries, which is a different instrumentation paradigm.Paper: Wei Minn et al., "CovAgent: Overcoming the 30% Curse of Mobile Application Coverage with Agentic AI and Dynamic Instrumentation" (2026). arXiv:2601.21253v1
What to look for: Section 3 for the full two-agent architecture, Algorithm 1 for the widget injection mapping strategy, Section 4.2 (RQ1) for the coverage improvement breakdown by fuzzer, and Section 4.4 (RQ3) for the activation condition taxonomy with per-category success rates showing where instrumentation works best (data dependencies, feature flags) and where it struggles (external server state).
development
Audit LLM-based automatic short answer grading (ASAG) systems for adversarial vulnerabilities using token-level and prompt-level attack strategies from the GradingAttack framework. Triggers: 'test grading robustness', 'adversarial attack on grading', 'audit LLM grader', 'red-team answer grading', 'ASAG vulnerability assessment', 'grading fairness attack'
development
Build structured information-seeking agents that decompose complex queries into multi-turn search-and-browse workflows, aggregate results from multiple web sources, and return answers in typed structured formats (items, sets, lists, tables). Applies the GISA benchmark's ReAct-based agent architecture and evaluation methodology. Trigger phrases: "build an information-seeking agent", "search agent pipeline", "multi-turn web research agent", "structured web search workflow", "aggregate information from multiple sources", "web research with structured output"
data-ai
Optimize LLM prompts using GFlowPO's iterative generate-evaluate-refine loop with diversity-preserving exploration and dynamic memory. Use when: 'optimize this prompt', 'find a better prompt for this task', 'prompt engineering with examples', 'auto-tune my system prompt', 'improve prompt accuracy', 'generate prompt variations'.
development
Constrain LLM generation with executable Pydantic schemas and multi-agent pipelines to produce structurally valid, domain-rich artifacts. Uses ontology-as-grammar to eliminate hallucinated structures while preserving creative output. Trigger phrases: "generate a valid game design", "schema-constrained generation", "build a multi-agent pipeline with Pydantic validation", "ontology-driven content generation", "structured creative generation with DSPy", "generate artifacts that pass domain validation".