From 940de240992cba3b7ca031278b51bfcf3608781c Mon Sep 17 00:00:00 2001 From: Skylot Date: Fri, 2 Aug 2013 13:59:49 +0400 Subject: [PATCH] core: split const-string and const-class instructions --- .../main/java/jadx/core/codegen/ClassGen.java | 4 +++ .../main/java/jadx/core/codegen/CodeGen.java | 4 --- .../main/java/jadx/core/codegen/InsnGen.java | 25 +++++++++------- .../core/dex/instructions/ConstClassInsn.java | 23 +++++++++++++++ .../dex/instructions/ConstStringInsn.java | 22 ++++++++++++++ .../core/dex/instructions/InsnDecoder.java | 4 +-- .../jadx/core/dex/instructions/InsnType.java | 2 ++ .../core/dex/instructions/args/InsnArg.java | 29 ++++++++++++++----- .../dex/instructions/args/RegisterArg.java | 19 +++++++----- .../core/dex/instructions/args/TypedVar.java | 2 +- .../instructions/mods/ConstructorInsn.java | 1 + .../java/jadx/core/dex/nodes/InsnNode.java | 2 +- .../dex/nodes/parser/DebugInfoParser.java | 4 +-- .../dex/visitors/ConstInlinerVisitor.java | 9 ++---- .../dex/visitors/FallbackModeVisitor.java | 2 ++ .../jadx/core/dex/visitors/ModVisitor.java | 14 ++++++--- .../dex/visitors/regions/RegionMaker.java | 19 +++++++----- 17 files changed, 131 insertions(+), 54 deletions(-) create mode 100644 jadx-core/src/main/java/jadx/core/dex/instructions/ConstClassInsn.java create mode 100644 jadx-core/src/main/java/jadx/core/dex/instructions/ConstStringInsn.java diff --git a/jadx-core/src/main/java/jadx/core/codegen/ClassGen.java b/jadx-core/src/main/java/jadx/core/codegen/ClassGen.java index 75b0e192..aaab6b65 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/ClassGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/ClassGen.java @@ -355,6 +355,10 @@ public class ClassGen { if (isInner(classInfo, cls.getClassInfo())) return shortName; + // don't add import if this class from same package + if(classInfo.getPackage().equals(cls.getPackage())) + return shortName; + for (ClassInfo cls : imports) { if (!cls.equals(classInfo)) { if (cls.getShortName().equals(shortName)) diff --git a/jadx-core/src/main/java/jadx/core/codegen/CodeGen.java b/jadx-core/src/main/java/jadx/core/codegen/CodeGen.java index 5e496948..f0cf3f13 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/CodeGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/CodeGen.java @@ -5,16 +5,12 @@ import jadx.core.dex.nodes.ClassNode; import jadx.core.dex.visitors.AbstractVisitor; import jadx.core.utils.exceptions.CodegenException; -import java.io.File; - public class CodeGen extends AbstractVisitor { - private final File dir; private final IJadxArgs args; public CodeGen(IJadxArgs args) { this.args = args; - this.dir = args.getOutDir(); } @Override diff --git a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java index 5f584026..899dfa5e 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java @@ -8,6 +8,8 @@ import jadx.core.dex.info.FieldInfo; import jadx.core.dex.info.MethodInfo; import jadx.core.dex.instructions.ArithNode; import jadx.core.dex.instructions.ArithOp; +import jadx.core.dex.instructions.ConstClassInsn; +import jadx.core.dex.instructions.ConstStringInsn; import jadx.core.dex.instructions.FillArrayOp; import jadx.core.dex.instructions.GotoNode; import jadx.core.dex.instructions.IfNode; @@ -181,18 +183,19 @@ public class InsnGen { private void makeInsnBody(CodeWriter code, InsnNode insn, EnumSet state) throws CodegenException { switch (insn.getType()) { + case CONST_STR: + String str = ((ConstStringInsn) insn).getString(); + code.add(StringUtils.unescapeString(str)); + break; + + case CONST_CLASS: + ArgType clsType = ((ConstClassInsn) insn).getClsType(); + code.add(useType(clsType)).add(".class"); + break; + case CONST: - if (insn.getArgsCount() == 0) { - // const in 'index' - string or class - Object ind = ((IndexInsnNode) insn).getIndex(); - if (ind instanceof String) - code.add(StringUtils.unescapeString(ind.toString())); - else if (ind instanceof ArgType) - code.add(useType((ArgType) ind)).add(".class"); - } else { - LiteralArg arg = (LiteralArg) insn.getArg(0); - code.add(lit(arg)); - } + LiteralArg arg = (LiteralArg) insn.getArg(0); + code.add(lit(arg)); break; case MOVE: diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/ConstClassInsn.java b/jadx-core/src/main/java/jadx/core/dex/instructions/ConstClassInsn.java new file mode 100644 index 00000000..6b14ff00 --- /dev/null +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/ConstClassInsn.java @@ -0,0 +1,23 @@ +package jadx.core.dex.instructions; + +import jadx.core.dex.instructions.args.ArgType; +import jadx.core.dex.nodes.InsnNode; + +public class ConstClassInsn extends InsnNode { + + private final ArgType clsType; + + public ConstClassInsn(ArgType clsType) { + super(InsnType.CONST_CLASS, 0); + this.clsType = clsType; + } + + public ArgType getClsType() { + return clsType; + } + + @Override + public String toString() { + return super.toString() + " " + clsType; + } +} diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/ConstStringInsn.java b/jadx-core/src/main/java/jadx/core/dex/instructions/ConstStringInsn.java new file mode 100644 index 00000000..a8ffe9d9 --- /dev/null +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/ConstStringInsn.java @@ -0,0 +1,22 @@ +package jadx.core.dex.instructions; + +import jadx.core.dex.nodes.InsnNode; + +public class ConstStringInsn extends InsnNode { + + private final String str; + + public ConstStringInsn(String str) { + super(InsnType.CONST_STR, 0); + this.str = str; + } + + public String getString() { + return str; + } + + @Override + public String toString() { + return super.toString() + " \"" + str + "\""; + } +} diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/InsnDecoder.java b/jadx-core/src/main/java/jadx/core/dex/instructions/InsnDecoder.java index eefd683c..5f7ce170 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/InsnDecoder.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/InsnDecoder.java @@ -96,13 +96,13 @@ public class InsnDecoder { case Opcodes.CONST_STRING: case Opcodes.CONST_STRING_JUMBO: { - InsnNode node = new IndexInsnNode(InsnType.CONST, dex.getString(insn.getIndex()), 0); + InsnNode node = new ConstStringInsn(dex.getString(insn.getIndex())); node.setResult(InsnArg.reg(insn, 0, ArgType.STRING)); return node; } case Opcodes.CONST_CLASS: { - InsnNode node = new IndexInsnNode(InsnType.CONST, dex.getType(insn.getIndex()), 0); + InsnNode node = new ConstClassInsn(dex.getType(insn.getIndex())); node.setResult(InsnArg.reg(insn, 0, ArgType.CLASS)); return node; } diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/InsnType.java b/jadx-core/src/main/java/jadx/core/dex/instructions/InsnType.java index 8331b834..4a5b6043 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/InsnType.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/InsnType.java @@ -4,6 +4,8 @@ public enum InsnType { NOP, // replacement for removed instructions CONST, + CONST_STR, + CONST_CLASS, ARITH, NEG, diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/args/InsnArg.java b/jadx-core/src/main/java/jadx/core/dex/instructions/args/InsnArg.java index 7144f6be..6a2ba343 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/args/InsnArg.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/args/InsnArg.java @@ -64,10 +64,27 @@ public abstract class InsnArg extends Typed { for (int i = 0; i < count; i++) { if (parentInsn.getArg(i) == this) { InsnArg arg; - if (insn.getType() == InsnType.MOVE) { - arg = insn.getArg(0); - } else { - arg = wrap(insn); + InsnType insnType = insn.getType(); + switch (insnType) { + case MOVE: + case CONST: + arg = insn.getArg(0); + String name = insn.getResult().getTypedVar().getName(); + if (name != null) { + arg.getTypedVar().setName(name); + } + break; + case CONST_STR: + arg = wrap(insn); + arg.getTypedVar().forceSetType(ArgType.STRING); + break; + case CONST_CLASS: + arg = wrap(insn); + arg.getTypedVar().forceSetType(ArgType.CLASS); + break; + default: + arg = wrap(insn); + break; } parentInsn.setArg(i, arg); return arg; @@ -80,8 +97,4 @@ public abstract class InsnArg extends Typed { // must be implemented in RegisterArg return false; } - - public int getRegNum() { - throw new UnsupportedOperationException("Must be called from RegisterArg"); - } } diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/args/RegisterArg.java b/jadx-core/src/main/java/jadx/core/dex/instructions/args/RegisterArg.java index 4e858585..70be3f88 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/args/RegisterArg.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/args/RegisterArg.java @@ -1,6 +1,7 @@ package jadx.core.dex.instructions.args; -import jadx.core.dex.instructions.IndexInsnNode; +import jadx.core.dex.instructions.ConstClassInsn; +import jadx.core.dex.instructions.ConstStringInsn; import jadx.core.dex.instructions.InsnType; import jadx.core.dex.nodes.InsnNode; import jadx.core.dex.visitors.InstructionRemover; @@ -17,7 +18,6 @@ public class RegisterArg extends InsnArg { this.regNum = rn; } - @Override public int getRegNum() { return regNum; } @@ -47,12 +47,15 @@ public class RegisterArg extends InsnArg { */ public Object getConstValue() { InsnNode parInsn = getAssignInsn(); - if (parInsn != null && parInsn.getType() == InsnType.CONST) { - if (parInsn.getArgsCount() == 0) { - // const in 'index' - string or class - return ((IndexInsnNode) parInsn).getIndex(); - } else { - return parInsn.getArg(0); + if (parInsn != null) { + InsnType insnType = parInsn.getType(); + switch (insnType) { + case CONST: + return parInsn.getArg(0); + case CONST_STR: + return ((ConstStringInsn) parInsn).getString(); + case CONST_CLASS: + return ((ConstClassInsn) parInsn).getClsType(); } } return null; diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/args/TypedVar.java b/jadx-core/src/main/java/jadx/core/dex/instructions/args/TypedVar.java index 3a149583..de56fbb1 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/args/TypedVar.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/args/TypedVar.java @@ -21,7 +21,7 @@ public class TypedVar { * This method must be used very carefully */ public boolean forceSetType(ArgType newType) { - if (newType != null && !type.equals(newType)) { + if (!newType.equals(type)) { type = newType; return true; } else { diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/mods/ConstructorInsn.java b/jadx-core/src/main/java/jadx/core/dex/instructions/mods/ConstructorInsn.java index aff9d8cd..95d52ece 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/mods/ConstructorInsn.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/mods/ConstructorInsn.java @@ -4,6 +4,7 @@ import jadx.core.dex.info.ClassInfo; import jadx.core.dex.info.MethodInfo; import jadx.core.dex.instructions.InsnType; import jadx.core.dex.instructions.InvokeNode; +import jadx.core.dex.instructions.args.InsnArg; import jadx.core.dex.instructions.args.RegisterArg; import jadx.core.dex.nodes.InsnNode; import jadx.core.dex.nodes.MethodNode; diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java index f1168f21..96b4e56c 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java @@ -71,7 +71,7 @@ public class InsnNode extends LineAttrNode { public boolean containsArg(RegisterArg arg) { for (InsnArg a : arguments) { - if (a == arg || (a.isRegister() && a.getRegNum() == arg.getRegNum())) + if (a == arg || (a.isRegister() && ((RegisterArg)a).getRegNum() == arg.getRegNum())) return true; } return false; diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/parser/DebugInfoParser.java b/jadx-core/src/main/java/jadx/core/dex/nodes/parser/DebugInfoParser.java index 8524a7ad..c6b199f2 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/parser/DebugInfoParser.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/parser/DebugInfoParser.java @@ -168,7 +168,7 @@ public class DebugInfoParser { insn.setSourceLine(line); for (InsnArg arg : insn.getArguments()) if (arg.isRegister()) { - activeRegisters[arg.getRegNum()] = arg; + activeRegisters[((RegisterArg) arg).getRegNum()] = arg; } RegisterArg res = insn.getResult(); @@ -211,7 +211,7 @@ public class DebugInfoParser { private static void merge(InsnArg arg, LocalVar var) { if (arg != null && arg.isRegister()) { - if (var.getRegNum() == arg.getRegNum()) + if (var.getRegNum() == ((RegisterArg) arg).getRegNum()) arg.setTypedVar(var.getTypedVar()); } } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/ConstInlinerVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/ConstInlinerVisitor.java index 2c7ab24b..0721dd84 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/ConstInlinerVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/ConstInlinerVisitor.java @@ -36,13 +36,12 @@ public class ConstInlinerVisitor extends AbstractVisitor { private static boolean checkInsn(MethodNode mth, BlockNode block, InsnNode insn) { if (insn.getType() == InsnType.CONST) { - if (insn.getArgsCount() == 1 - && insn.getArg(0).isLiteral() + if (insn.getArg(0).isLiteral() && insn.getResult().getType().getRegCount() == 1 /* process only narrow types */) { long lit = ((LiteralArg) insn.getArg(0)).getLiteral(); return replaceConst(mth, block, insn, lit); } - // TODO process string const + // TODO process string and class const } return false; } @@ -106,9 +105,7 @@ public class ConstInlinerVisitor extends AbstractVisitor { private static void fixTypes(MethodNode mth, InsnNode insn) { switch (insn.getType()) { case CONST: - if (insn.getArgsCount() > 0) { - insn.getArg(0).merge(insn.getResult()); - } + insn.getArg(0).merge(insn.getResult()); break; case MOVE: diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/FallbackModeVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/FallbackModeVisitor.java index c6ef574a..b4f0d58f 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/FallbackModeVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/FallbackModeVisitor.java @@ -26,6 +26,8 @@ public class FallbackModeVisitor extends AbstractVisitor { case ARITH: // ?? case NEG: case CONST: + case CONST_STR: + case CONST_CLASS: case CMP_L: case CMP_G: catchAttr.getTryBlock().removeInsn(insn); diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java index 4ebf35e8..673eb2a3 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java @@ -4,6 +4,8 @@ import jadx.core.Consts; import jadx.core.deobf.NameMapper; import jadx.core.dex.attributes.AttributeType; import jadx.core.dex.info.MethodInfo; +import jadx.core.dex.instructions.ConstClassInsn; +import jadx.core.dex.instructions.ConstStringInsn; import jadx.core.dex.instructions.IndexInsnNode; import jadx.core.dex.instructions.InsnType; import jadx.core.dex.instructions.InvokeNode; @@ -98,12 +100,16 @@ public class ModVisitor extends AbstractVisitor { break; case CONST: + case CONST_STR: + case CONST_CLASS: ClassNode parentClass = mth.getParentClass(); FieldNode f = null; - if (insn.getArgsCount() == 0) { - // const-string - IndexInsnNode node = (IndexInsnNode) insn; - f = parentClass.getConstField(node.getIndex()); + if (insn.getType() == InsnType.CONST_STR) { + String s = ((ConstStringInsn) insn).getString(); + f = parentClass.getConstField(s); + } else if (insn.getType() == InsnType.CONST_CLASS) { + ArgType t = ((ConstClassInsn) insn).getClsType(); + f = parentClass.getConstField(t); } else { LiteralArg arg = (LiteralArg) insn.getArg(0); ArgType type = arg.getType(); diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java index f7115441..79fa4b31 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java @@ -1,5 +1,6 @@ package jadx.core.dex.visitors.regions; +import jadx.core.Consts; import jadx.core.dex.attributes.AttributeFlag; import jadx.core.dex.attributes.AttributeType; import jadx.core.dex.attributes.AttributesList; @@ -42,19 +43,23 @@ public class RegionMaker { private static final Logger LOG = LoggerFactory.getLogger(RegionMaker.class); private final MethodNode mth; - private final BitSet processedBlocks; + private BitSet processedBlocks; public RegionMaker(MethodNode mth) { this.mth = mth; - this.processedBlocks = new BitSet(mth.getBasicBlocks().size()); + if (Consts.DEBUG) { + this.processedBlocks = new BitSet(mth.getBasicBlocks().size()); + } } public Region makeRegion(BlockNode startBlock, RegionStack stack) { - int id = startBlock.getId(); - if (processedBlocks.get(id)) - LOG.debug(" Block already processed: " + startBlock + ", mth: " + mth); - else - processedBlocks.set(id); + if (Consts.DEBUG) { + int id = startBlock.getId(); + if (processedBlocks.get(id)) + LOG.debug(" Block already processed: " + startBlock + ", mth: " + mth); + else + processedBlocks.set(id); + } Region r = new Region(stack.peekRegion()); BlockNode next = startBlock; -- GitLab