Skip to content

Instantly share code, notes, and snippets.

@romainthomas
Created May 30, 2019 10:22
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save romainthomas/9479945fb9ec9b9d8f1ff947e098e80a to your computer and use it in GitHub Desktop.
Save romainthomas/9479945fb9ec9b9d8f1ff947e098e80a to your computer and use it in GitHub Desktop.
Jadx custom simplification
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