AI Skill Report Card

Patching Smali Files

A88·Sep 3, 2026·Source: Web
14 / 15

Given a .smali method and a patch instruction:

  1. Read the full file, locate the target method, note .locals N and register usage.
  2. Apply the minimal correct edit (correct smali syntax, correct register handling).
  3. Bump .locals if a new register is introduced.
  4. Round-trip validate: assemble → disassemble → reassemble, diff to confirm stability.
  5. If valid: backup original, write patched file, generate report, zip everything.
  6. If invalid: stop, do not zip, return only the error report.

No shortcuts. No silent guesses without documenting them.

Recommendation
Add an example showing multi-file patching to demonstrate the combined report/single ZIP behavior mentioned in the workflow.
15 / 15
Progress:
- [ ] 1. Ingest & parse: read file(s) line by line, index classes/fields/methods
- [ ] 2. Locate target: find exact method(s) matching user instruction
- [ ] 3. Analyze: signature, .locals count, register map (p0..pN, v0..vN), control flow, return points
- [ ] 4. Plan patch: decide exact instructions to insert/modify/remove
- [ ] 5. Register safety check: any new register needed? -> increment .locals; never reuse a live register
- [ ] 6. Apply edit: rewrite only the targeted lines, preserve everything else byte-for-byte
- [ ] 7. Dead-code check: ensure no instructions placed after return/throw in same block
- [ ] 8. Round-trip validate: smali assemble -> baksmali disassemble -> smali reassemble
- [ ] 9. Diff check: compare before/after, confirm only intended changes exist
- [ ] 10. If validation fails: fix or abort with error report (no partial output)
- [ ] 11. If validation passes: backup original (note path in report), save patched file
- [ ] 12. Generate transparent report (per file, per method)
- [ ] 13. Package modified files + report into ZIP
- [ ] 14. Deliver ZIP + report (or error-only report if failed)

Step Details

Step 1-3 (Read & Analyze):

  • Parse .class, .super, .field, .method blocks.
  • For each target method, record: full signature, .locals value, parameter registers (p0=this if non-static), local registers in use at each point, all return*/goto/if-*/invoke-* lines and branch labels.

Step 4-5 (Plan & Register Safety):

  • Never reuse a register that is live (holds a value still needed later in the method).
  • If injecting new logic (e.g., logging, a new invoke), allocate a fresh register: new_v = old .locals count, then .locals (old+1).
  • If parameter registers exist, remember Dalvik convention: locals v0..v(N-1) come before parameter registers p0..pM in the raw register file — inserting a new local shifts nothing if you only increase .locals, but double-check any explicit high-register (v15, v16) math.
  • Document exact register(s) chosen and why in the report.

Step 6-7 (Apply & Dead-code Check):

  • Only touch lines within the exact method block instructed. Never modify sibling methods or other classes.
  • If instruction is "add before return", insert immediately before the return* opcode, never after.
  • Reject/flag any accidental placement after return, return-void, return-object, or throw within the same basic block.

Step 8-9 (Validate):

  • Run: smali assemble patched.smali -o patched.dex (or equivalent), then baksmali disassemble patched.dex -o out/, then reassemble again.
  • Compare final re-disassembled smali against the intended patched version — must match with zero unexpected diffs, zero warnings, zero errors.
  • If tooling unavailable in environment, perform static syntax/semantic self-check (opcode validity, register range validity, label resolution, .locals vs max register used) and clearly state in the report that live round-trip tooling was not executed.

Step 10-11 (Pass/Fail Gate):

  • Fail → produce error report only: what failed, exact error/warning text, which line, why. No ZIP delivered.
  • Pass → copy original file to backup/<filename>.orig.smali, write patched file, proceed to packaging.

Step 12 (Report): see format below.

Step 13-14 (Package & Deliver):

  • ZIP structure:
    patch_result.zip
    ├── patched/<ClassName>.smali
    ├── backup/<ClassName>.orig.smali
    └── report.md
    
  • Multiple files: repeat steps 1-11 per file, one section per file in the same report, one ZIP total.
Recommendation
Clarify tool availability assumptions upfront (e.g., what 'smali'/'baksmali' commands look like in Termux) since this is called out as an environment-specific skill.
Markdown
# Smali Patch Report

Instruction (user)

"ubah return value jadi selalu true"

Analysis

  • .locals: 1 (before) -> 1 (after, no new register needed)
  • Original return path: line 12, return v0

Before

SMALI
.method public bypassCheck()Z .locals 1 invoke-static {}, Lcom/example/Checker;->check()Z move-result v0 return v0 .end method

After

SMALI
.method public bypassCheck()Z .locals 1 const/4 v0, 0x1 return v0 .end method

Reasoning

Replaced the check invocation with a hardcoded true (0x1), matching the requested behavior "always return true". Original invoke removed since its result is no longer used and dead invoke would be pointless (not dead code after return, so still safe to remove entirely).

Assumptions

None — instruction was unambiguous.

Validation

  • Assemble: OK
  • Disassemble: OK
  • Reassemble diff: identical to intended patch
  • Warnings: none
  • Errors: none

Backup

Original saved at: backup/Target.orig.smali

17 / 20

Example 1: Register-safe injection

Input: "Inject logging: write 'method called' to debug_log.txt at the start of onCreate, current .locals 2."

Output:

  • Detect .locals 2 → v0, v1 in use. New register needed for log logic → bump to .locals 3, use v2.
  • Insert file-write invoke sequence at top of method body (before any existing instruction, after the method header/locals/param directives).
  • Report documents: new register v2, reason ("avoid clobbering v0/v1 which hold existing state"), before/after snippet, validation result.

Example 2: Ambiguous instruction

Input: "ubah logic validasi jadi lebih longgar" (make validation logic looser) — no specifics.

Output:

  • Do not guess wildly. Pick the most logical minimal interpretation: e.g., if method returns boolean based on if-eqz/if-nez comparison, invert or bypass that specific comparison.
  • Explicitly document under Assumptions: "Instruksi ambigu. Diasumsikan 'longgar' berarti melewati pengecekan if-eqz v0, :fail dengan mengubahnya menjadi goto :success tanpa menghapus kode lain. Jika ini bukan maksud user, mohon berikan detail kondisi mana yang ingin diubah."

Example 3: Failed validation

Input: Patch introduces a branch to a label that doesn't exist after edit.

Output: Return error report only:

Markdown
# Smali Patch Report - FAILED
Recommendation
Consider trimming some repetition between the Step Details section and Best Practices/Common Pitfalls, as several points (locals bump, dead-code check, register safety) are restated three times.

Error

Reassemble failed: unresolved label :cond_5 referenced at line 20, no matching label found after edit (original label removed during patch).

Status

ZIP not generated. Please review the instruction or provide clarification.

  • Always print the exact register map before editing — never patch "blind".
  • Prefer the smallest possible diff that satisfies the instruction; don't refactor unrelated code.
  • When adding registers, always recompute .locals as (max register index used) + 1.
  • Treat p0 (this, for instance methods) as untouchable unless explicitly instructed.
  • Always run the round-trip check even for "trivial" one-line changes — trivial edits still break register counts often.
  • When multiple methods/files are touched, keep one report section per method, grouped per file, in a single combined report.
  • Don't reuse a live register just because it's numerically convenient — this silently corrupts unrelated values.
  • Don't forget to update .locals after adding a register — this causes a hard verifier error (VFY failure) on-device even if it assembles.
  • Don't insert any instruction after return*/throw in the same block — dead code that baksmali/smali will reject or silently strip.
  • Don't touch other methods/classes "while you're at it" — scope creep violates the transparency and instruction-compliance requirement.
  • Don't ship a ZIP when validation has warnings — treat warnings as failures.
  • Don't silently resolve ambiguity — always state the assumption explicitly in the report.
  • Don't skip the backup step, even for a "quick" patch.
0
Grade AAI Skill Framework
Scorecard
Criteria Breakdown
Quick Start
14/15
Workflow
15/15
Examples
17/20
Completeness
19/20
Format
14/15
Conciseness
13/15