Skip to content

Commit

Permalink
Initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
RealAlphabet committed Jun 20, 2021
0 parents commit a988710
Show file tree
Hide file tree
Showing 9 changed files with 209 additions and 0 deletions.
15 changes: 15 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Ignore everything
*
!*/

# Expect sources and libs
!*.java
!*.jar
!MANIFEST.MF

# Except Git
!.gitignore
!*.md

# Expect Makefile
!Makefile
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Abstractor

Try to steal my Minecraft server's API now. 😘
Binary file added lib/asm-all-5.2.jar
Binary file not shown.
3 changes: 3 additions & 0 deletions src/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: com.alphabet.abstractor.Main

23 changes: 23 additions & 0 deletions src/com/alphabet/abstractor/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.alphabet.abstractor;

import com.alphabet.abstractor.utils.Loader;
import com.alphabet.abstractor.utils.MethodModifier;
import com.alphabet.abstractor.utils.Saver;

import java.io.File;
import java.io.IOException;
import java.util.Map;

public class Main {

public static void main(String[] args) throws IOException {
if (args.length < 1)
System.out.println("java -jar abstractor.jar [jar]");

else {
Map<String, MethodModifier> classesMap = Loader.loadClasses(new File(args[0]));
Map<String, byte[]> bytesMap = Saver.processNodes(classesMap);
Saver.saveAsJar(bytesMap, "output.jar");
}
}
}
60 changes: 60 additions & 0 deletions src/com/alphabet/abstractor/utils/Loader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.alphabet.abstractor.utils;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.stream.Stream;

public class Loader {

public static Map<String, MethodModifier> loadClasses(File jarFile) throws IOException {
Map<String, MethodModifier> classes = new HashMap<>();

try (JarFile jar = new JarFile(jarFile); Stream<JarEntry> str = jar.stream()) {
str.forEach(entry -> readJar(jar, entry, classes));
}

return classes;
}

private static Map<String, MethodModifier> readJar(JarFile jar, JarEntry entry, Map<String, MethodModifier> classes) {
String name = entry.getName();

try (InputStream is = jar.getInputStream(entry)) {
if (name.endsWith(".class")) {
try {
MethodModifier methodReplacer = getReplacer(is);

if (methodReplacer.shouldIgnore)
return classes;

classes.put(name, methodReplacer);

} catch (Exception e) {
e.printStackTrace();
}
}

} catch (IOException e) {
e.printStackTrace();
}

return classes;
}

private static MethodModifier getReplacer(InputStream stream) throws IOException {
ClassReader classReader = new ClassReader(stream);
ClassWriter classWriter = new ClassWriter(0);
MethodModifier methodReplacer = new MethodModifier(classWriter);

classReader.accept(methodReplacer, 0);
return methodReplacer;
}
}
42 changes: 42 additions & 0 deletions src/com/alphabet/abstractor/utils/MethodModifier.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.alphabet.abstractor.utils;

import org.objectweb.asm.*;

public class MethodModifier extends ClassVisitor {

public boolean shouldIgnore;

MethodModifier(ClassWriter writer) {
super(Opcodes.ASM5, writer);
}

@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
if ((access & Opcodes.ACC_PUBLIC) == 0)
shouldIgnore = true;
else
super.visit(version, access, name, signature, superName, interfaces);
}

@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
if ((access & Opcodes.ACC_PUBLIC) == 0)
return null;

return new ReplacerMethod(
Type.getReturnType(desc),
super.visitMethod(access, name, desc, signature, exceptions));
}

@Override
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
if ((access & Opcodes.ACC_PUBLIC) == 0)
return null;

return super.visitField(access, name, desc, signature, value);
}

public byte[] toByteArray() {
return ((ClassWriter) this.cv).toByteArray();
}
}
30 changes: 30 additions & 0 deletions src/com/alphabet/abstractor/utils/ReplacerMethod.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.alphabet.abstractor.utils;

import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

public class ReplacerMethod extends MethodVisitor {

private final Type returnType;
private final MethodVisitor targetWriter;

ReplacerMethod(Type returnType, MethodVisitor writer) {
super(Opcodes.ASM5);
this.returnType = returnType;
this.targetWriter = writer;
}

@Override
public void visitCode() {
targetWriter.visitCode();

if (returnType == Type.VOID_TYPE)
targetWriter.visitInsn(Opcodes.RETURN);

else {
targetWriter.visitInsn(Opcodes.ACONST_NULL);
targetWriter.visitInsn(Opcodes.ARETURN);
}
}
}
33 changes: 33 additions & 0 deletions src/com/alphabet/abstractor/utils/Saver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.alphabet.abstractor.utils;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;

public class Saver {

public static Map<String, byte[]> processNodes(Map<String, MethodModifier> replacerMap) {
Map<String, byte[]> out = new HashMap<>();

for (Map.Entry<String, MethodModifier> entry : replacerMap.entrySet())
out.put(entry.getKey(), entry.getValue().toByteArray());

return out;
}

public static void saveAsJar(Map<String, byte[]> outBytes, String fileName) {
try (JarOutputStream out = new JarOutputStream(new FileOutputStream(fileName))) {
for (String entry : outBytes.keySet()) {
out.putNextEntry(new ZipEntry(entry));
out.write(outBytes.get(entry));
out.closeEntry();
}

} catch (IOException e) {
e.printStackTrace();
}
}
}

0 comments on commit a988710

Please sign in to comment.