Skip to content

Commit

Permalink
feat: disassembly
Browse files Browse the repository at this point in the history
  • Loading branch information
zlataovce committed Sep 13, 2024
1 parent 6730dbc commit 4c92103
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 21 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# script-krak

A slicer script binding for the Krakatau Java decompiler.
A slicer script binding for the Krakatau Java decompiler and disassembler.
13 changes: 10 additions & 3 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -350,17 +350,24 @@ const krak = {
id: "krak",
label: "Krakatau",
language: "java",
run: worker.run,
run: worker.decompile,
};
const krakAsm = {
id: "krak-asm",
label: "Krakatau (ASM)",
run: worker.disassemble,
};
var index = {
name: "krak",
description: "A script binding for the Krakatau Java decompiler.",
version: "1.1.1",
description: "A script binding for the Krakatau Java decompiler and disassembler.",
version: "1.2.0",
load(context) {
context.disasm.add(krak);
context.disasm.add(krakAsm);
},
unload(context) {
context.disasm.remove(krak.id);
context.disasm.remove(krakAsm.id);
},
};

Expand Down
36 changes: 30 additions & 6 deletions dist/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -336,9 +336,11 @@ function generateUUID() {
}

const krakScript = `from pyodide.http import pyfetch
response = await pyfetch("https://cdn.jsdelivr.net/gh/run-slicer/script-krak@${"1.1.1"}/dist/krak.zip")
response = await pyfetch("https://cdn.jsdelivr.net/gh/run-slicer/script-krak@${"1.2.0"}/dist/krak.zip")
await response.unpack_archive()
from io import StringIO
from Krakatau.java.visitor import DefaultVisitor
from Krakatau.java.javaclass import generateAST
from Krakatau.ssa import ssaFromVerified
Expand All @@ -347,6 +349,8 @@ from Krakatau.java.stringescape import escapeString
from Krakatau.environment import Environment
from Krakatau.classfile import ClassFile
from Krakatau.classfileformat.reader import Reader
from Krakatau.classfileformat.classdata import ClassData
from Krakatau.assembler.disassembly import Disassembler
def makeGraph(m):
v = verifyBytecode(m.code)
Expand Down Expand Up @@ -389,15 +393,35 @@ def decompile(data):
return source
decompile`;
def disassemble(data):
c = ClassData(Reader(data=bytes(data.to_py())))
output = StringIO()
Disassembler(c, output.write, roundtrip=False).disassemble()
return output.getvalue()`;
let decompileFunc = null;
let disassembleFunc = null;
const loadFuncs = async () => {
await import('https://cdn.jsdelivr.net/pyodide/v0.26.2/full/pyodide.mjs')
.then(({ loadPyodide }) => loadPyodide({ indexURL: "https://cdn.jsdelivr.net/pyodide/v0.26.2/full/" }))
.then(async ({ runPythonAsync, globals }) => {
await runPythonAsync(krakScript);
decompileFunc = globals.get("decompile");
disassembleFunc = globals.get("disassemble");
});
};
expose({
async run(data) {
async decompile(data) {
if (!decompileFunc) {
decompileFunc = await import('https://cdn.jsdelivr.net/pyodide/v0.26.2/full/pyodide.mjs')
.then(({ loadPyodide }) => loadPyodide({ indexURL: "https://cdn.jsdelivr.net/pyodide/v0.26.2/full/" }))
.then(({ runPythonAsync }) => runPythonAsync(krakScript));
await loadFuncs();
}
return decompileFunc(data);
},
async disassemble(data) {
if (!disassembleFunc) {
await loadFuncs();
}
return disassembleFunc(data);
},
});
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "script-krak",
"version": "1.1.1",
"version": "1.2.0",
"type": "module",
"author": "run-slicer",
"license": "GPL-3.0-only",
"description": "A slicer script binding for the Krakatau Java decompiler.",
"description": "A slicer script binding for the Krakatau Java decompiler and disassembler.",
"scripts": {
"prepare": "mkdir -p dist; cd Krakatau; find Krakatau LICENSE.TXT -name \"*.py\" -o -name \"LICENSE.TXT\" | zip -FS -@ ../dist/krak.zip",
"build": "rollup --config rollup.config.ts --configPlugin @rollup/plugin-typescript",
Expand Down
12 changes: 10 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,25 @@ const krak: Disassembler = {
id: "krak",
label: "Krakatau",
language: "java",
run: worker.run,
run: worker.decompile,
};

const krakAsm: Disassembler = {
id: "krak-asm",
label: "Krakatau (ASM)",
run: worker.disassemble,
};

export default {
name: "krak",
description: "A script binding for the Krakatau Java decompiler.",
description: "A script binding for the Krakatau Java decompiler and disassembler.",
version: __SCRIPT_VERSION__,
load(context: ScriptContext): void | Promise<void> {
context.disasm.add(krak);
context.disasm.add(krakAsm);
},
unload(context: ScriptContext): void | Promise<void> {
context.disasm.remove(krak.id);
context.disasm.remove(krakAsm.id);
},
} satisfies Script;
44 changes: 37 additions & 7 deletions src/worker.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { expose } from "comlink";

export interface Worker {
run(data: Uint8Array): Promise<string>;
decompile(data: Uint8Array): Promise<string>;
disassemble(data: Uint8Array): Promise<string>;
}

const krakScript = `from pyodide.http import pyfetch
response = await pyfetch("https://cdn.jsdelivr.net/gh/run-slicer/script-krak@${__SCRIPT_VERSION__}/dist/krak.zip")
await response.unpack_archive()
from io import StringIO
from Krakatau.java.visitor import DefaultVisitor
from Krakatau.java.javaclass import generateAST
from Krakatau.ssa import ssaFromVerified
Expand All @@ -16,6 +19,8 @@ from Krakatau.java.stringescape import escapeString
from Krakatau.environment import Environment
from Krakatau.classfile import ClassFile
from Krakatau.classfileformat.reader import Reader
from Krakatau.classfileformat.classdata import ClassData
from Krakatau.assembler.disassembly import Disassembler
def makeGraph(m):
v = verifyBytecode(m.code)
Expand Down Expand Up @@ -58,18 +63,43 @@ def decompile(data):
return source
decompile`;
def disassemble(data):
c = ClassData(Reader(data=bytes(data.to_py())))
output = StringIO()
Disassembler(c, output.write, roundtrip=False).disassemble()
return output.getvalue()`;

type KrakFunc = (data: Uint8Array) => string;

let decompileFunc: KrakFunc | null = null;
let disassembleFunc: KrakFunc | null = null;

let decompileFunc: ((data: Uint8Array) => string) | null = null;
const loadFuncs = async () => {
await import("https://cdn.jsdelivr.net/pyodide/v0.26.2/full/pyodide.mjs")
.then(({ loadPyodide }) => loadPyodide({ indexURL: "https://cdn.jsdelivr.net/pyodide/v0.26.2/full/" }))
.then(async ({ runPythonAsync, globals }) => {
await runPythonAsync(krakScript);

decompileFunc = globals.get("decompile");
disassembleFunc = globals.get("disassemble");
});
};

expose({
async run(data: Uint8Array): Promise<string> {
async decompile(data: Uint8Array): Promise<string> {
if (!decompileFunc) {
decompileFunc = await import("https://cdn.jsdelivr.net/pyodide/v0.26.2/full/pyodide.mjs")
.then(({ loadPyodide }) => loadPyodide({ indexURL: "https://cdn.jsdelivr.net/pyodide/v0.26.2/full/" }))
.then(({ runPythonAsync }) => runPythonAsync(krakScript));
await loadFuncs();
}

return decompileFunc(data);
},
async disassemble(data: Uint8Array): Promise<string> {
if (!disassembleFunc) {
await loadFuncs();
}

return disassembleFunc(data);
},
} satisfies Worker);

0 comments on commit 4c92103

Please sign in to comment.