From f482b8b95c121bedc70df1a3f30557be7e0c1f37 Mon Sep 17 00:00:00 2001 From: Skylot Date: Tue, 12 May 2020 21:52:00 +0100 Subject: [PATCH] fix: restart comment to escape strings in insn fallback dump --- .../java/jadx/core/codegen/MethodGen.java | 47 ++++++++++++++++--- .../core/dex/visitors/DotGraphVisitor.java | 4 +- .../dex/visitors/regions/CheckRegions.java | 2 +- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/jadx-core/src/main/java/jadx/core/codegen/MethodGen.java b/jadx-core/src/main/java/jadx/core/codegen/MethodGen.java index 04606b059..5840b40c5 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/MethodGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/MethodGen.java @@ -16,6 +16,7 @@ import jadx.core.dex.attributes.annotations.MethodParameters; import jadx.core.dex.attributes.nodes.JumpInfo; import jadx.core.dex.attributes.nodes.MethodOverrideAttr; import jadx.core.dex.info.AccessInfo; +import jadx.core.dex.instructions.ConstStringNode; import jadx.core.dex.instructions.IfNode; import jadx.core.dex.instructions.InsnType; import jadx.core.dex.instructions.args.ArgType; @@ -35,6 +36,10 @@ import jadx.core.utils.exceptions.CodegenException; import jadx.core.utils.exceptions.DecodeException; import jadx.core.utils.exceptions.JadxOverflowException; +import static jadx.core.codegen.MethodGen.FallbackOption.BLOCK_DUMP; +import static jadx.core.codegen.MethodGen.FallbackOption.COMMENTED_DUMP; +import static jadx.core.codegen.MethodGen.FallbackOption.FALLBACK_MODE; + public class MethodGen { private static final Logger LOG = LoggerFactory.getLogger(MethodGen.class); @@ -221,7 +226,7 @@ public class MethodGen { public void addInstructions(CodeWriter code) throws CodegenException { if (mth.root().getArgs().isFallbackMode()) { - addFallbackMethodCode(code); + addFallbackMethodCode(code, FALLBACK_MODE); } else if (classGen.isFallbackMode()) { dumpInstructions(code); } else { @@ -249,7 +254,7 @@ public class MethodGen { public void dumpInstructions(CodeWriter code) { code.startLine("/*"); - addFallbackMethodCode(code); + addFallbackMethodCode(code, COMMENTED_DUMP); code.startLine("*/"); code.startLine("throw new UnsupportedOperationException(\"Method not decompiled: ") @@ -263,7 +268,7 @@ public class MethodGen { .add("\");"); } - public void addFallbackMethodCode(CodeWriter code) { + public void addFallbackMethodCode(CodeWriter code, FallbackOption fallbackOption) { if (mth.getInstructions() == null) { // load original instructions try { @@ -285,11 +290,17 @@ public class MethodGen { if (mth.getThisArg() != null) { code.startLine(nameGen.useArg(mth.getThisArg())).add(" = this;"); } - addFallbackInsns(code, mth, insnArr, true); + addFallbackInsns(code, mth, insnArr, fallbackOption); code.decIndent(); } - public static void addFallbackInsns(CodeWriter code, MethodNode mth, InsnNode[] insnArr, boolean addLabels) { + public enum FallbackOption { + FALLBACK_MODE, + BLOCK_DUMP, + COMMENTED_DUMP + } + + public static void addFallbackInsns(CodeWriter code, MethodNode mth, InsnNode[] insnArr, FallbackOption option) { InsnGen insnGen = new InsnGen(getFallbackMethodGen(mth), true); boolean attachInsns = mth.root().getArgs().isJsonOutput(); InsnNode prevInsn = null; @@ -297,7 +308,7 @@ public class MethodGen { if (insn == null) { continue; } - if (addLabels && needLabel(insn, prevInsn)) { + if (option != BLOCK_DUMP && needLabel(insn, prevInsn)) { code.decIndent(); code.startLine(getLabelName(insn.getOffset()) + ':'); code.incIndent(); @@ -306,7 +317,14 @@ public class MethodGen { continue; } try { - code.startLine(); + boolean escapeComment = isCommentEscapeNeeded(insn, option); + if (escapeComment) { + code.decIndent(); + code.startLine("*/"); + code.startLine("// "); + } else { + code.startLine(); + } if (attachInsns) { code.attachLineAnnotation(insn); } @@ -318,6 +336,11 @@ public class MethodGen { } } insnGen.makeInsn(insn, code, InsnGen.Flags.INLINE); + if (escapeComment) { + code.startLine("/*"); + code.incIndent(); + } + CatchAttr catchAttr = insn.get(AType.CATCH_BLOCK); if (catchAttr != null) { code.add(" // " + catchAttr); @@ -330,6 +353,16 @@ public class MethodGen { } } + private static boolean isCommentEscapeNeeded(InsnNode insn, FallbackOption option) { + if (option == COMMENTED_DUMP) { + if (insn.getType() == InsnType.CONST_STR) { + String str = ((ConstStringNode) insn).getString(); + return str.contains("*/"); + } + } + return false; + } + private static boolean needLabel(InsnNode insn, InsnNode prevInsn) { if (insn.contains(AType.EXC_HANDLER)) { return true; diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/DotGraphVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/DotGraphVisitor.java index 5bf2900a9..ed69bc25f 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/DotGraphVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/DotGraphVisitor.java @@ -23,6 +23,8 @@ import jadx.core.utils.RegionUtils; import jadx.core.utils.StringUtils; import jadx.core.utils.Utils; +import static jadx.core.codegen.MethodGen.FallbackOption.BLOCK_DUMP; + public class DotGraphVisitor extends AbstractVisitor { private static final String NL = "\\l"; @@ -272,7 +274,7 @@ public class DotGraphVisitor extends AbstractVisitor { } else { CodeWriter code = new CodeWriter(); List instructions = block.getInstructions(); - MethodGen.addFallbackInsns(code, mth, instructions.toArray(new InsnNode[0]), false); + MethodGen.addFallbackInsns(code, mth, instructions.toArray(new InsnNode[0]), BLOCK_DUMP); String str = escape(code.newLine().toString()); if (str.startsWith(NL)) { str = str.substring(NL.length()); diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/CheckRegions.java b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/CheckRegions.java index 45fc2d223..39efecbd7 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/CheckRegions.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/CheckRegions.java @@ -61,7 +61,7 @@ public class CheckRegions extends AbstractVisitor { && !block.contains(AFlag.ADDED_TO_REGION) && !block.contains(AFlag.DONT_GENERATE) && !block.contains(AFlag.REMOVE)) { - String blockCode = getBlockInsnStr(mth, block); + String blockCode = getBlockInsnStr(mth, block).replace("*/", "*\\/"); mth.addWarn("Code restructure failed: missing block: " + block + ", code lost:" + blockCode); } }