From b7fe9758d0ca2de11a01124ffc9706c609bc618b Mon Sep 17 00:00:00 2001 From: NextToMinus Date: Fri, 24 Jan 2025 10:59:42 +0800 Subject: [PATCH 1/4] Fix the bug java.lang.IllegalArgumentException: Opcode: IPUT_OBJECT_VOLATILE @ 0x0 at soot.dexpler.instructions.InstructionFactory.fromOpcode(InstructionFactory.java:382) during create jimple for apk --- src/main/java/soot/dexpler/instructions/InstructionFactory.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/soot/dexpler/instructions/InstructionFactory.java b/src/main/java/soot/dexpler/instructions/InstructionFactory.java index 4588e9a82a2..07457f176cd 100644 --- a/src/main/java/soot/dexpler/instructions/InstructionFactory.java +++ b/src/main/java/soot/dexpler/instructions/InstructionFactory.java @@ -201,6 +201,7 @@ public static DexlibAbstractInstruction fromOpcode(Opcode op, Instruction instru case IGET: case IGET_OBJECT: + case IGET_OBJECT_VOLATILE: case IGET_BOOLEAN: case IGET_BYTE: case IGET_CHAR: @@ -209,6 +210,7 @@ public static DexlibAbstractInstruction fromOpcode(Opcode op, Instruction instru return new IgetInstruction(instruction, codeAddress); case IPUT: case IPUT_OBJECT: + case IPUT_OBJECT_VOLATILE: case IPUT_BOOLEAN: case IPUT_BYTE: case IPUT_CHAR: From 8d820167f78109f028984f8cd3be763f2b7e0d32 Mon Sep 17 00:00:00 2001 From: NextToMinus Date: Fri, 24 Jan 2025 13:02:10 +0800 Subject: [PATCH 2/4] fix the problem of stop create jimple because of :new RuntimeException("Variable " + m + " used without definition!")" Modifications: Replaced the code that throws a RuntimeException with a direct continue statement to skip the propagation step. Rationale: This approach is safer because certain variables (e.g., uninitialized parameters or special variables) may legitimately lack definitions. By skipping propagation for undefined variables, the CopyPropagator aligns with compiler fault-tolerance requirements, avoiding crashes caused by unresolved variables. Impact: After the modification, the program continues execution gracefully when encountering undefined variables instead of terminating abruptly. This ensures robustness for cases involving uninitialized variables or special symbols (e.g., parameters). --- .../java/soot/jimple/toolkits/scalar/CopyPropagator.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/soot/jimple/toolkits/scalar/CopyPropagator.java b/src/main/java/soot/jimple/toolkits/scalar/CopyPropagator.java index 329635bd743..c9242957f8f 100644 --- a/src/main/java/soot/jimple/toolkits/scalar/CopyPropagator.java +++ b/src/main/java/soot/jimple/toolkits/scalar/CopyPropagator.java @@ -218,7 +218,10 @@ protected void internalTransform(Body b, String phaseName, Map o if (l != m) { Integer defCount = localToDefCount.get(m); if (defCount == null || defCount == 0) { - throw new RuntimeException("Variable " + m + " used without definition!"); + if (Options.v().verbose()) { + logger.debug("[" + b.getMethod().getName() + "] Skipping undefined variable: " + m); + } + continue; } else if (defCount == 1) { useBox.setValue(m); copyLineTags(useBox, def); From 86ca1fe7c07b184b154ff240bcd38dc1c8abd9d8 Mon Sep 17 00:00:00 2001 From: NextToMinus Date: Fri, 24 Jan 2025 13:08:51 +0800 Subject: [PATCH 3/4] Fix the java.util.ConcurrentModificationException during the create jimple Error: ConcurrentModificationException occurs in multithreaded environments when an ArrayList is modified concurrently. Specifically, this happens during iteration over an ArrayList in the SootClass.getMethodsByNameAndParamCount() method while another thread modifies the list. Solution: Modify the getMethodsByNameAndParamCount() method to create a copy of the list before iteration. This avoids ConcurrentModificationException because the iteration is performed on the copied list. Even if the original list is modified by another thread, the iteration remains unaffected. Implementation: Create a snapshot of the list (e.g., using new ArrayList<>(originalList)). Iterate over the copied list instead of the original. Detail Exception Info Exception in thread "Thread-0" java.util.ConcurrentModificationException at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1095) at java.base/java.util.ArrayList$Itr.next(ArrayList.java:1049) at soot.SootClass.getMethodsByNameAndParamCount(SootClass.java:1326) at soot.FastHierarchy.getSignaturePolymorphicMethod(FastHierarchy.java:995) at soot.FastHierarchy.resolveMethod(FastHierarchy.java:894) at soot.FastHierarchy.resolveMethod(FastHierarchy.java:845) at soot.SootMethodRefImpl.tryResolve(SootMethodRefImpl.java:229) at soot.SootMethodRefImpl.tryResolve(SootMethodRefImpl.java:215) at soot.toolkits.exceptions.UnitThrowAnalysis.mightThrow(UnitThrowAnalysis.java:311) at soot.toolkits.exceptions.UnitThrowAnalysis$ValueSwitch.caseInstanceInvokeExpr(UnitThrowAnalysis.java:1217) at soot.toolkits.exceptions.UnitThrowAnalysis$ValueSwitch.caseInterfaceInvokeExpr(UnitThrowAnalysis.java:1034) at soot.jimple.internal.AbstractInterfaceInvokeExpr.apply(AbstractInterfaceInvokeExpr.java:121) at soot.toolkits.exceptions.UnitThrowAnalysis.mightThrow(UnitThrowAnalysis.java:303) at soot.toolkits.exceptions.UnitThrowAnalysis$UnitSwitch.caseInvokeStmt(UnitThrowAnalysis.java:813) at soot.jimple.internal.JInvokeStmt.apply(JInvokeStmt.java:99) at soot.toolkits.exceptions.UnitThrowAnalysis.mightThrow(UnitThrowAnalysis.java:287) at soot.toolkits.exceptions.UnitThrowAnalysis.mightThrow(UnitThrowAnalysis.java:282) at soot.toolkits.graph.ExceptionalUnitGraph.buildExceptionDests(ExceptionalUnitGraph.java:277) at soot.toolkits.graph.ExceptionalUnitGraph.initialize(ExceptionalUnitGraph.java:220) at soot.toolkits.graph.ExceptionalUnitGraph.(ExceptionalUnitGraph.java:127) at soot.toolkits.graph.ExceptionalUnitGraphFactory.newExceptionalUnitGraph(ExceptionalUnitGraphFactory.java:55) at soot.toolkits.graph.ExceptionalUnitGraphFactory.createExceptionalUnitGraph(ExceptionalUnitGraphFactory.java:50) at soot.jimple.toolkits.scalar.CopyPropagator.internalTransform(CopyPropagator.java:141) at soot.BodyTransformer.transform(BodyTransformer.java:52) at soot.BodyTransformer.transform(BodyTransformer.java:56) at soot.toolkits.scalar.SharedInitializationLocalSplitter.internalTransform(SharedInitializationLocalSplitter.java:135) at soot.BodyTransformer.transform(BodyTransformer.java:52) at soot.BodyTransformer.transform(BodyTransformer.java:56) at soot.dexpler.DexBody.jimplify(DexBody.java:747) at soot.dexpler.DexMethod$1.getBody(DexMethod.java:117) at soot.SootMethod.retrieveActiveBody(SootMethod.java:454) at soot.SootMethod.retrieveActiveBody(SootMethod.java:409) at soot.PackManager.lambda$retrieveAllBodies$2(PackManager.java:1224) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) at java.base/java.lang.Thread.run(Thread.java:1583) Exception in thread "main" java.util.ConcurrentModificationException at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1095) at java.base/java.util.ArrayList$Itr.next(ArrayList.java:1049) at soot.SootClass.getMethodsByNameAndParamCount(SootClass.java:1326) at soot.FastHierarchy.getSignaturePolymorphicMethod(FastHierarchy.java:995) at soot.FastHierarchy.resolveMethod(FastHierarchy.java:894) at soot.FastHierarchy.resolveMethod(FastHierarchy.java:845) at soot.SootMethodRefImpl.tryResolve(SootMethodRefImpl.java:229) at soot.SootMethodRefImpl.tryResolve(SootMethodRefImpl.java:215) at soot.toolkits.exceptions.UnitThrowAnalysis.mightThrow(UnitThrowAnalysis.java:311) at soot.toolkits.exceptions.UnitThrowAnalysis$ValueSwitch.caseInstanceInvokeExpr(UnitThrowAnalysis.java:1217) at soot.toolkits.exceptions.UnitThrowAnalysis$ValueSwitch.caseInterfaceInvokeExpr(UnitThrowAnalysis.java:1034) at soot.jimple.internal.AbstractInterfaceInvokeExpr.apply(AbstractInterfaceInvokeExpr.java:121) at soot.toolkits.exceptions.UnitThrowAnalysis.mightThrow(UnitThrowAnalysis.java:303) at soot.toolkits.exceptions.UnitThrowAnalysis$UnitSwitch.caseInvokeStmt(UnitThrowAnalysis.java:813) at soot.jimple.internal.JInvokeStmt.apply(JInvokeStmt.java:99) at soot.toolkits.exceptions.UnitThrowAnalysis.mightThrow(UnitThrowAnalysis.java:287) at soot.toolkits.exceptions.UnitThrowAnalysis.mightThrow(UnitThrowAnalysis.java:282) at soot.toolkits.graph.ExceptionalUnitGraph.buildExceptionDests(ExceptionalUnitGraph.java:277) at soot.toolkits.graph.ExceptionalUnitGraph.initialize(ExceptionalUnitGraph.java:220) at soot.toolkits.graph.ExceptionalUnitGraph.(ExceptionalUnitGraph.java:127) at soot.toolkits.graph.ExceptionalUnitGraphFactory.newExceptionalUnitGraph(ExceptionalUnitGraphFactory.java:55) at soot.toolkits.graph.ExceptionalUnitGraphFactory.createExceptionalUnitGraph(ExceptionalUnitGraphFactory.java:50) at soot.jimple.toolkits.scalar.CopyPropagator.internalTransform(CopyPropagator.java:141) at soot.BodyTransformer.transform(BodyTransformer.java:52) at soot.BodyTransformer.transform(BodyTransformer.java:56) at soot.toolkits.scalar.SharedInitializationLocalSplitter.internalTransform(SharedInitializationLocalSplitter.java:135) at soot.BodyTransformer.transform(BodyTransformer.java:52) at soot.BodyTransformer.transform(BodyTransformer.java:56) at soot.dexpler.DexBody.jimplify(DexBody.java:747) at soot.dexpler.DexMethod$1.getBody(DexMethod.java:117) at soot.SootMethod.retrieveActiveBody(SootMethod.java:454) at soot.SootMethod.retrieveActiveBody(SootMethod.java:409) at soot.PackManager.lambda$retrieveAllBodies$2(PackManager.java:1224) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) at java.base/java.lang.Thread.run(Thread.java:1583) --- src/main/java/soot/SootClass.java | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/main/java/soot/SootClass.java b/src/main/java/soot/SootClass.java index c334429f385..e3a43374881 100644 --- a/src/main/java/soot/SootClass.java +++ b/src/main/java/soot/SootClass.java @@ -1322,18 +1322,13 @@ public boolean isOpenedByModule() { * @return the methods */ public Collection getMethodsByNameAndParamCount(String name, int paramCount) { - List result = null; - for (SootMethod m : getMethods()) { - if (m.getParameterCount() == paramCount && m.getName().equals(name)) { - if (result == null) { - result = new ArrayList<>(); + List result = new ArrayList<>(); + // 创建副本以避免并发修改 + List methodsCopy = new ArrayList<>(this.getMethods()); + for (SootMethod m : methodsCopy) { + if (m.getName().equals(name) && m.getParameterCount() == paramCount) { + result.add(m); } - result.add(m); - } - } - - if (result == null) { - return Collections.emptyList(); } return result; } From 06fee56ef963aad241f5f43f438df2cfe295f318 Mon Sep 17 00:00:00 2001 From: NextToMinus Date: Fri, 24 Jan 2025 13:14:48 +0800 Subject: [PATCH 4/4] Translated Comment --- src/main/java/soot/SootClass.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/soot/SootClass.java b/src/main/java/soot/SootClass.java index e3a43374881..221e64e89a4 100644 --- a/src/main/java/soot/SootClass.java +++ b/src/main/java/soot/SootClass.java @@ -1323,7 +1323,7 @@ public boolean isOpenedByModule() { */ public Collection getMethodsByNameAndParamCount(String name, int paramCount) { List result = new ArrayList<>(); - // 创建副本以避免并发修改 + // Create a copy to avoid concurrent modification List methodsCopy = new ArrayList<>(this.getMethods()); for (SootMethod m : methodsCopy) { if (m.getName().equals(name) && m.getParameterCount() == paramCount) {