Storyyeller / Krakatau

Java decompiler, assembler, and disassembler
GNU General Public License v3.0
1.95k stars 219 forks source link

False, uncompilable casts added #164

Closed Janmm14 closed 4 years ago

Janmm14 commented 4 years ago

I came across a method where Krakatau is putting out slightly wrong code. Here is the Krakatau disassemble of it (in a clean, new class): https://gist.github.com/Janmm14/8deb94d88082d21e591b24a49d6988c8

Krakatau is adding boolean casts before the array accesses at the xor stuff during decompilation:

    {
        String s0 = null;
        try
        {
            char[] a = s.toCharArray();
            char[] a0 = new char[a.length];
            char[] a1 = new char[10];
            a1[0] = (char)18482;
            a1[1] = (char)9093;
            a1[2] = (char)9094;
            a1[3] = (char)38931;
            a1[4] = (char)37157;
            a1[5] = (char)17794;
            a1[6] = (char)2323;
            a1[7] = (char)13346;
            a1[8] = (char)2131;
            a1[9] = (char)1828;
            char[] a2 = new char[10];
            a2[0] = (char)18464;
            a2[1] = (char)33795;
            a2[2] = (char)34643;
            a2[3] = (char)14338;
            a2[4] = (char)14400;
            a2[5] = (char)14484;
            a2[6] = (char)34617;
            a2[7] = (char)4152;
            a2[8] = (char)33540;
            a2[9] = (char)13107;
            int i = 0;
            while(i < a.length)
            {
                int i0 = (char)((boolean)a[i] ^ (boolean)a2[i % a2.length]);
                a0[i] = (char)i0;
                i = i + 1;
            }
            char[] a3 = new char[a0.length];
            int i1 = 0;
            while(i1 < a.length)
            {
                int i2 = (char)((boolean)a0[i1] ^ (boolean)a1[i1 % a1.length]);
                a3[i1] = (char)i2;
                i1 = i1 + 1;
            }
            s0 = new String(a3);
        }
        catch(Exception ignoredException)
        {
            return s;
        }
        return s0;
    }

These boolean casts have to be removed and not replaced with someting like == 0 ? 0 : 1 to match the behaviour of the source code. Krakatau doesn't know that char can be xor'd I think.

For your convenience, the assembled class in a zip (no main method included): Stuff.zip

Storyyeller commented 4 years ago

Thanks for the report. I'll take a look tonight.

Storyyeller commented 4 years ago

Ok should be fixed now. Thanks for finding this.

Storyyeller commented 4 years ago

P.S. I added a simple heuristic for transforming while loops into for loops. It only handles simple cases and it doesn't include the initializer, but I figured it would be better than nothing. Please try it out and tell me what you think.