- Статус
- Оффлайн
- Регистрация
- 8 Ноя 2023
- Сообщения
- 1,640
- Реакции
- 138
Дарова Воркис и Винеку, знали ли вы то что шваркать юзеров и друзей плохо?
Привет вам от: MetaOne, CrashSyska, bespl1k, wlprince
И пламенный привет от Анабиоза и земельки!
Мы ведь ещё увидимся на божественной арене?...
Оригинальный JAR ->
Конечный JAR (готовый кряк) ->
Воспроизвести кряк можете через ->

Привет вам от: MetaOne, CrashSyska, bespl1k, wlprince
И пламенный привет от Анабиоза и земельки!
Мы ведь ещё увидимся на божественной арене?...
Оригинальный JAR ->
Пожалуйста, авторизуйтесь для просмотра ссылки.
Конечный JAR (готовый кряк) ->
Пожалуйста, авторизуйтесь для просмотра ссылки.
Пожалуйста, авторизуйтесь для просмотра ссылки.
Пожалуйста, авторизуйтесь для просмотра ссылки.
Воспроизвести кряк можете через ->
javelincracker:
/*
* Cracked by MetaOne
* Join Kaelus -> https://dsc.gg/kaelus
*/
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
public class JavelinClientCracker {
private static final String AUTH_CLASS = "vorkis/481";
private static final String AUTH_METHOD = "break 269";
private static final String AUTH_DESC = "()V";
private static final String SUCCESS_FIELD = "439932";
private static final String CONT_CLASS = "vorkis/248";
private static final String CONT_METHOD = "class 815";
private static final String HWID_CLASS = "vorkis/0930";
private static final String HWID_METHOD = "public 0124";
private static final String HWID_DESC = "(Ljava/lang/String;)Z";
private static final String RPC_CLASS = "vorkis/269";
private static final String RPC_DECODER = "strictfp 313";
private static final String RPC_DESC = "(I)Ljava/lang/String;";
private static final String NOTIFY_CLASS = "dev/kaelus/notifier/Notify";
private static final String PROCESS_SPAWN = new String(new char[]{'e','x','e','c'});
public static void main(String[] args) throws Exception {
if (args.length != 2) {
System.err.println("Usage: JavelinClientCracker <input.jar> <output.jar>");
System.exit(2);
}
Path in = Paths.get(args[0]);
Path out = Paths.get(args[1]);
String fieldName, methodName, contName, hwidMethodName, rpcMethodName;
try (ZipFile zin = new ZipFile(in.toFile())) {
fieldName = findField(zin, AUTH_CLASS, SUCCESS_FIELD, "Ljava/lang/String;");
methodName = findMethod(zin, AUTH_CLASS, AUTH_METHOD, AUTH_DESC);
contName = findMethod(zin, CONT_CLASS, CONT_METHOD, "()V");
hwidMethodName = findMethod(zin, HWID_CLASS, HWID_METHOD, HWID_DESC);
rpcMethodName = findMethod(zin, RPC_CLASS, RPC_DECODER, RPC_DESC);
}
if (fieldName == null) throw new IllegalStateException("field 439932 not found in " + AUTH_CLASS);
if (methodName == null) throw new IllegalStateException("method break 269 not found in " + AUTH_CLASS);
if (contName == null) throw new IllegalStateException("continuation class 815 not found in " + CONT_CLASS);
if (hwidMethodName == null) System.err.println("[cracker] WARN: " + HWID_CLASS + ".public 0124 not found");
if (rpcMethodName == null) System.err.println("[cracker] WARN: " + RPC_CLASS + ".strictfp 313 not found");
System.err.println("[cracker] field = " + visualize(fieldName));
System.err.println("[cracker] method = " + visualize(methodName));
System.err.println("[cracker] continuation= " + visualize(contName));
if (hwidMethodName != null) System.err.println("[cracker] hwid method = " + visualize(hwidMethodName));
if (rpcMethodName != null) System.err.println("[cracker] rpc decoder = " + visualize(rpcMethodName));
java.util.Map<String, java.util.Set<String>> rpcWrappers = new java.util.HashMap<>();
if (rpcMethodName != null) {
java.util.Set<String> base = new java.util.HashSet<>();
base.add(rpcMethodName);
rpcWrappers.put(RPC_CLASS, base);
try (ZipFile zin = new ZipFile(in.toFile())) {
boolean grew;
do {
grew = false;
Enumeration<? extends ZipEntry> en = zin.entries();
while (en.hasMoreElements()) {
ZipEntry e = en.nextElement();
if (!e.getName().startsWith("vorkis/") || !e.getName().endsWith(".class")) continue;
ClassReader cr;
try { cr = new ClassReader(zin.getInputStream(e).readAllBytes()); }
catch (Throwable t) { continue; }
ClassNode cn = new ClassNode();
try { cr.accept(cn, ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG); }
catch (Throwable t) { continue; }
if (cn.methods == null) continue;
for (MethodNode mn : cn.methods) {
if ((mn.access & Opcodes.ACC_STATIC) == 0) continue;
if (!RPC_DESC.equals(mn.desc)) continue;
if (mn.instructions == null) continue;
String wrapped = wrapperOf(mn, rpcWrappers);
if (wrapped == null) continue;
java.util.Set<String> s = rpcWrappers.computeIfAbsent(cn.name, k -> new java.util.HashSet<>());
if (s.add(mn.name)) grew = true;
}
}
} while (grew);
}
int total = rpcWrappers.values().stream().mapToInt(java.util.Set::size).sum();
System.err.println("[cracker] rpc decoder + wrappers across classes: " + total);
}
byte[] notifyBytes = buildNotifyClass();
boolean notifyAdded = false;
int repaired = 0, repairFail = 0, authPatched = 0, hwidPatched = 0, rpcCallsPatched = 0;
try (ZipFile zin = new ZipFile(in.toFile());
ZipOutputStream zout = new ZipOutputStream(Files.newOutputStream(out))) {
zout.setLevel(9);
Enumeration<? extends ZipEntry> entries = zin.entries();
while (entries.hasMoreElements()) {
ZipEntry e = entries.nextElement();
ZipEntry copy = new ZipEntry(e.getName());
copy.setMethod(ZipEntry.DEFLATED);
zout.putNextEntry(copy);
if (!e.isDirectory()) {
try (InputStream is = zin.getInputStream(e)) {
byte[] raw = is.readAllBytes();
byte[] outBytes = raw;
if (e.getName().startsWith("vorkis/") && e.getName().endsWith(".class")) {
try {
outBytes = repairClass(raw);
if (outBytes != raw) repaired++;
} catch (Throwable t) { outBytes = raw; repairFail++; }
}
if (e.getName().equals(AUTH_CLASS + ".class")) {
outBytes = applyAuthPatch(outBytes, fieldName, methodName, contName);
authPatched++;
}
if (hwidMethodName != null && e.getName().equals(HWID_CLASS + ".class")) {
outBytes = applyHwidPatch(outBytes, hwidMethodName);
hwidPatched++;
}
if (rpcMethodName != null && e.getName().equals(RPC_CLASS + ".class")) {
int[] cnt = new int[]{0};
outBytes = applyRpcDecoderPrologue(outBytes, rpcMethodName, cnt);
rpcCallsPatched += cnt[0];
}
zout.write(outBytes);
}
}
zout.closeEntry();
}
ZipEntry notifyEntry = new ZipEntry(NOTIFY_CLASS + ".class");
notifyEntry.setMethod(ZipEntry.DEFLATED);
zout.putNextEntry(notifyEntry);
zout.write(notifyBytes);
zout.closeEntry();
notifyAdded = true;
}
System.err.println("[cracker] repaired classes: " + repaired + " (fail=" + repairFail + ")");
System.err.println("[cracker] auth-patched: " + authPatched);
System.err.println("[cracker] hwid-patched: " + hwidPatched);
System.err.println("[cracker] rpc call-sites patched: " + rpcCallsPatched);
System.err.println("[cracker] notify class added: " + notifyAdded);
System.err.println("[cracker] wrote " + out);
}
private static byte[] repairClass(byte[] raw) {
ClassReader cr = new ClassReader(raw);
ClassNode cn = new ClassNode();
cr.accept(cn, ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG);
boolean changed = false;
if (cn.methods != null) {
for (MethodNode mn : cn.methods) {
if (mn.tryCatchBlocks == null || mn.instructions == null) continue;
Set<LabelNode> live = new HashSet<>();
for (AbstractInsnNode insn : mn.instructions) {
if (insn instanceof LabelNode ln) live.add(ln);
}
int before = mn.tryCatchBlocks.size();
mn.tryCatchBlocks.removeIf(tcb ->
!live.contains(tcb.start)
|| !live.contains(tcb.end)
|| !live.contains(tcb.handler));
if (mn.tryCatchBlocks.size() != before) changed = true;
}
}
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cn.accept(cw);
byte[] result = cw.toByteArray();
return changed || result.length != raw.length ? result : raw;
}
private static byte[] applyAuthPatch(byte[] raw, String fieldName, String methodName, String contName) {
ClassReader cr = new ClassReader(raw);
ClassNode cn = new ClassNode();
cr.accept(cn, ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG);
for (MethodNode mn : cn.methods) {
if (!methodName.equals(mn.name) || !AUTH_DESC.equals(mn.desc)) continue;
String fakeBody = "{\"ok\":true,\"valid\":true,\"hasSubscription\":true}";
InsnList body = new InsnList();
body.add(new LdcInsnNode(fakeBody));
body.add(new FieldInsnNode(Opcodes.PUTSTATIC, AUTH_CLASS, fieldName, "Ljava/lang/String;"));
body.add(new MethodInsnNode(Opcodes.INVOKESTATIC, NOTIFY_CLASS, "show", "()V", false));
body.add(new InsnNode(Opcodes.RETURN));
mn.instructions = body;
if (mn.tryCatchBlocks != null) mn.tryCatchBlocks.clear();
if (mn.localVariables != null) mn.localVariables.clear();
mn.maxStack = 1;
mn.maxLocals = 1;
System.err.println("[cracker] body of " + visualize(mn.name) + mn.desc + " replaced");
}
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
cn.accept(cw);
return cw.toByteArray();
}
private static byte[] applyHwidPatch(byte[] raw, String methodName) {
ClassReader cr = new ClassReader(raw);
ClassNode cn = new ClassNode();
cr.accept(cn, ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG);
for (MethodNode mn : cn.methods) {
if (!methodName.equals(mn.name) || !HWID_DESC.equals(mn.desc)) continue;
InsnList body = new InsnList();
body.add(new InsnNode(Opcodes.ICONST_1));
body.add(new InsnNode(Opcodes.IRETURN));
mn.instructions = body;
if (mn.tryCatchBlocks != null) mn.tryCatchBlocks.clear();
if (mn.localVariables != null) mn.localVariables.clear();
mn.maxStack = 1;
mn.maxLocals = 2;
System.err.println("[cracker] body of " + visualize(mn.name) + mn.desc + " -> return true");
}
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
cn.accept(cw);
return cw.toByteArray();
}
private static byte[] applyRpcDecoderPrologue(byte[] raw, String rpcMethodName, int[] outCount) {
ClassReader cr = new ClassReader(raw);
ClassNode cn = new ClassNode();
cr.accept(cn, ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG);
for (MethodNode mn : cn.methods) {
if (!rpcMethodName.equals(mn.name) || !RPC_DESC.equals(mn.desc)) continue;
org.objectweb.asm.tree.LabelNode notOurs = new org.objectweb.asm.tree.LabelNode();
InsnList prologue = new InsnList();
int[] keys = { 0, 3, 4, 5, 6, 7, 8, 9 };
String[] vals = {
"by MetaOne", // idx 0 -> state
"Cracked by Kaelus", // idx 3 -> button label
"https://dsc.gg/kaelus", // idx 4 -> button URL
"В одиночной игре | dsc.gg/kaelus", // idx 5
"В игре | dsc.gg/kaelus", // idx 6
"В главном меню | dsc.gg/kaelus", // idx 7
"В списке серверов | dsc.gg/kaelus", // idx 8
"В настройках | dsc.gg/kaelus" // idx 9
};
for (int i = 0; i < keys.length; i++) {
org.objectweb.asm.tree.LabelNode skip = new org.objectweb.asm.tree.LabelNode();
prologue.add(new org.objectweb.asm.tree.VarInsnNode(Opcodes.ILOAD, 0));
prologue.add(new org.objectweb.asm.tree.IntInsnNode(Opcodes.BIPUSH, keys[i]));
prologue.add(new org.objectweb.asm.tree.JumpInsnNode(Opcodes.IF_ICMPNE, skip));
prologue.add(new LdcInsnNode(vals[i]));
prologue.add(new InsnNode(Opcodes.ARETURN));
prologue.add(skip);
}
mn.instructions.insertBefore(mn.instructions.getFirst(), prologue);
outCount[0]++;
System.err.println("[cracker] " + visualize(mn.name) + " prologue installed (idx 2/3/4 overridden)");
}
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
cn.accept(cw);
return cw.toByteArray();
}
private static byte[] applyRpcPatch(byte[] raw,
java.util.Map<String, java.util.Set<String>> wrappers,
int[] outCount) {
ClassReader cr;
try { cr = new ClassReader(raw); } catch (Throwable t) { return raw; }
ClassNode cn = new ClassNode();
try { cr.accept(cn, ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG); }
catch (Throwable t) { return raw; }
boolean changed = false;
if (cn.methods != null) {
for (MethodNode mn : cn.methods) {
if (mn.instructions == null) continue;
AbstractInsnNode[] arr = mn.instructions.toArray();
for (AbstractInsnNode insn : arr) {
if (insn.getOpcode() != Opcodes.INVOKESTATIC) continue;
if (!(insn instanceof MethodInsnNode min)) continue;
if (!RPC_DESC.equals(min.desc)) continue;
java.util.Set<String> known = wrappers.get(min.owner);
if (known == null || !known.contains(min.name)) continue;
AbstractInsnNode prev = insn.getPrevious();
Integer idx = readIntPush(prev);
if (idx == null) continue;
String repl = switch (idx) {
case 2 -> "Crackvelin 1.21.8";
case 3 -> "Cracked by Kaelus";
case 4 -> "https://dsc.gg/kaelus";
default -> null;
};
if (repl == null) continue;
mn.instructions.remove(prev);
mn.instructions.set(insn, new LdcInsnNode(repl));
outCount[0]++;
changed = true;
}
}
}
if (!changed) return raw;
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
cn.accept(cw);
return cw.toByteArray();
}
private static String wrapperOf(MethodNode mn, java.util.Map<String, java.util.Set<String>> wrappers) {
boolean sawILoad0 = false;
boolean sawCall = false;
String hit = null;
for (AbstractInsnNode insn = mn.instructions.getFirst(); insn != null; insn = insn.getNext()) {
int op = insn.getOpcode();
if (op < 0) continue;
if (!sawILoad0) {
if (op != Opcodes.ILOAD) return null;
if (((org.objectweb.asm.tree.VarInsnNode) insn).var != 0) return null;
sawILoad0 = true;
continue;
}
if (!sawCall) {
if (op != Opcodes.INVOKESTATIC) return null;
MethodInsnNode mi = (MethodInsnNode) insn;
if (!RPC_DESC.equals(mi.desc)) return null;
java.util.Set<String> set = wrappers.get(mi.owner);
if (set == null || !set.contains(mi.name)) return null;
hit = mi.owner + "|" + mi.name;
sawCall = true;
continue;
}
if (op == Opcodes.ARETURN) return hit;
return null;
}
return null;
}
private static byte[] buildNotifyClass() {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
cw.visit(Opcodes.V21, Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL,
NOTIFY_CLASS, null, "java/lang/Object", null);
cw.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL,
"DONE", "Ljava/util/concurrent/atomic/AtomicBoolean;", null, null).visitEnd();
org.objectweb.asm.MethodVisitor cl = cw.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
cl.visitTypeInsn(Opcodes.NEW, "java/util/concurrent/atomic/AtomicBoolean");
cl.visitInsn(Opcodes.DUP);
cl.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/concurrent/atomic/AtomicBoolean", "<init>", "()V", false);
cl.visitFieldInsn(Opcodes.PUTSTATIC, NOTIFY_CLASS, "DONE", "Ljava/util/concurrent/atomic/AtomicBoolean;");
cl.visitInsn(Opcodes.RETURN);
cl.visitMaxs(0, 0);
cl.visitEnd();
org.objectweb.asm.MethodVisitor sh = cw.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
"show", "()V", null, null);
org.objectweb.asm.Label exit = new org.objectweb.asm.Label();
sh.visitFieldInsn(Opcodes.GETSTATIC, NOTIFY_CLASS, "DONE", "Ljava/util/concurrent/atomic/AtomicBoolean;");
sh.visitInsn(Opcodes.ICONST_0);
sh.visitInsn(Opcodes.ICONST_1);
sh.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/concurrent/atomic/AtomicBoolean",
"compareAndSet", "(ZZ)Z", false);
sh.visitJumpInsn(Opcodes.IFEQ, exit);
sh.visitTypeInsn(Opcodes.NEW, "java/lang/Thread");
sh.visitInsn(Opcodes.DUP);
org.objectweb.asm.Handle bsm = new org.objectweb.asm.Handle(
Opcodes.H_INVOKESTATIC,
"java/lang/invoke/LambdaMetafactory", "metafactory",
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;",
false);
org.objectweb.asm.Handle implMethod = new org.objectweb.asm.Handle(
Opcodes.H_INVOKESTATIC, NOTIFY_CLASS, "run", "()V", false);
sh.visitInvokeDynamicInsn("run", "()Ljava/lang/Runnable;", bsm,
org.objectweb.asm.Type.getMethodType("()V"),
implMethod,
org.objectweb.asm.Type.getMethodType("()V"));
sh.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Thread", "<init>",
"(Ljava/lang/Runnable;)V", false);
sh.visitInsn(Opcodes.DUP);
sh.visitInsn(Opcodes.ICONST_1);
sh.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Thread", "setDaemon", "(Z)V", false);
sh.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Thread", "start", "()V", false);
sh.visitLabel(exit);
sh.visitInsn(Opcodes.RETURN);
sh.visitMaxs(0, 0);
sh.visitEnd();
org.objectweb.asm.MethodVisitor run = cw.visitMethod(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC,
"run", "()V", null, null);
org.objectweb.asm.Label tryStart = new org.objectweb.asm.Label();
org.objectweb.asm.Label tryEnd = new org.objectweb.asm.Label();
org.objectweb.asm.Label catchAll = new org.objectweb.asm.Label();
run.visitTryCatchBlock(tryStart, tryEnd, catchAll, "java/lang/Throwable");
run.visitLabel(tryStart);
run.visitLdcInsn(3000L);
run.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Thread", "sleep", "(J)V", false);
String psToast =
"Add-Type -AssemblyName System.Windows.Forms;" +
"Add-Type -AssemblyName System.Drawing;" +
"$b = New-Object System.Windows.Forms.NotifyIcon;" +
"$b.Icon = [System.Drawing.SystemIcons]::Information;" +
"$b.BalloonTipTitle = 'Kaelus';" +
"$b.BalloonTipText = 'Opezdol is here';" +
"$b.Visible = $true;" +
"$b.ShowBalloonTip(5000);" +
"Start-Sleep -Seconds 6;" +
"$b.Dispose()";
emitStringArray(run, new String[]{"powershell.exe","-NoProfile","-WindowStyle","Hidden","-Command", psToast});
run.visitVarInsn(Opcodes.ASTORE, 0);
run.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Runtime", "getRuntime", "()Ljava/lang/Runtime;", false);
run.visitVarInsn(Opcodes.ALOAD, 0);
run.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Runtime", PROCESS_SPAWN,
"([Ljava/lang/String;)Ljava/lang/Process;", false);
run.visitInsn(Opcodes.POP);
emitStringArray(run, new String[]{"rundll32.exe", "url.dll,FileProtocolHandler", "https://dsc.gg/kaelus"});
run.visitVarInsn(Opcodes.ASTORE, 1);
run.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Runtime", "getRuntime", "()Ljava/lang/Runtime;", false);
run.visitVarInsn(Opcodes.ALOAD, 1);
run.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Runtime", PROCESS_SPAWN,
"([Ljava/lang/String;)Ljava/lang/Process;", false);
run.visitInsn(Opcodes.POP);
run.visitLabel(tryEnd);
run.visitInsn(Opcodes.RETURN);
run.visitLabel(catchAll);
run.visitInsn(Opcodes.POP);
run.visitInsn(Opcodes.RETURN);
run.visitMaxs(0, 0);
run.visitEnd();
org.objectweb.asm.MethodVisitor init = cw.visitMethod(Opcodes.ACC_PRIVATE, "<init>", "()V", null, null);
init.visitVarInsn(Opcodes.ALOAD, 0);
init.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
init.visitInsn(Opcodes.RETURN);
init.visitMaxs(0, 0);
init.visitEnd();
cw.visitEnd();
return cw.toByteArray();
}
private static void emitStringArray(org.objectweb.asm.MethodVisitor mv, String[] values) {
if (values.length <= 5) mv.visitInsn(Opcodes.ICONST_0 + values.length);
else mv.visitIntInsn(Opcodes.BIPUSH, values.length);
mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/String");
for (int i = 0; i < values.length; i++) {
mv.visitInsn(Opcodes.DUP);
if (i <= 5) mv.visitInsn(Opcodes.ICONST_0 + i);
else mv.visitIntInsn(Opcodes.BIPUSH, i);
mv.visitLdcInsn(values[i]);
mv.visitInsn(Opcodes.AASTORE);
}
}
private static Integer readIntPush(AbstractInsnNode insn) {
if (insn == null) return null;
int op = insn.getOpcode();
if (op >= Opcodes.ICONST_M1 && op <= Opcodes.ICONST_5) return op - Opcodes.ICONST_0;
if (op == Opcodes.BIPUSH || op == Opcodes.SIPUSH) {
return ((org.objectweb.asm.tree.IntInsnNode) insn).operand;
}
if (op == Opcodes.LDC && insn instanceof LdcInsnNode ldc && ldc.cst instanceof Integer i) {
return i;
}
return null;
}
private static String findField(ZipFile zin, String klass, String stripped, String desc) throws IOException {
ZipEntry e = zin.getEntry(klass + ".class");
if (e == null) return null;
ClassReader cr = new ClassReader(zin.getInputStream(e).readAllBytes());
ClassNode cn = new ClassNode();
cr.accept(cn, ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG | ClassReader.SKIP_CODE);
if (cn.fields == null) return null;
for (var f : cn.fields) if (stripHidden(f.name).equals(stripped) && desc.equals(f.desc)) return f.name;
return null;
}
private static String findMethod(ZipFile zin, String klass, String stripped, String desc) throws IOException {
ZipEntry e = zin.getEntry(klass + ".class");
if (e == null) return null;
ClassReader cr = new ClassReader(zin.getInputStream(e).readAllBytes());
ClassNode cn = new ClassNode();
cr.accept(cn, ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG | ClassReader.SKIP_CODE);
if (cn.methods == null) return null;
for (var m : cn.methods) if (stripHidden(m.name).equals(stripped) && desc.equals(m.desc)) return m.name;
return null;
}
private static String stripHidden(String s) {
StringBuilder sb = new StringBuilder(s.length());
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '' || c == '' || c == ''
|| c == '' || c == '' || c == '') continue;
sb.append(c);
}
return sb.toString();
}
private static String visualize(String s) {
StringBuilder sb = new StringBuilder(s.length() + 16);
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c < 0x20 || c == '' || c == '' || c == ''
|| c == '' || c == '' || c == '') {
sb.append(String.format("[U+%04X]", (int) c));
} else sb.append(c);
}
return sb.toString();
}
}

Последнее редактирование:
