Então... Estou tentando descompilar o IRPF2007.zip pra ter código fonte, de modo a poder distribuir uma versão livre que eu mesmo possa usar pra preparar minha declaração.

Tentei primeiro o JReversePro 1.4.1, mas o resultado foi meio mais ou menos, quase nada compilava de volta :-(

Deu pra ver o jeitão do Crc32, o "algoritmo secreto" de hashing que a Receita Federal usa pra verificar a consistência de cada linha da declaração (vai um hash, o NR_CONTROLE, nos últimos 10 caracteres de cada linha), assim como da declaração e do recibo como um todo (o campo NR_HASH da especificação).

Meu plano era gerar a declaração na mão, mas estudando a fundo o jeitão do arquivo, cheguei à conclusão que ia dar trabalho demais :-( O negócio arquivo definitivamente não foi feito pra ser gerado na mão.

Então voltei a explorar os descompiladores. Achei o JODE, que fez um trabalho um tanto melhor. Após ?alguns patches, consegui compilar o branch 1.1 do repositório SVN usando o gcj do Fedora pre-7:

svn co -r 1046 https://jode.svn.sourceforge.net/svnroot/jode/branches/branch_1_1/jode jode-1.1
cd jode-1.1
patch -p0 < ../irpf-jode-1.1-r1046.patch
aclocal && automake -a && autoconf
PATH=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre/bin:$PATH
CLASSPATH=/usr/share/java/gnu-getopt-1.0.12.jar CLASSLIB=/usr/share/java/libgcj-4.1.2.jar JAVAC=/usr/bin/ecj JAR=/usr/bin/fastjar ./configure
gcj -O2 -c /usr/share/java/gnu-getopt-1.0.12.jar 
gcj jode/decompiler/*.java jode/bytecode/*.java jode/jvm/*.java jode/expr/*.java jode/flow/*.java jode/type/*.java jode/util/*.java jode/*.java -I/usr/share/java/gnu-getopt-1.0.12.jar gnu-getopt-1.0.12.o -g --main=jode.decompiler.Main -o ../jode.bin -O3

E aí eu já conseguia descompilar tudo que interessava no IRPF.jar que estava no ?arquivo .ZIP que a Receita Federal costumava distribuir, antes de re-publicar o arquivo com opções de ofuscamento de código e sem informação de debugging, pra depois dizer pra gente que não podia mudar o que tava no site nem pra resolver o problema de violação de licenças. Sorte que eu tinha guardado o arquivo antigo, né?

unzip -d IRPF irpf2007v1.0.zip
.../jode.bin -w 0 -d irpf -classpath IRPF/jhall.jar:/usr/share/java/libgcj-4.1.2.jar -s gnu IRPF/IRPF.jar

O -w 0 não é absolutamente essencial, mas o algoritmo que introduz quebras de linhas e indentação em linhas muito longas é exponencial e tem umas linhas bem longas em alguns dos arquivos fonte. Não tive paciência pra esperar terminar sem isso, e acabei introduzindo a opção -w pra resolver esse problema.

Agora, o pé em que estou é o seguinte: tenho fontes que precisam ser um tanto massageados pra funcionarem, preciso localizar os fontes dos pacotes originais que a Receita Federal usa, e, mais importante de tudo, fazer o todo funcionar, seja no Kaffe, seja no GCJ. No momento, o GCJ está parecendo bem mais promissor. A versão do Fedora 6 dava mais ou menos o mesmo problema que o Kaffe 1.1.7, provavelmente por causa de limitações no GNU Classpath, mas a versão do Fedora 7 está mais promissora: a tela principal se abre e os menus parecem funcionar. Woohoo!

Quanto a massagear os fontes, um dos grandes problemas é que expressões do tipo <nome.de.alguma>.class são traduzidas pelo compilador para um campo estático de nome class$<número>. Tipo, olha o que o descompilador gerou pro corpo do construtor:

public ColecaoEspecie ()
{
    ColecaoEspecie colecaoespecie = this;
    Class var_class = class$0;
    if (var_class == null)
        {
            Class var_class_0_;
            try
                {
                    var_class_0_ = Class.forName ("serpro.ppgd.irpf.moedaestrangeira.especie.ItemDadosEspecie");
                }
            catch (ClassNotFoundException classnotfoundexception)
                {
                    NoClassDefFoundError noclassdeffounderror = new NoClassDefFoundError;
                    ((UNCONSTRUCTED)noclassdeffounderror).NoClassDefFoundError (classnotfoundexception.getMessage ());
                    throw noclassdeffounderror;
                }
            var_class = class$0 = var_class_0_;
        }
    ((UNCONSTRUCTED)colecaoespecie).ColecaoItensGCapME (var_class);
}

em vez do que presumivelmente estava no original:

public ColecaoEspecie () {
    super(serpro.ppgd.irpf.moedaestrangeira.especie.ItemDadosEspecie.class);
}

O outro problema que já detectei foi com algumas exceções. Alguns métodos são descompilados para um corpo como:

{
    exception = exception_<número>_;
    break while_<número>_;
}

Ainda não investiguei isso; não sei se tem código sendo jogado fora, se isso é só um pass-through de exceções, ou se tem alguma coisa esquisita rolando.

Outros dois arquivos deixam de compilar por referências às classes com.sun.image.codec.jpeg.JPEGCodec e com.sun.image.codec.jpeg.JPEGImageDecoder.

Uns 4 outros arquivos contêm a frase "MISSING MONITORENTER", o que provavelmente significa que o descompilador se perdeu num synchronized.

Bom, acho que é mais ou menos isso. Fora esses errinhos, que ainda não decidi se vale a pena tentar consertar no descompilador ou através de scripts ou na mão mesmo, o que falta é localizar os fontes correspondentes às bibliotecas livres usadas pela SRF e fazer o programa funcionar sem o que não for livre.

Tá parecendo factível nesta semana, antes de estourar o prazo do 30 de abril... Ainda mais se você ajudar, em softwares-impostos@fsfla.org ;-)

Os fontes estão em https://www.fsfla.org/svn/fsfla/blogs/lxo/software/irpf2007-livre/

Até blogo...