Skip to content

Commit

Permalink
feat: working pure function analysis hash
Browse files Browse the repository at this point in the history
  • Loading branch information
terminalsin committed Nov 25, 2024
1 parent ee95cde commit 3755e1a
Show file tree
Hide file tree
Showing 23 changed files with 1,012 additions and 1,169 deletions.
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ allprojects {
jcenter()
mavenCentral()
mavenLocal()
maven {
url 'https://repo.cleanroommc.com/releases/'
}
}

apply plugin: 'java'
Expand Down
2 changes: 2 additions & 0 deletions dev.skidfuscator.obfuscator.pureanalysis/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ version = '2.0.0-SNAPSHOT'

repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}

dependencies {
api project(':modasm')
api 'com.github.xxDark:SSVM:d559ea90bb'

testImplementation platform('org.junit:junit-bom:5.10.0')
testImplementation 'org.junit.jupiter:junit-jupiter'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,58 +1,12 @@
package dev.skidfuscator.pureanalysis;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class ClassHierarchyAnalyzer {
private final ConcurrentHashMap<String, ClassNode> classCache = new ConcurrentHashMap<>();
private final ClassLoader classLoader;
private final Set<String> analyzedClasses = ConcurrentHashMap.newKeySet();

public ClassHierarchyAnalyzer(ClassLoader classLoader) {
this.classLoader = classLoader;
}

public ClassNode getClass(String className) throws IOException {
return classCache.computeIfAbsent(className, this::loadClass);
}

private ClassNode loadClass(String className) {
try {
ClassReader reader = new ClassReader(classLoader.getResourceAsStream(
className.replace('.', '/') + ".class"));
ClassNode classNode = new ClassNode();
reader.accept(classNode, ClassReader.EXPAND_FRAMES);
return classNode;
} catch (IOException e) {
throw new RuntimeException("Failed to load class: " + className, e);
}
}

public Set<String> getAllSuperClasses(String className) throws IOException {
Set<String> superClasses = new HashSet<>();
collectSuperClasses(className, superClasses);
return superClasses;
}

private void collectSuperClasses(String className, Set<String> collected) throws IOException {
if (className == null || className.equals("java/lang/Object")) return;

ClassNode classNode = getClass(className);
collected.add(className);

// Collect superclass
if (classNode.superName != null) {
collectSuperClasses(classNode.superName, collected);
}

// Collect interfaces
for (String interfaceName : classNode.interfaces) {
collectSuperClasses(interfaceName, collected);
}
}
}
public interface ClassHierarchyAnalyzer {
ClassNode getClass(String className) throws IOException;

Set<String> getAllSuperClasses(String className) throws IOException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package dev.skidfuscator.pureanalysis;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class SimpleClassHierarchyAnalyzer implements ClassHierarchyAnalyzer {
private final ConcurrentHashMap<String, ClassNode> classCache = new ConcurrentHashMap<>();
private final ClassLoader classLoader;
private final Set<String> analyzedClasses = ConcurrentHashMap.newKeySet();

public SimpleClassHierarchyAnalyzer(ClassLoader classLoader) {
this.classLoader = classLoader;
}

@Override
public ClassNode getClass(String className) throws IOException {
return classCache.computeIfAbsent(className, this::loadClass);
}

private ClassNode loadClass(String className) {
try {
ClassReader reader = new ClassReader(classLoader.getResourceAsStream(
className.replace('.', '/') + ".class"));
ClassNode classNode = new ClassNode();
reader.accept(classNode, ClassReader.EXPAND_FRAMES);
return classNode;
} catch (IOException e) {
throw new RuntimeException("Failed to load class: " + className, e);
}
}

@Override
public Set<String> getAllSuperClasses(String className) throws IOException {
Set<String> superClasses = new HashSet<>();
collectSuperClasses(className, superClasses);
return superClasses;
}

private void collectSuperClasses(String className, Set<String> collected) throws IOException {
if (className == null || className.equals("java/lang/Object")) return;

ClassNode classNode = getClass(className);
collected.add(className);

// Collect superclass
if (classNode.superName != null) {
collectSuperClasses(classNode.superName, collected);
}

// Collect interfaces
for (String interfaceName : classNode.interfaces) {
collectSuperClasses(interfaceName, collected);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package dev.skidfuscator.pureanalysis.vm;

import org.objectweb.asm.Type;
import org.objectweb.asm.tree.MethodNode;

public class VirtualMachinery {


public static class VirtualMachineReport {
private MethodNode method;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import dev.skidfuscator.pureanalysis.ClassHierarchyAnalyzer;
import dev.skidfuscator.pureanalysis.PurityAnalyzer;
import dev.skidfuscator.pureanalysis.PurityReport;
import dev.skidfuscator.pureanalysis.SimpleClassHierarchyAnalyzer;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.objectweb.asm.ClassReader;
Expand All @@ -23,7 +23,7 @@ public class JVMPurityAnalyzerTest {

@BeforeEach
void setUp() {
analyzer = new PurityAnalyzer(new ClassHierarchyAnalyzer(
analyzer = new PurityAnalyzer(new SimpleClassHierarchyAnalyzer(
getClass().getClassLoader())
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package framework;

import dev.skidfuscator.pureanalysis.ClassHierarchyAnalyzer;
import dev.skidfuscator.pureanalysis.PurityAnalyzer;
import dev.skidfuscator.pureanalysis.PurityReport;
import dev.skidfuscator.pureanalysis.SimpleClassHierarchyAnalyzer;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import org.objectweb.asm.ClassReader;
Expand Down Expand Up @@ -35,7 +35,7 @@ public class PurityAnalysisTest {
private final MemoryClassLoader classLoader = new MemoryClassLoader();

public PurityAnalysisTest() {
this.analyzer = new PurityAnalyzer(new ClassHierarchyAnalyzer(classLoader));
this.analyzer = new PurityAnalyzer(new SimpleClassHierarchyAnalyzer(classLoader));
setupAnalyzer();
}

Expand Down
2 changes: 2 additions & 0 deletions dev.skidfuscator.obfuscator/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ dependencies {
compileOnly 'org.projectlombok:lombok:1.18.24'

api project(':commons')
api project(':pure-analysis')

implementation 'com.github.lukfor:magic-progress:0.3.2'
implementation 'com.github.matomo-org:matomo-java-tracker:v1.7'
api 'com.github.Col-E:jphantom:1.4.3'
Expand Down
Loading

0 comments on commit 3755e1a

Please sign in to comment.