A performant, multithreaded DEX to Java bytecode translator, written in kotlin.
It has a similar capabilities as the original EnJarify written in Python (source here).
java -jar kJarify-fat.jar example.apk
void example(File input, File output) {
KJarify.process(inputFile, outputFile, OptimizationOptions.PRETTY);
}
suspend fun example(input: File, output: File) {
KJarify.suspendProcess(input, output, OptimizationOptions.PRETTY)
}
List<byte[]> dexDataList = ...
DexProcessor.ProcessCallBack callback = new DexProcessor.ProcessCallBack() {
@Override
public void onClassTranslated(@NotNull String unicodeName, @NotNull byte[] classData) {
... handle the translated byte codes
}
};
DexProcessor processor = new DexProcessor(
OptimizationOptions.ALL,
Executors.newFixedThreadPool(16),
callback
);
processor.process(dexDataList);
// you can get the result without a callback too
Map<String, byte[]> classDataList = processor.classes;
val dexDataList: List<ByteArray> = ...
val callback = object : DexProcessor.ProcessCallBack() {
override suspend fun suspendOnClassTranslated(unicodeName: String, classData: ByteArray) {
... handle the translated byte codes
}
}
val processor = DexProcessor(
optimizationOptions = OptimizationOptions(
...
),
coroutineDispatcher = Dispatchers.Default,
callback = callback,
)
processor.suspendProcess(dexDataList)
// you can get the result without a callback too
val classDataList: Map<String, ByteArray> = processor.classes
On a 8c/16t 7820X CPU
| DEX size | EnJarify | KJarify |
|---|---|---|
| ~16.6MB | 1min 5s | 5.6s |
| ~94.6MB | 8 min 9s | 37s |