反转字节码 - 尝试反编译表达式

逆向工程 文件格式
2021-06-13 17:36:33

我正在尝试对专有脚本“编译字节码”进行逆向工程,因此我可以恢复已经离开的承包商的源代码。

虽然我已经完成了大部分工作,但我正在努力研究如何将表达式转换回代码。想知道是否有人可能从下面的模式中对可能用于重建方程的逻辑类型有一些想法。特别是如何将运算符应用回表达式的组件。

具体来说,我想弄清楚如何反编译这两个表达式:

A = B * C+D/E-F
A = B * (C+D)/E-F

操作代码,这是从下面提供的示例中得出的

22 04 >
2B 04 <
32 04 *
01 04 +
17 04 /
55 04 -
25 00 AND
27 00 OR
26 04 end of statement

任务类型:

3D 40 xx xx       = Variable xx xx 
3D 45 xx xx xx xx = 4 byte number
4B xx             = One byte value
48 xx             = One byte value
38 40 xx xx       = Assign result to variable xx xx

在这个例子中,变量是:

A = 00 00
B = 00 04
C = 00 08
D = 00 0C
E = 00 10
F = 00 14

例子:

A = 10*20+30/40-50/2

4B AF       ; 175 
38 40 00 00 ; Assign result to A

A = 10*B+30/40-50/2

48 0A       ; 10
3D 40 00 04 ; B 
32 04       ; *
48 00       ; 0
01 04       ; +
48 19       ; 25
55 04       ; -
38 40 00 00 ; assign result to A

A = B+C

3D 40 00 04 ; B
3D 40 00 08 ; C
01 04       ; +
38 40 00 00 ; assign result to A

A = B*C

3D 40 00 04 ; B
3D 40 00 08 ; C
32 04       ; *
38 40 00 00 ; assign result to A

A = BC

3D 40 00 04 ; B
3D 40 00 08 ; C
55 04       ; -
38 40 00 00 ; Assign result to A

A = B/C

3D 40 00 04 ; B
3D 40 00 08 ; C
17 04       ; / 
38 40 00 00 ; Assign result to A

A = B*C+DE/F

3D 40 00 04 ; B
3D 40 00 08 ; C
32 04       ; *
3D 40 00 0C ; D
01 04       ; +
3D 40 00 10 ; E
3D 40 00 14 ; F
17 04       ; /
55 04       ; -
38 40 00 00 ; Assign result to A

A = B*C+D/EF

3D 40 00 04 ; B
3D 40 00 08 ; C
32 04       ; *
3D 40 00 0C ; D
3D 40 00 10 ; E
17 04       ; / 
01 04       ; +
3D 40 00 14 ; F
55 04       ; -
38 40 00 00 ; Assign result to A

A = B*(C+D)/EF

3D 40 00 04 ; B
3D 40 00 08 ; C
3D 40 00 0C ; D
01 04       ; +
32 04       ; *
3D 40 00 10 ; E
17 04       ; /
3D 40 00 14 ; F
55 04       ; -
38 40 00 00 ; Assign result to A

A = B+C * D

3D 40 00 04 ; B
3D 40 00 08 ; C 
3D 40 00 0C ; D
32 04       ; * 
01 04       ; +
38 40 00 00 ; assign result to A

A=(B+C) * D

3D 40 00 04 ; B
3D 40 00 08 ; C
01 04       ; +
3D 40 00 0C ; D
32 04       ; *
38 40 00 00 ; assign result to A

A=B+C+D * E

3D 40 00 04 ; B
3D 40 00 08 ; C
01 04       ; +
3D 40 00 0C ; D
3D 40 00 10 ; E
32 04       ; *
01 04       ; +
38 40 00 00 ; assign result to A

A=(B+C+D) * E

3D 40 00 04 ; B
3D 40 00 08 ; C
01 04       ; +
3D 40 00 0C ; D
01 04       ; +
3D 40 00 10 ; E
32 04       ; *
38 40 00 00 ; assign result to A

A=A+B * C+D+E * F

3D 40 00 00 ; A
3D 40 00 04 ; B
3D 40 00 08 ; C
32 04       ; *
01 04       ; +
3D 40 00 0C ; D
01 04       ; +
3D 40 00 10 ; E
3D 40 00 14 ; F
32 04       ; *
01 04       ; +
38 40 00 00 ; Assign result to A

A=(A+B) * (C+D)+E * F

3D 40 00 00 ; A
3D 40 00 04 ; B
01 04       ; + 
3D 40 00 08 ; C
3D 40 00 0C ; D
01 04       ; +   
32 04       ; *
3D 40 00 10 ; E
3D 40 00 14 ; F
32 04       ; *
01 04       ; +
38 40 00 00 ; Assign result to A

A=A+B+(C * D)+E

3D 40 00 00 ; A
3D 40 00 04 ; B
01 04       ; +
3D 40 00 08 ; C
3D 40 00 0C ; D
32 04       ; *
01 04       ; +
3D 40 00 10 ; E
01 04       ; + 
38 40 00 00 ; assign result to A

A=A+B+(C* D *E)+F

3D 40 00 00 ; A
3D 40 00 04 ; B
01 04       ; +
3D 40 00 08 ; C
3D 40 00 0C ; D
32 04       ; *
3D 40 00 10 ; E
32 04       ; *
01 04       ; +
3D 40 00 14 ; F
01 04       ; +
38 40 00 00 ; assign result to A

A=BC

3D 40 00 04 ; B
3D 40 00 08 ; C
55 04       ; -
38 40 00 00 ; assign result to A

A=B*C+DE/F

3D 40 00 04 ; B
3D 40 00 08 ; C
32 04       ; *
3D 40 00 0C ; D
01 04       ; +
3D 40 00 10 ; E
3D 40 00 14 ; F
17 04       ; -
55 04       ; /
38 40 00 00 ; Assign result to A

布尔表达式

512<A

3D 45 00 00 02 00 ; 512
3D 40 00 00       ; variable A
2B 04             ; <
26 00             ; end of expression
00 7E             ; ?

a>B 和 b128 或 d>1024 或 e>128

3D 40 00 00 ; A
3D 40 00 04 ; B
22 04       ; >
25 00       ; AND
00 CC       ;
3D 40 00 04 ; B
3D 40 00 08 ; C
2B 04       ; <
25 00       ; AND
00 CC       ;
3D 40 00 08 ; C
4B 80       ; 128
22 04       ; >
27 00       ; OR 
00 E8       ;
3D 40 00 0C ; D 
3D 45 00 00 04 00 ; 1024
22 04       ; >
27 00       ; OR 
00 E8       ; 
3D 40 00 10 ; E
4B 80       ; 128
22 04       ; >
26 00       ; end of expression
01 14       ; ?
1个回答

感谢 Jongware 的回应,他正确地将其识别为反向波兰符号,需要将其转换为“中缀”

在一些样品上测试

原来的:

1) A=B * C+DE/F

2) A=B * C+D/EF

3) A=B * (C+D)/EF

反编译:

1) A=(((B * C)+D)-(E/F))

2) A=(((B * C)+(D/E))-F)

3) A=(((B* (C+D))/E)-F)

如果这对其他人有帮助,那么这就是 C# 中的原型处理代码,我已经验证过它可以正常工作。此代码需要进一步改进,但它确实适用于所描述的这种情况。

    // instruction is a byte[] array containing the code to decode
    Stack<string> stack = new Stack<string>();
    string op;
    byte[] bit32=new byte[4];
    string result;

    for (int i = 0; i < instruction.Length;i++ )
    {
        op="";
        switch (instruction[i])
        {
            case 0x22:
                op=">";
                i++;
                break;
            case 0x2B:
                op="<";
                i++;
                break;
            case 0x32:
                op="*";
                i++;
                break;
        case 0x01:
            op="+";
            i++;
            break;
        case 0x17:
            op="/";
            i++;
            break;
        case 0x55:
            op="-";
            i++;
            break;
        case 0x38:
            i++;

            if (instruction[i]==0x40)
            {
                // builds the final result, and adds it to textboxDecompiledText
                i++;
                result = string.Format("{0}={1}", string.Format("S{0:X2}{1:X2}", instruction[i], instruction[i + 1]),
                stack.Pop());

                i++;

                textBoxDecompiled.Text += result;
                break;

            }
            break;
        case 0x4B: // 1 byte integer
        case 0x48:
            i++;
            stack.Push(((int)instruction[i]).ToString());
            break;
        case 0x3D:
            i++;
            switch (instruction[i])
            {
                case 0x40: // variable
                    i++;
                    string currentVariable= string.Format("S{0:X2}{1:X2}", instruction[i], instruction[i + 1]);
                    stack.Push(currentVariable);
                    i += 1;
                    break;
                case 0x45: // 4 byte integer
                    i++;
                    Buffer.BlockCopy(instruction,i,bit32,0,4);
                    Array.Reverse(bit32);
                    int bit32result = BitConverter.ToInt32(instruction, 0);
                    stack.Push(bit32result.ToString());
                    i+=3;
                    break;


            }
            break;

    }

    // check if we have an operator
    if (!string.IsNullOrEmpty(op))
    {
        if (stack.Count >= 2)
        {
            string op2 = stack.Pop();
            string op1 = stack.Pop();
            stack.Push(string.Format("({0}{1}{2})", op1, op, op2));
        }
        else
        {
            // something wrong here!
            throw new InvalidOperationException();
        }
    }
}