Created
May 30, 2019 10:22
-
-
Save romainthomas/9479945fb9ec9b9d8f1ff947e098e80a to your computer and use it in GitHub Desktop.
Jadx custom simplification
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/jadx-core/src/main/java/jadx/core/Jadx.java b/jadx-core/src/main/java/jadx/core/Jadx.java | |
index 91ea0905..175b73ed 100644 | |
--- a/jadx-core/src/main/java/jadx/core/Jadx.java | |
+++ b/jadx-core/src/main/java/jadx/core/Jadx.java | |
@@ -47,6 +47,9 @@ import jadx.core.dex.visitors.shrink.CodeShrinkVisitor; | |
import jadx.core.dex.visitors.ssa.SSATransform; | |
import jadx.core.dex.visitors.typeinference.TypeInferenceVisitor; | |
+// Deobfuscation passes | |
+import jadx.core.dex.visitors.deobf.DecodeStrings; | |
+ | |
public class Jadx { | |
private static final Logger LOG = LoggerFactory.getLogger(Jadx.class); | |
@@ -119,6 +122,9 @@ public class Jadx { | |
passes.add(new DependencyCollector()); | |
passes.add(new RenameVisitor()); | |
+ | |
+ // Deobfuscation passes | |
+ passes.add(new DecodeStrings()); | |
} | |
return passes; | |
} | |
diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/deobf/DecodeStrings.java b/jadx-core/src/main/java/jadx/core/dex/visitors/deobf/DecodeStrings.java | |
new file mode 100644 | |
index 00000000..79f396bf | |
--- /dev/null | |
+++ b/jadx-core/src/main/java/jadx/core/dex/visitors/deobf/DecodeStrings.java | |
@@ -0,0 +1,109 @@ | |
+package jadx.core.dex.visitors.deobf; | |
+ | |
+import java.util.List; | |
+ | |
+import org.slf4j.Logger; | |
+import org.slf4j.LoggerFactory; | |
+ | |
+import jadx.core.dex.info.MethodInfo; | |
+import jadx.core.dex.instructions.ConstStringNode; | |
+import jadx.core.dex.instructions.InsnType; | |
+import jadx.core.dex.instructions.InvokeNode; | |
+import jadx.core.dex.instructions.PhiInsn; | |
+import jadx.core.dex.instructions.args.InsnArg; | |
+import jadx.core.dex.instructions.args.InsnWrapArg; | |
+import jadx.core.dex.instructions.args.RegisterArg; | |
+import jadx.core.dex.nodes.BlockNode; | |
+import jadx.core.dex.nodes.InsnNode; | |
+import jadx.core.dex.nodes.MethodNode; | |
+import jadx.core.dex.visitors.AbstractVisitor; | |
+ | |
+public class DecodeStrings extends AbstractVisitor { | |
+ | |
+ private static final Logger LOG = LoggerFactory.getLogger(DecodeStrings.class); | |
+ | |
+ public static byte[] hex2bytes(String str) { | |
+ byte[] bytes = str.getBytes(); | |
+ int length = bytes.length; | |
+ byte[] bArr = new byte[(length / 2)]; | |
+ for (int i = 0; i < length; i += 2) { | |
+ bArr[i / 2] = (byte) Integer.parseInt(new String(bytes, i, 2), 16); | |
+ } | |
+ return bArr; | |
+ } | |
+ | |
+ public static byte[] decode(byte[] bArr) { | |
+ byte[] bArr2 = new byte[bArr.length]; | |
+ for (int i = 0; i < bArr.length; i++) { | |
+ bArr2[i] = (byte) (bArr[i] ^ -1); | |
+ } | |
+ return bArr2; | |
+ } | |
+ | |
+ public static String decodeStr(String str) { | |
+ return new String(decode(hex2bytes(str))); | |
+ } | |
+ | |
+ | |
+ @Override | |
+ public void visit(MethodNode mth) { | |
+ if (mth.isNoCode()) { | |
+ return; | |
+ } | |
+ for (BlockNode block : mth.getBasicBlocks()) { | |
+ simplify(mth, block); | |
+ } | |
+ } | |
+ | |
+ | |
+ private static InsnNode simplify(MethodNode mth, InsnNode insn) { | |
+ for (InsnArg arg : insn.getArguments()) { | |
+ if (arg.isInsnWrap()) { | |
+ InsnNode ni = simplify(mth, ((InsnWrapArg) arg).getWrapInsn()); | |
+ if (ni != null) { | |
+ arg.wrapInstruction(ni); | |
+ } | |
+ } | |
+ } | |
+ | |
+ if (insn.getType() != InsnType.INVOKE) { | |
+ return null; | |
+ } | |
+ | |
+ MethodInfo callMth = ((InvokeNode) insn).getCallMth(); | |
+ | |
+ if (callMth.getDeclClass().getFullName().equals("com.ishumei.e.g") && callMth.getName().equals("qs")) { | |
+ // GaoAoxCoJpRm is a "static" method -> arg0: string | |
+ InsnArg arg0 = insn.getArg(0); | |
+ if (arg0.isRegister()) { | |
+ RegisterArg regArgs = (RegisterArg)arg0; | |
+ // TODO: Handle Phi assignment | |
+ PhiInsn assign = (PhiInsn)regArgs.getAssignInsn(); | |
+ return null; | |
+ } | |
+ ConstStringNode string_inst = (ConstStringNode)(((InsnWrapArg)arg0).getWrapInsn()); | |
+ | |
+ | |
+ String encoded = string_inst.getString(); | |
+ String decoded = decodeStr(encoded); | |
+ | |
+ LOG.info("{} --> {}", encoded, decoded); | |
+ | |
+ // New string | |
+ ConstStringNode constStrInsn = new ConstStringNode(decodeStr(encoded)); | |
+ return constStrInsn; | |
+ } | |
+ | |
+ return null; | |
+ | |
+ } | |
+ | |
+ private static void simplify(MethodNode mth, BlockNode block) { | |
+ List<InsnNode> insns = block.getInstructions(); | |
+ int size = insns.size(); | |
+ for (int i = 0; i < size; i++) { | |
+ InsnNode insn = insns.get(i); | |
+ simplify(mth, insn); | |
+ } | |
+ } | |
+} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment