Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing IndexOutOfBoundsException with negative register index #2056

Merged
merged 1 commit into from
Dec 10, 2023

Conversation

Away-pp
Copy link
Contributor

@Away-pp Away-pp commented Dec 10, 2023

When I try to decompile framework.jar (from /system/framework/framework.jar) the following exception occurs

ERROR: [5053] IndexOutOfBoundsException in pass: SSATransform in method: android.os.BatteryStats.dumpCheckinLocked(android.content.Context, java.io.PrintWriter, int, int, boolean):void, file: classes2.dex
java.lang.IndexOutOfBoundsException: bitIndex < 0: -80
	at java.base/java.util.BitSet.get(BitSet.java:626)
	at jadx.core.dex.visitors.ssa.LiveVarAnalysis.fillBasicBlockInfo(LiveVarAnalysis.java:65)
	at jadx.core.dex.visitors.ssa.LiveVarAnalysis.runAnalysis(LiveVarAnalysis.java:36)
	at jadx.core.dex.visitors.ssa.SSATransform.process(SSATransform.java:55)
	at jadx.core.dex.visitors.ssa.SSATransform.visit(SSATransform.java:41)
	at jadx.core.dex.visitors.DepthTraversal.visit(DepthTraversal.java:26)
	at jadx.core.dex.visitors.DepthTraversal.lambda$visit$1(DepthTraversal.java:14)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at jadx.core.dex.visitors.DepthTraversal.visit(DepthTraversal.java:14)
	at jadx.core.ProcessClass.process(ProcessClass.java:72)
	at jadx.core.ProcessClass.generateCode(ProcessClass.java:107)
	at jadx.core.dex.nodes.ClassNode.decompile(ClassNode.java:383)
	at jadx.core.dex.nodes.ClassNode.decompile(ClassNode.java:307)
	at jadx.api.JavaClass.load(JavaClass.java:127)
	at jadx.api.JavaClass.decompile(JavaClass.java:69)
	at jadx.gui.jobs.DecompileTask.lambda$scheduleJobs$0(DecompileTask.java:73)
	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:833)

After analysis, it was found that in DexInsnFormat class, the FORMAT_21T variable is doing the following operation

public static final DexInsnFormat FORMAT_21T = new DexInsnFormat(2, 1) {
                @Override
                public void decode(DexInsnData insn, int opcodeUnit, SectionReader in) {
                        int[] regs = insn.getArgsReg();
                        regs[0] = signedByte1(opcodeUnit);
                        insn.setTarget(insn.getOffset() + in.readShort());
                }

The issue found with this is that when the analyzed method is too big with a lot of internal variables, then opcodeUnit will have a big value (great than 32512). This will trigger an overflow and will create negative index for the registers.

The fix is to remove the signed operation and use the method byte1.

@skylot skylot merged commit d5bf9f2 into skylot:master Dec 10, 2023
5 checks passed
@skylot
Copy link
Owner

skylot commented Dec 10, 2023

@Away-pp great! Thank you for the fix 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants