-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAllatoriStringTransformer.java
More file actions
118 lines (100 loc) · 4.42 KB
/
Copy pathAllatoriStringTransformer.java
File metadata and controls
118 lines (100 loc) · 4.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import org.objectweb.asm.*;
import java.lang.reflect.Method;
import java.util.*;
public class AllatoriStringTransformer extends ClassVisitor {
private final Map<String, Method> decryptMethodMap;
private final Set<String> decryptClassNames;
private final String className;
public AllatoriStringTransformer(int api, ClassVisitor cv, String className, Map<String, Method> decryptMethodMap, Set<String> decryptClassNames) {
super(api, cv);
this.className = className;
this.decryptMethodMap = decryptMethodMap;
this.decryptClassNames = decryptClassNames;
}
@Override
public void visitInnerClass(String name, String outerName, String innerName, int access) {
if (isAllatoriClass(name)) {
return;
}
super.visitInnerClass(name, outerName, innerName, access);
}
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
String methodKey = className.replace('/', '.') + "." + name + descriptor;
if (isDecryptMethod(methodKey)) {
return null;
}
MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
return new MethodVisitor(api, mv) {
private String pendingLdcString = null;
@Override
public void visitLdcInsn(Object value) {
if (value instanceof String) {
pendingLdcString = (String) value;
}
super.visitLdcInsn(value);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
String methodKey = owner.replace('/', '.') + "." + name + descriptor;
if (opcode == Opcodes.INVOKESTATIC && isDecryptMethod(methodKey)) {
Method decryptMethod = findDecryptMethod(methodKey);
if (decryptMethod != null && pendingLdcString != null) {
try {
decryptMethod.setAccessible(true);
String decrypted = (String) decryptMethod.invoke(null, pendingLdcString);
if (decrypted != null && decrypted.endsWith("ALLATORIxDEMO")) {
decrypted = decrypted.substring(0, decrypted.length() - "ALLATORIxDEMO".length());
}
super.visitInsn(Opcodes.POP);
super.visitLdcInsn(decrypted);
pendingLdcString = null;
return;
} catch (Exception e) {
System.err.println("[-] Decryption failed for " + methodKey + ": " + e.getMessage());
}
}
}
this.pendingLdcString = null;
super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
}
@Override
public void visitTypeInsn(int opcode, String type) {
if (isAllatoriClass(type)) {
return;
}
super.visitTypeInsn(opcode, type);
}
};
}
private boolean isDecryptMethod(String methodKey) {
if (decryptMethodMap.containsKey(methodKey)) {
return true;
}
return methodKey.endsWith("ALLATORIxDEMO") || methodKey.contains("ALLATORIxDEMO");
}
private Method findDecryptMethod(String methodKey) {
if (decryptMethodMap.containsKey(methodKey)) {
return decryptMethodMap.get(methodKey);
}
for (Map.Entry<String, Method> entry : decryptMethodMap.entrySet()) {
if (entry.getKey().endsWith("ALLATORIxDEMO") || methodKey.endsWith(entry.getKey())) {
return entry.getValue();
}
}
return null;
}
private boolean isAllatoriClass(String internalName) {
if (internalName == null) return false;
String norm = internalName.replace('/', '.');
if (norm.endsWith("ALLATORIxDEMO") || norm.contains("ALLATORIxDEMO")) {
return true;
}
for (String deco : decryptClassNames) {
if (norm.contains(deco)) {
return true;
}
}
return false;
}
}