google / google/smali

Switch Instruction Validation Error in MutableMethodImplementation

Open
#104 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
400
Forks
67
Avg merge
1d 2h
Merged PRs (30d)
1

Description

Issue

When creating a MutableMethodImplementation with a clean instruction list (containing only const/4 and return), the fixInstructions() method throws:

```
java.lang.IllegalStateException: Switch instruction at address/index 0x7/3 points to the end of the method.
```

---

How to Reproduce

```java
// Create fresh method implementation
MutableMethodImplementation mutable = new MutableMethodImplementation(1);
mutable.addInstruction(new BuilderInstruction11n(Opcode.CONST_4, 0, 0));
mutable.addInstruction(new BuilderInstruction11x(Opcode.RETURN, 0));

// This call fails with the exception above
mutable.getInstructions();
```

Expected Behavior

The method should return the two instructions without throwing any exception.

Actual Behavior

The method throws IllegalStateException even though there are no switch instructions in the new implementation.

Additional Context

This happens when:

· A method with PACKED_SWITCH or SPARSE_SWITCH is replaced with a clean implementation
· The MutableMethodImplementation is created from scratch (not copying original instructions)
· fixInstructions() somehow still tries to validate switch instructions that no longer exist

```
java.lang.IllegalStateException: Switch instruction at address/index 0x7/3 points to the end of the method.
at com.android.tools.smali.dexlib2.builder.MutableMethodImplementation.fixInstructions(MutableMethodImplementation.java:452)
at com.android.tools.smali.dexlib2.builder.MutableMethodImplementation.getInstructions(MutableMethodImplementation.java:220)
```

---

Environment

· Dexlib2 Version: Latest
· Java Version: 17
· Tested On: Multiple Android API levels

---

Impact

This prevents replacing method implementations when the original method contains switch instructions. Any attempt to build a clean method body results in this exception.

---

How to Fix, Could you please look into MutableMethodImplementation.fixInstructions() method? The switch validation logic seems to be triggered even when no switch instructions exist in the current implementation.

Maybe the method is retaining some internal state from the original method or not properly clearing references to removed instructions?

---

I'm not very familiar with the internal implementation, but I wanted to report this so you can investigate.

---

ERROR

```
E: [ERROR] ❌ virtualMethods Failed to patch: Lcom/fasterxml/jackson/module/kotlin/IntValueClassBoxConverter;->convert
java.lang.IllegalStateException: Switch error in method while building Action
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: java.lang.IllegalStateException: Switch instruction at address/index 0x7/3 points to the end of the method.
at com.android.tools.smali.dexlib2.builder.MutableMethodImplementation.fixInstructions(MutableMethodImplementation.java:452)
at com.android.tools.smali.dexlib2.builder.MutableMethodImplementation.getInstructions(MutableMethodImplementation.java:220)
at com.

[SmaliFiles.zip](https://github.com/user-attachments/files/30037075/SmaliFiles.zip)

patcher.dex.Action.(Action.java:52)
... 8 more

E: [ERROR] ❌ virtualMethods Failed to patch: Lcom/fasterxml/jackson/module/kotlin/NoConversionCreatorBoxDeserializer$WrapsInt;->invokeExact
java.lang.IllegalStateException: Switch error in method while building Action
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: java.lang.IllegalStateException: Switch instruction at address/index 0x7/3 points to the end of the method.
at com.android.tools.smali.dexlib2.builder.MutableMethodImplementation.fixInstructions(MutableMethodImplementation.java:452)
at com.android.tools.smali.dexlib2.builder.MutableMethodImplementation.getInstructions(MutableMethodImplementation.java:220)
at com.patcher.dex.Action.(Action.java:52)
... 8 more

E: [ERROR] ❌ virtualMethods Failed to patch: Lcom/fasterxml/jackson/module/kotlin/ValueClassKeyDeserializer$WrapsInt;->invokeExact
java.lang.IllegalStateException: Switch error in method while building Action
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: java.lang.IllegalStateException: Switch instruction at address/index 0x7/3 points to the end of the method.
at com.android.tools.smali.dexlib2.builder.MutableMethodImplementation.fixInstructions(MutableMethodImplementation.java:452)
at com.android.tools.smali.dexlib2.builder.MutableMethodImplementation.getInstructions(MutableMethodImplementation.java:220)
at com.patcher.dex.Action.(Action.java:52)
... 8 more
```

[SmaliFiles.zip](https://github.com/user-attachments/files/30037132/SmaliFiles.zip)

Contributor guide

Open the contributing guide

Research direction

Start with the reproducer in the issue, then inspect MutableMethodImplementation.getInstructions() and fixInstructions(), especially the validation at MutableMethodImplementation.java:452. Confirm whether a clean two-instruction implementation still retains switch-related state, and consider the issue done when it returns without the exception and replacing an implementation that previously contained a switch also succeeds.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.