Skip to content

Commit 0017ae8

Browse files
committed
Fixes
-ASM version set to 6.0, since javavm uses 6.0 -Obscure bug with MethodExecutor
1 parent efa6d95 commit 0017ae8

File tree

8 files changed

+167
-13
lines changed

8 files changed

+167
-13
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<version>1.0.0</version>
77
<properties>
88
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
9-
<version.asm>7.1</version.asm>
9+
<version.asm>6.0</version.asm>
1010
</properties>
1111
<build>
1212
<sourceDirectory>src/main/java</sourceDirectory>

src/main/java/com/javadeobfuscator/deobfuscator/executor/MethodExecutor.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,7 +1166,9 @@ else if(obj instanceof JavaObject)
11661166
MethodInsnNode cast = (MethodInsnNode) now;
11671167
Type type = Type.getReturnType(cast.desc);
11681168
List<JavaValue> args = new ArrayList<>();
1169-
for (Type t1 : Type.getArgumentTypes(cast.desc)) {
1169+
List<Type> l = new ArrayList<>(Arrays.asList(Type.getArgumentTypes(cast.desc)));
1170+
Collections.reverse(l);
1171+
for (Type t1 : l) {
11701172
if (t1.getSort() == Type.LONG || t1.getSort() == Type.DOUBLE) {
11711173
if (!(stack.get(0) instanceof JavaTop)) {
11721174
throw new ExecutionException("Expected JavaTop");
@@ -1264,7 +1266,9 @@ else if(obj instanceof JavaObject)
12641266
MethodInsnNode cast = (MethodInsnNode) now;
12651267
Type type = Type.getReturnType(cast.desc);
12661268
List<JavaValue> args = new ArrayList<>();
1267-
for (Type t1 : Type.getArgumentTypes(cast.desc)) {
1269+
List<Type> l = new ArrayList<>(Arrays.asList(Type.getArgumentTypes(cast.desc)));
1270+
Collections.reverse(l);
1271+
for (Type t1 : l) {
12681272
if (t1.getSort() == Type.LONG || t1.getSort() == Type.DOUBLE) {
12691273
if (!(stack.get(0) instanceof JavaTop)) {
12701274
throw new ExecutionException("Expected JavaTop");
@@ -1443,7 +1447,9 @@ else if(obj instanceof JavaObject)
14431447
MethodInsnNode cast = (MethodInsnNode) now;
14441448
Type type = Type.getReturnType(cast.desc);
14451449
List<JavaValue> args = new ArrayList<>();
1446-
for (Type t1 : Type.getArgumentTypes(cast.desc)) {
1450+
List<Type> l = new ArrayList<>(Arrays.asList(Type.getArgumentTypes(cast.desc)));
1451+
Collections.reverse(l);
1452+
for (Type t1 : l) {
14471453
if (t1.getSort() == Type.LONG || t1.getSort() == Type.DOUBLE) {
14481454
if (!(stack.get(0) instanceof JavaTop)) {
14491455
throw new ExecutionException("Expected JavaTop");
@@ -1607,7 +1613,9 @@ else if(argumentTypes[i + 3].getSort() == Type.DOUBLE)
16071613
args.add(JavaValue.valueOf(arg));
16081614
}
16091615
List<JavaValue> newArgs = new ArrayList<>();
1610-
for (Type t1 : Type.getArgumentTypes(cast.desc)) {
1616+
List<Type> l = new ArrayList<>(Arrays.asList(Type.getArgumentTypes(cast.desc)));
1617+
Collections.reverse(l);
1618+
for (Type t1 : l) {
16111619
if (t1.getSort() == Type.LONG || t1.getSort() == Type.DOUBLE) {
16121620
if (!(stack.get(0) instanceof JavaTop)) {
16131621
throw new ExecutionException("Expected JavaTop");

src/main/java/com/javadeobfuscator/deobfuscator/transformers/allatori/StringEncryptionTransformer.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,14 @@ public boolean canCheckEquality(JavaValue first, JavaValue second, Context conte
104104
{
105105
MethodInsnNode m = (MethodInsnNode)ain;
106106
String strCl = m.owner;
107-
if(m.desc.equals("(Ljava/lang/String;)Ljava/lang/String;"))
107+
if(m.desc.equals("(Ljava/lang/Object;)Ljava/lang/String;")
108+
|| m.desc.equals("(Ljava/lang/String;)Ljava/lang/String;"))
108109
{
109110
Frame<SourceValue> f = frames[method.instructions.indexOf(m)];
110111
if(f.getStack(f.getStackSize() - 1).insns.size() != 1)
111112
continue;
112113
AbstractInsnNode ldc = f.getStack(f.getStackSize() - 1).insns.iterator().next();
113-
if(ldc.getOpcode() != Opcodes.LDC)
114+
if(ldc.getOpcode() != Opcodes.LDC || !(((LdcInsnNode)ldc).cst instanceof String))
114115
continue;
115116
Context context = new Context(provider);
116117
context.push(classNode.name, method.name, getDeobfuscator().getConstantPool(classNode).getSize());

src/main/java/com/javadeobfuscator/deobfuscator/transformers/general/peephole/ConstantFolder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public boolean transform() throws Throwable {
9696
if (results.size() == 1) {
9797
InsnList replacement = new InsnList();
9898
replacement.add(new InsnNode(POP2)); // remove existing args from stack
99-
replacement.add(Utils.getNumberInsn(results.iterator().next()));
99+
replacement.add(Utils.getIntInsn(results.iterator().next()));
100100
replacements.put(ain, replacement);
101101
folded.getAndIncrement();
102102
}

src/main/java/com/javadeobfuscator/deobfuscator/transformers/smoke/NumberObfuscationTransformer.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public boolean transform() throws Throwable {
3737
((MethodInsnNode) ain).name.equals("length") &&
3838
ain.getPrevious() instanceof LdcInsnNode && ((LdcInsnNode) ain.getPrevious()).cst instanceof String) {
3939
AbstractInsnNode previous = ain.getPrevious();
40-
method.instructions.set(ain, Utils.getNumberInsn(((String)((LdcInsnNode)ain.getPrevious()).cst).length()));
40+
method.instructions.set(ain, Utils.getIntInsn(((String)((LdcInsnNode)ain.getPrevious()).cst).length()));
4141
method.instructions.remove(previous);
4242
count.getAndIncrement();
4343
}
@@ -81,7 +81,7 @@ else if(entry.getKey() == a2)
8181
{
8282
Integer resultValue;
8383
if((resultValue = doMath(Utils.getIntValue(a1), Utils.getIntValue(a2), ain.getOpcode())) != null) {
84-
AbstractInsnNode newValue = Utils.getNumberInsn(resultValue);
84+
AbstractInsnNode newValue = Utils.getIntInsn(resultValue);
8585
replace.put(ain, newValue);
8686
method.instructions.set(ain, newValue);
8787
method.instructions.remove(a1);
@@ -114,7 +114,7 @@ else if(entry.getKey() == a2)
114114
if (ain.getOpcode() == Opcodes.INVOKESTATIC) {
115115
Integer number = numberMethods.get(((MethodInsnNode)ain).owner + ((MethodInsnNode)ain).name + ((MethodInsnNode)ain).desc);
116116
if (number != null) {
117-
method.instructions.set(ain, Utils.getNumberInsn(number));
117+
method.instructions.set(ain, Utils.getIntInsn(number));
118118
count.getAndIncrement();
119119
}
120120
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/*
2+
* Copyright 2018 Sam Sun <[email protected]>
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.javadeobfuscator.deobfuscator.transformers.special;
18+
19+
import java.util.Collections;
20+
import java.util.HashMap;
21+
import java.util.Map;
22+
import java.util.Map.Entry;
23+
import java.util.concurrent.atomic.AtomicInteger;
24+
25+
import org.objectweb.asm.Opcodes;
26+
import org.objectweb.asm.tree.ClassNode;
27+
import org.objectweb.asm.tree.InsnNode;
28+
import org.objectweb.asm.tree.MethodInsnNode;
29+
import org.objectweb.asm.tree.MethodNode;
30+
import org.objectweb.asm.tree.VarInsnNode;
31+
32+
import com.javadeobfuscator.deobfuscator.config.*;
33+
import com.javadeobfuscator.deobfuscator.exceptions.*;
34+
import com.javadeobfuscator.deobfuscator.transformers.*;
35+
import com.javadeobfuscator.deobfuscator.utils.TransformerHelper;
36+
import com.javadeobfuscator.javavm.MethodExecution;
37+
import com.javadeobfuscator.javavm.VirtualMachine;
38+
import com.javadeobfuscator.javavm.mirrors.JavaClass;
39+
import com.javadeobfuscator.javavm.utils.ArrayConversionHelper;
40+
import com.javadeobfuscator.javavm.values.JavaWrapper;
41+
42+
public class BisGuardTransformer extends Transformer<TransformerConfig>
43+
{
44+
@Override
45+
public boolean transform() throws WrongTransformerException
46+
{
47+
VirtualMachine vm = TransformerHelper.newVirtualMachine(this);
48+
AtomicInteger count = new AtomicInteger();
49+
System.out.println("[Special] [BisGuardTransformer] Starting");
50+
ClassNode loader = classNodes().stream().filter(c -> c.name.equals("JavaPreloader")).findFirst().orElse(null);
51+
MethodNode getCipher = loader == null ? null : loader.methods.stream().filter(m -> m.name.equals("getCipher")
52+
&& m.desc.equals("([B)LJavaPreloader$Cipher;")).findFirst().orElse(null);
53+
ClassNode cipher = classNodes().stream().filter(c -> c.name.equals("JavaPreloader$Cipher")).findFirst().orElse(null);
54+
MethodNode decrypt = cipher == null ? null : cipher.methods.stream().filter(m -> m.name.equals("decrypt")
55+
&& m.desc.equals("([B)V")).findFirst().orElse(null);
56+
if(getCipher != null && decrypt != null)
57+
{
58+
MethodNode init = new MethodNode(Opcodes.ACC_PUBLIC, "<init>", "(I)V", null, null);
59+
init.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
60+
init.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false));
61+
init.instructions.add(new InsnNode(Opcodes.RETURN));
62+
loader.methods.add(init);
63+
JavaWrapper instance = vm.newInstance(JavaClass.forName(vm, "JavaPreloader"), "(I)V", vm.newInt(0));
64+
loader.methods.remove(init);
65+
MethodExecution cipherInstance = vm.execute(loader, getCipher, instance, Collections.<JavaWrapper>singletonList(
66+
vm.getNull()));
67+
boolean contains = getDeobfuscator().getInputPassthrough().containsKey("JavaSerialNo.class");
68+
byte[] decryptionKey = null;
69+
if(contains)
70+
{
71+
byte[] data = getDeobfuscator().getInputPassthrough().get("JavaSerialNo.class");
72+
JavaWrapper byteArr = ArrayConversionHelper.convertByteArray(vm, data);
73+
vm.execute(cipher, decrypt, cipherInstance.getReturnValue(), Collections.<JavaWrapper>singletonList(byteArr));
74+
byte[] b = ArrayConversionHelper.convertByteArray(byteArr.asArray());
75+
getDeobfuscator().getInputPassthrough().remove("JavaSerialNo.class");
76+
getDeobfuscator().loadInput("JavaSerialNo.class", b);
77+
ClassNode cn = classNodes().stream().filter(c -> c.name.equals("JavaSerialNo")).findFirst().orElse(null);
78+
MethodNode serialBytes = cn.methods.stream().filter(m -> m.name.equals("toSerialNoBytes")).findFirst().orElse(null);
79+
MethodExecution execution = vm.execute(cn, serialBytes);
80+
String res = vm.convertJavaObjectToString(execution.getReturnValue());
81+
//Convert to decryption key
82+
MethodNode hex2Bytes = loader.methods.stream().filter(m -> m.name.equals("hexToBytes")).findFirst().orElse(null);
83+
MethodExecution execution2 = vm.execute(loader, hex2Bytes, instance, Collections.<JavaWrapper>singletonList(
84+
vm.getString(res)));
85+
cipherInstance = vm.execute(loader, getCipher, instance, Collections.<JavaWrapper>singletonList(
86+
vm.getNull()));
87+
decryptionKey = ArrayConversionHelper.convertByteArray(execution2.getReturnValue().asArray());
88+
JavaWrapper byteArr1 = ArrayConversionHelper.convertByteArray(vm, decryptionKey);
89+
vm.execute(cipher, decrypt, cipherInstance.getReturnValue(), Collections.<JavaWrapper>singletonList(byteArr1));
90+
decryptionKey = ArrayConversionHelper.convertByteArray(byteArr1.asArray());
91+
cipherInstance = vm.execute(loader, getCipher, instance, Collections.<JavaWrapper>singletonList(
92+
ArrayConversionHelper.convertByteArray(vm, decryptionKey)));
93+
}
94+
Map<String, byte[]> decrypted = new HashMap<>();
95+
for(Entry<String, byte[]> passthrough : getDeobfuscator().getInputPassthrough().entrySet())
96+
if(passthrough.getKey().endsWith(".class"))
97+
{
98+
byte[] data = passthrough.getValue();
99+
if(data[0] != -54 || data[1] != -2 || data[2] != -70 || data[3] != -66)
100+
{
101+
cipherInstance = vm.execute(loader, getCipher, instance, Collections.<JavaWrapper>singletonList(
102+
decryptionKey == null ? vm.getNull() : ArrayConversionHelper.convertByteArray(vm, decryptionKey)));
103+
JavaWrapper byteArr = ArrayConversionHelper.convertByteArray(vm, data);
104+
vm.execute(cipher, decrypt, cipherInstance.getReturnValue(), Collections.<JavaWrapper>singletonList(byteArr));
105+
byte[] b = ArrayConversionHelper.convertByteArray(byteArr.asArray());
106+
decrypted.put(passthrough.getKey(), b);
107+
count.getAndIncrement();
108+
}
109+
}
110+
for(Entry<String, byte[]> entry : decrypted.entrySet())
111+
{
112+
getDeobfuscator().getInputPassthrough().remove(entry.getKey());
113+
getDeobfuscator().loadInput(entry.getKey(), entry.getValue());
114+
}
115+
//Delete all class files related to encryption
116+
classNodes().removeIf(c -> c.name.equals("JavaPreloader$1") || c.name.equals("JavaPreloader$2")
117+
|| c.name.equals("JavaPreloader$3") || c.name.equals("JavaPreloader$Cipher")
118+
|| c.name.equals("JavaPreloader$KlassLoader") || c.name.equals("JavaPreloader$Loader")
119+
|| c.name.equals("JavaPreloader$Protected") || c.name.equals("JavaPreloader")
120+
|| c.name.equals("JavaSerialNo") || c.name.equals("SerialNoClass")
121+
|| c.name.equals("com/bisguard/utils/Authenticator"));
122+
//Set Main-Class to Subordinate-Class
123+
String realMain = null;
124+
int index = -1;
125+
String[] lines = new String(getDeobfuscator().getInputPassthrough().get("META-INF/MANIFEST.MF")).split("\n");
126+
for(int i = 0; i < lines.length; i++)
127+
{
128+
String line = lines[i];
129+
if(line.startsWith("Subordinate-Class: "))
130+
realMain = line.replace("Subordinate-Class: ", "");
131+
else if(line.startsWith("Main-Class: "))
132+
index = i;
133+
}
134+
lines[index] = "Main-Class: " + realMain;
135+
String res = "";
136+
for(String line : lines)
137+
res += line + "\n";
138+
res = res.substring(0, res.length() - 2);
139+
getDeobfuscator().getInputPassthrough().put("META-INF/MANIFEST.MF", res.getBytes());
140+
}
141+
System.out.println("[Special] [BisGuardTransformer] Decrypted " + count.get() + " classes");
142+
System.out.println("[Special] [BisGuardTransformer] Done");
143+
return count.get() > 0;
144+
}
145+
}

src/main/java/com/javadeobfuscator/deobfuscator/transformers/special/FlowObfuscationTransformer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ else if(entry.getKey() == a2)
244244
Integer resultValue;
245245
if((resultValue = doMath(Utils.getIntValue(a1), Utils.getIntValue(a2), ain.getOpcode())) != null)
246246
{
247-
AbstractInsnNode newValue = Utils.getNumberInsn(resultValue);
247+
AbstractInsnNode newValue = Utils.getIntInsn(resultValue);
248248
replace.put(ain, newValue);
249249
method.instructions.set(ain, newValue);
250250
method.instructions.remove(a1);

src/main/java/com/javadeobfuscator/deobfuscator/utils/Utils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ public static InsnList cloneInsnList(InsnList original) {
328328
return newInsnList;
329329
}
330330

331-
public static AbstractInsnNode getNumberInsn(int number) {
331+
public static AbstractInsnNode getIntInsn(int number) {
332332
if (number >= -1 && number <= 5)
333333
return new InsnNode(number + 3);
334334
else if (number >= -128 && number <= 127)

0 commit comments

Comments
 (0)