AI Skill Report Card
Patching Smali
Reads, patches, validates (round-trip), and packages .smali files with 100% deterministic, transparent behavior. Every patch is backed up, documented with before/after snippets, and rejected if validation produces any error or warning.
Quick Start14 / 15
Input:
smali_file:com/example/app/MainActivity.smalipatch_instruction: "Force methodisPremium()Zto always return true"
Process:
- Read file, locate
.method public isPremium()Z - Analyze body, registers,
.locals - Replace body with:
SMALI
.method public isPremium()Z .locals 1 const/4 v0, 0x1 return v0 .end method - Round-trip validate (assemble → disassemble → re-assemble, 0 errors)
- Output:
patched_output.zip(contains patched.smali) +patch_report.txt(before/after snippet, reasoning, validation result)
Recommendation▾
Add an example showing a failed validation and the revision loop in action, not just successful patches
Workflow15 / 15
Progress:
- [ ] Step 1: Parse patch_instruction → map to smali syntax; flag ambiguity
- [ ] Step 2: Read full .smali file; analyze class/fields/methods/registers/.locals/control flow
- [ ] Step 3: Identify exact patch point (method signature, label, or line)
- [ ] Step 4: Backup original file
- [ ] Step 5: Apply patch (update .locals if new registers added, never reuse active registers, no dead code after return)
- [ ] Step 6: Round-trip validate (assemble → disassemble → re-assemble)
- [ ] Step 7: If validation fails, revise and repeat Step 6
- [ ] Step 8: Package .smali into ZIP + generate patch_report.txt
- [ ] Step 9: Deliver only if validation passed with 0 errors/warnings
Step details
1. Parse instruction
- Map natural-language instruction to concrete smali operations (e.g., "always return true" →
const/4 vX, 0x1+return vX). - If instruction is ambiguous (e.g., "make it work better"), do NOT guess silently — pick the most literal, minimal interpretation and explicitly log the assumption in the report.
2. Read & analyze
- Parse
.class,.super,.field,.methodblocks. - Track register usage:
.locals N, parameter registers (p0,p1...), and everyvregister touched in the target method. - Trace control flow: labels (
:cond_0), branches (if-*,goto),try/catchblocks,return/return-void/return-object.
3. Identify patch point
- Match exact method signature (name + descriptor), not just name — avoid overload collisions.
- If a label or line number is given, locate it precisely; never approximate.
4. Backup
- Copy original file untouched, referenced in the report (e.g.,
original_backup/MainActivity.smali).
5. Apply patch
- If new local registers are introduced, recalculate and update
.localscount. - Never reuse a register that is still live (holds a value used later) — allocate a new one instead.
- Ensure no unreachable instructions exist after
return/return-void/return-object/throw. - Preserve original indentation style (4 spaces, standard smali convention) and blank-line structure around the modified block.
- Modify ONLY the method/class explicitly named in the instruction — nothing else in the file changes.
6. Round-trip validation
- Assemble the patched smali → produce dex/class equivalent.
- Disassemble that result back to smali.
- Re-assemble again.
- Compare for structural consistency; MUST produce 0 errors and 0 warnings.
- If any error/warning appears, revise the patch and repeat — do not proceed to packaging.
7. Packaging
- ZIP contains only the patched
.smalifile(s), preserving original directory path structure. patch_report.txtincludes: instruction interpretation, assumptions (if any), patch location, before/after snippet, register changes, validation result, reasoning.
8. Deliver
- Only deliver ZIP + report together, and only if validation succeeded. Never send one without the other.
Recommendation▾
Include a brief note on tooling assumptions (e.g., which smali/baksmali or apktool commands are actually invoked for round-trip validation)
Examples17 / 20
Example 1: Simple boolean patch
Input:
smali_file:MainActivity.smalipatch_instruction: "MakeisPremium()Zalways return true"
Output (patch_report.txt excerpt):
Instruction interpretation: Replace return value of boolean method with constant true.
Assumptions: None — instruction unambiguous.
Patch location: MainActivity.smali, method isPremium()Z (line 42-46)
BEFORE:
.method public isPremium()Z
.locals 1
iget-boolean v0, p0, Lcom/example/app/MainActivity;->premiumFlag:Z
return v0
.end method
AFTER:
.method public isPremium()Z
.locals 1
const/4 v0, 0x1
return v0
.end method
Register changes: v0 reused safely (was dead after original return; no active value retained).
Validation: Round-trip assemble/disassemble/re-assemble — 0 errors, 0 warnings. PASSED.
Example 2: Ambiguous instruction
Input: patch_instruction: "fix the login check"
Output (patch_report.txt excerpt):
Instruction interpretation: Ambiguous — "fix" not defined.
Assumption logged: Interpreted as forcing method checkLogin()Z to always return true (most common patch pattern for this instruction type). If this is incorrect, please clarify desired condition logic.
[... snippet, validation as above ...]
Example 3: Register overflow requiring .locals update
Input: patch instruction requires adding a new temp register in a method with .locals 2 (v0, v1 both active).
Output:
BEFORE: .locals 2
AFTER: .locals 3
Reasoning: v0 and v1 are live throughout method body; new comparison value stored in v2 to avoid clobbering active registers.
Recommendation▾
Consider a short troubleshooting section for common assembler error messages and how to interpret them
Best Practices
- Always back up the original file before any modification.
- Always run full round-trip validation before packaging — never trust a single assemble pass.
- Always include before/after snippets in the report, not just a diff summary.
- Always state assumptions explicitly when instructions are ambiguous — never silently guess.
- Keep indentation and formatting consistent with the original file's style.
- Touch only what the instruction specifies — no incidental "cleanup" edits.
Common Pitfalls
- Do not reuse a register that still holds a live value — this causes silent runtime corruption, not a validation error.
- Do not forget to update
.localswhen register count increases — causes verifier rejection at runtime even if assembly "succeeds." - Do not leave instructions after
return/throw— unreachable code triggers verifier warnings. - Do not package or deliver results if round-trip validation shows ANY warning — treat warnings as blocking, not advisory.
- Do not patch other methods/classes "while you're in there" — strictly scope changes to the instruction.
- Do not deliver a ZIP without the accompanying patch_report.txt, or vice versa.
- Do not guess silently on ambiguous instructions — always log the assumption.