Skip to content

Commit

Permalink
feat: JS wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
zlataovce committed Aug 14, 2024
1 parent 5156eb9 commit e51c7da
Show file tree
Hide file tree
Showing 13 changed files with 255 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ plugins {
}

group = "run.slicer"
version = "1.0.0-SNAPSHOT"
version = "1.0.0"
description = "A Java library for performing bytecode normalization and generic deobfuscation."

repositories {
Expand Down
3 changes: 3 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
[versions]
picocli = "4.7.6"
teavm = "0.10.0"

[libraries]
jspecify = { group = "org.jspecify", name = "jspecify", version = "0.3.0" }
picocli = { group = "info.picocli", name = "picocli", version.ref = "picocli" }
picocli-codegen = { group = "info.picocli", name = "picocli-codegen", version.ref = "picocli" }
proguard = { group = "com.github.run-slicer", name = "proguard", version = "82ace0a065" }
teavm-core = { group = "org.teavm", name = "teavm-core", version.ref = "teavm" }

[plugins]
shadow = { id = "com.gradleup.shadow", version = "8.3.0" }
blossom = { id = "net.kyori.blossom", version = "2.1.0" }
teavm = { id = "org.teavm", version.ref = "teavm" }
1 change: 1 addition & 0 deletions js/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist/
51 changes: 51 additions & 0 deletions js/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
plugins {
id("poke.base-conventions")
alias(libs.plugins.teavm)
}

dependencies {
implementation(project(":${rootProject.name}-core"))
compileOnly(libs.teavm.core)
}

teavm.js {
mainClass = "run.slicer.poke.js.Main"
moduleType = org.teavm.gradle.api.JSModuleType.ES2015
// obfuscated = false
// optimization = org.teavm.gradle.api.OptimizationLevel.NONE
}

tasks {
register<Copy>("copyDist") {
group = "build"

from("../README.md", "../LICENSE", generateJavaScript, "poke.d.ts")
into("dist")

doLast {
file("dist/package.json").writeText(
"""
{
"name": "@run-slicer/poke",
"version": "${project.version}",
"description": "A library for performing Java bytecode normalization and generic deobfuscation.",
"main": "poke-js.js",
"types": "poke.d.ts",
"keywords": [
"deobfuscation",
"java",
"bytecode",
"optimization"
],
"author": "run-slicer",
"license": "GPL-2.0-only"
}
""".trimIndent()
)
}
}

build {
dependsOn("copyDist")
}
}
9 changes: 9 additions & 0 deletions js/poke.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
declare module "@run-slicer/poke" {
export interface Config {
passes?: number;
optimize?: boolean;
verify?: boolean;
}

export function analyze(data: Uint8Array, config?: Config): Uint8Array;
}
23 changes: 23 additions & 0 deletions js/src/main/java/run/slicer/poke/js/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package run.slicer.poke.js;

import org.teavm.jso.JSByRef;
import org.teavm.jso.JSExport;
import org.teavm.jso.core.JSObjects;
import run.slicer.poke.Analyzer;

public class Main {
@JSExport
public static @JSByRef byte[] analyze(@JSByRef byte[] data, Options options) {
return analyze0(data, options == null || JSObjects.isUndefined(options) ? JSObjects.create() : options);
}

private static byte[] analyze0(byte[] data, Options options) {
final Analyzer analyzer = Analyzer.builder()
.passes(options.passes())
.optimize(options.optimize())
.verify(options.verify())
.build();

return analyzer.analyze(data);
}
}
15 changes: 15 additions & 0 deletions js/src/main/java/run/slicer/poke/js/Options.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package run.slicer.poke.js;

import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;

public interface Options extends JSObject {
@JSBody(script = "return this.passes || 0;")
int passes();

@JSBody(script = "return Boolean(this.optimize);")
boolean optimize();

@JSBody(script = "return Boolean(this.verify);")
boolean verify();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package run.slicer.poke.js.teavm.classlib.java.util.concurrent;

import java.util.Collection;
import java.util.List;
import java.util.concurrent.*;

final class DummyExecutorService implements ExecutorService {
private boolean shutdown = false;

@Override
public void shutdown() {
this.shutdown = true;
}

@Override
public List<Runnable> shutdownNow() {
this.shutdown = true;
return List.of();
}

@Override
public boolean isShutdown() {
return this.shutdown;
}

@Override
public boolean isTerminated() {
return this.shutdown;
}

@Override
public boolean awaitTermination(long timeout, TimeUnit unit) {
return true;
}

@Override
public <T> Future<T> submit(Callable<T> task) {
try {
return new Task<>(task.call(), null);
} catch (Throwable t) {
return new Task<>(null, t);
}
}

@Override
public <T> Future<T> submit(Runnable task, T result) {
try {
task.run();
} catch (Throwable t) {
return new Task<>(null, t);
}

return new Task<>(result, null);
}

@Override
public Future<?> submit(Runnable task) {
try {
task.run();
} catch (Throwable t) {
return new Task<>(null, t);
}

return new Task<>(null, null);
}

@Override
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) {
throw new UnsupportedOperationException();
}

@Override
public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) {
throw new UnsupportedOperationException();
}

@Override
public <T> T invokeAny(Collection<? extends Callable<T>> tasks) {
throw new UnsupportedOperationException();
}

@Override
public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) {
throw new UnsupportedOperationException();
}

@Override
public void execute(Runnable command) {
command.run();
}

private record Task<T>(T value, Throwable error) implements Future<T> {
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return false;
}

@Override
public boolean isCancelled() {
return false;
}

@Override
public boolean isDone() {
return true;
}

@Override
public T get() throws ExecutionException {
if (this.error != null) {
throw new ExecutionException(this.error);
}

return this.value;
}

@Override
public T get(long timeout, TimeUnit unit) throws ExecutionException {
return this.get();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package run.slicer.poke.js.teavm.classlib.java.util.concurrent;

import java.util.concurrent.Executor;

public interface TExecutorService extends Executor {
TFuture<?> submit(Runnable task);

void shutdown();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package run.slicer.poke.js.teavm.classlib.java.util.concurrent;

import java.util.concurrent.ThreadFactory;

public class TExecutors {
@SuppressWarnings("DataFlowIssue")
public static TExecutorService newFixedThreadPool(int ignored0, ThreadFactory ignored1) {
return (TExecutorService) ((Object) new DummyExecutorService());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package run.slicer.poke.js.teavm.classlib.java.util.concurrent;

import java.util.concurrent.ExecutionException;

public interface TFuture<V> {
V get() throws InterruptedException, ExecutionException;
}
3 changes: 3 additions & 0 deletions js/src/teavm/resources/META-INF/teavm.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mapClass|run.slicer.poke.js.teavm.classlib.java.util.concurrent.TExecutors=java.util.concurrent.Executors
mapClass|run.slicer.poke.js.teavm.classlib.java.util.concurrent.TExecutorService=java.util.concurrent.ExecutorService
mapClass|run.slicer.poke.js.teavm.classlib.java.util.concurrent.TFuture=java.util.concurrent.Future
2 changes: 1 addition & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ fun includePrefixed(vararg modules: String) {
}
}

includePrefixed("core", "cli")
includePrefixed("core", "cli", "js")

0 comments on commit e51c7da

Please sign in to comment.