
Descompilador, montador e desmontador de Java
Krakatau fornece um assembler e disassembler para bytecode Java, que permite converter classfiles binários para um formato de texto legível por humanos, fazer alterações e convertê-los de volta para um classfile, mesmo para código ofuscado. Você também pode criar seus próprios classfiles do zero escrevendo bytecode manualmente, e pode examinar e comparar detalhes de baixo nível de binários Java. Ao contrário do javap, o disassembler do Krakatau pode lidar até mesmo com código altamente ofuscado, e a saída desassemblada pode ser remontada em um classfile.
Krakatau também fornece um decompiler para converter binários Java em código-fonte legível. Ao contrário de outros decompilers, o decompiler do Krakatau foi especificamente projetado para trabalhar com código ofuscado e pode facilmente lidar com truques que quebram outros decompilers. No entanto, o decompiler do Krakatau não suporta alguns recursos do Java 8+ como lambdas, então funciona melhor em código mais antigo.
A sintaxe do assembler do Krakatau é principalmente um superconjunto da sintaxe Jasmin, com algumas pequenas incompatibilidades, mas ao contrário do Jasmin, o Krakatau tem suporte completo para a especificação de bytecode Java 19 e até suporta alguns recursos não documentados encontrados em versões antigas da JVM. Para uma visão geral da sintaxe do assembler, veja o tutorial ou a especificação completa.
Primeiro, você precisará instalar Rust e Cargo. Em seguida, clone este repositório e execute cargo build --release. Isso produzirá um binário em target/release/krak2, que você pode chamar diretamente, adicionar ao PATH, criar link simbólico, etc.
O desmontador tem dois modos: padrão e roundtrip. O modo padrão é otimizado para legibilidade e facilidade de modificação dos arquivos assembly resultantes. Quando a saída é remontada, resultará em classfiles que são equivalentes em comportamento ao original do ponto de vista da especificação JVM, mas não necessariamente idênticos bit a bit (por exemplo, as entradas do constant pool podem ser reordenadas). O modo roundtrip produz saída que será remontada em classfiles bit a bit idênticos ao original, mas isso significa que os arquivos assembly preservam informações de codificação de baixo nível que os tornam mais difíceis de ler, como a ordem exata das entradas do constant pool. Recomenda-se usar o modo roundtrip ao trabalhar com código que depende de atributos não padronizados, como código CLDC ou código Scala.
Exemplo de uso:
krak2 dis --out temp RecordTest.class
krak2 dis --out disassembled.zip --roundtrip r0lling-challenge.jar
Você pode desmontar um classfile individual ou um arquivo jar inteiro. Se o nome do arquivo de entrada terminar em .jar ou .zip, ele será tratado como um arquivo jar e todos os arquivos .class dentro do jar serão desmontados.
A opção --out controla o local de saída. Se o valor de --out for um diretório, a saída será colocada em arquivos individuais nesse diretório. Caso contrário, se o valor de --out terminar em .jar ou .zip, a saída será colocada em um único arquivo zip nesse local. Se o valor de --out terminar com .j, a saída será escrita nesse arquivo (note que um único arquivo .j pode conter várias classes - todas as classes serão desmontadas e escritas no mesmo arquivo, uma após a outra). Se a opção --out for omitida, as classes desmontadas serão escritas na saída padrão.
Para desmontar no modo roundtrip conforme descrito acima, passe a opção --roundtrip (ou -r para abreviar).
O assembler do Krakatau permite que você escreva bytecode Java em um formato baseado em texto amigável e convertê-lo em classfiles Java binários.
krak2 asm --out temp Krakatau/tests/assembler/good/strictfp.j
Você pode montar um arquivo .j individual ou um arquivo jar inteiro. Se o nome do arquivo de entrada terminar em .jar ou .zip, ele será tratado como um arquivo zip e todos os arquivos .j dentro serão montados.
A opção --out controla o local de saída. Se o valor de --out for um diretório, a saída será colocada em arquivos individuais nesse diretório. Caso contrário, se o valor de --out terminar em .jar ou .zip, a saída será colocada em um único arquivo zip nesse local. Se o valor de --out terminar com .class, o único arquivo classfile de saída será escrito nesse arquivo (se a entrada tiver várias classes, ocorrerá um erro neste caso).
O decompiler v2 ainda está em desenvolvimento. Para decompilação, atualmente você precisa usar o Krakatau v1.