Exemplo n.º 1
0
 static void WriteCode(CodeGraph FuncCodeGraph, int Indent)
 {
     sWriter.Write(FuncCodeGraph.OutputCode(Indent));
 }
Exemplo n.º 2
0
        static void DecompFunction(uint ofs, int IndentL)
        {
            byte command;

            sReader.Keep();
            sReader.Goto(sTextOffset + ofs);
            var            maxofs        = 0u;
            Stack <string> Stack         = new Stack <string>();
            CodeGraph      FuncCodeGraph = new CodeGraph();

            do
            {
                var pos = sReader.Position - sTextOffset;
                command = sReader.Read8();
                var nextofs = 0u;
                switch (command)
                {
                case 0x00:     //int
                {
                    Stack.Push(sReader.ReadS32().ToString());
                    break;
                }

                case 0x01:     //flt
                {
                    Stack.Push(sReader.ReadF32().ToString());
                    break;
                }

                case 0x02:     //str
                {
                    var data  = sReader.ReadS32();
                    var value = FetchDataValue(data);
                    Stack.Push("\"" + value + "\"");
                    break;
                }

                case 0x03:     //adr
                {
                    Stack.Push(sReader.ReadS32().ToString("X8"));
                    break;
                }

                case 0x04:     //var
                {
                    var display = sReader.ReadS32();
                    var data    = sReader.ReadS32();
                    switch (display)
                    {
                    case 0: Stack.Push(FetchSymbolName(FetchSymbol(i => i.Type == SymbolType.Variable && i.Data == data))); break;

                    case 1: Stack.Push("local" + data.ToString()); break;
                    }
                    break;
                }

                case 0x06:     //inc
                {
                    string Op = Stack.Pop();
                    Stack.Push("(" + Op + "+1)");
                    break;
                }

                case 0x07:     //dec
                {
                    string Op = Stack.Pop();
                    Stack.Push("(" + Op + "-1)");
                    break;
                }

                case 0x08:     //add
                {
                    string Op2 = Stack.Pop();
                    string Op1 = Stack.Pop();
                    Stack.Push("(" + Op1 + " + " + Op2 + ")");
                    break;
                }

                case 0x09:     //sub
                {
                    string Op1 = Stack.Pop();
                    string Op2 = Stack.Pop();
                    Stack.Push("(" + Op1 + " - " + Op2 + ")");
                    break;
                }

                case 0x0A:     //mul
                {
                    string Op2 = Stack.Pop();
                    string Op1 = Stack.Pop();
                    Stack.Push("(" + Op1 + " * " + Op2 + ")");
                    break;
                }

                case 0x0B:     //div
                {
                    string Op1 = Stack.Pop();
                    string Op2 = Stack.Pop();
                    Stack.Push("(" + Op1 + " / " + Op2 + ")");
                    break;
                }

                case 0x0C:     //mod
                {
                    string Op1 = Stack.Pop();
                    string Op2 = Stack.Pop();
                    Stack.Push("(" + Op1 + " % " + Op2 + ")");
                    break;
                }

                case 0x0D:           //ass
                {
                    sReader.Read8(); //Ignore this byte
                    var    display      = sReader.ReadS32();
                    var    data         = sReader.ReadS32();
                    string VariableName = "";
                    switch (display)
                    {
                    case 0: VariableName = FetchSymbolName(FetchSymbol(i => i.Type == SymbolType.Variable && i.Data == data)); break;

                    case 1: VariableName = "local" + data.ToString(); break;
                    }
                    CodeVertex NewLine = new CodeVertex(VertexType.CodeBlock, -1, VariableName + " = " + Stack.Pop() + ";", pos);
                    FuncCodeGraph.AddVertex(NewLine);
                    break;
                }

                case 0x0E:     //eq
                {
                    string Op2 = Stack.Pop();
                    string Op1 = Stack.Pop();
                    Stack.Push("(" + Op1 + " == " + Op2 + ")");
                    break;
                }

                case 0x0F:     //ne
                {
                    string Op2 = Stack.Pop();
                    string Op1 = Stack.Pop();
                    Stack.Push("(" + Op1 + " != " + Op2 + ")");
                    break;
                }

                case 0x10:     //gt
                {
                    string Op1 = Stack.Pop();
                    string Op2 = Stack.Pop();
                    Stack.Push("(" + Op1 + " > " + Op2 + ")");
                    break;
                }

                case 0x11:     //lt
                {
                    string Op1 = Stack.Pop();
                    string Op2 = Stack.Pop();
                    Stack.Push("(" + Op1 + " < " + Op2 + ")");
                    break;
                }

                case 0x12:     //ge
                {
                    string Op1 = Stack.Pop();
                    string Op2 = Stack.Pop();
                    Stack.Push("(" + Op1 + " >= " + Op2 + ")");
                    break;
                }

                case 0x13:     //le
                {
                    string Op1 = Stack.Pop();
                    string Op2 = Stack.Pop();
                    Stack.Push("(" + Op1 + " <= " + Op2 + ")");
                    break;
                }

                case 0x14:     //neg
                {
                    string Op1 = Stack.Pop();
                    Stack.Push("-(" + Op1 + ")");
                    break;
                }

                case 0x15:     //not
                {
                    string Op1 = Stack.Pop();
                    Stack.Push("!(" + Op1 + ")");
                    break;
                }

                case 0x16:     //and
                {
                    string Op1 = Stack.Pop();
                    string Op2 = Stack.Pop();
                    Stack.Push("(" + Op1 + " && " + Op2 + ")");
                    break;
                }

                case 0x17:     //or
                {
                    string Op1 = Stack.Pop();
                    string Op2 = Stack.Pop();
                    Stack.Push("(" + Op1 + " || " + Op2 + ")");
                    break;
                }

                case 0x18:     //band
                {
                    string Op1 = Stack.Pop();
                    string Op2 = Stack.Pop();
                    Stack.Push("(" + Op1 + " & " + Op2 + ")");
                    break;
                }

                case 0x19:     //bor
                {
                    string Op1 = Stack.Pop();
                    string Op2 = Stack.Pop();
                    Stack.Push("(" + Op1 + " ^ " + Op2 + ")");
                    break;
                }

                case 0x1A:     //shl
                {
                    string Op1 = Stack.Pop();
                    string Op2 = Stack.Pop();
                    Stack.Push("(" + Op1 + " << " + Op2 + ")");
                    break;
                }

                case 0x1B:     //shr
                {
                    string Op1 = Stack.Pop();
                    string Op2 = Stack.Pop();
                    Stack.Push("(" + Op1 + " >> " + Op2 + ")");
                    break;
                }

                case 0x1C:     //call
                {
                    var    dest     = sReader.Read32();
                    var    args     = sReader.ReadS32();
                    var    symbol   = FetchSymbol(i => i.Data == dest);
                    string FuncName = "";
                    if (symbol != null)
                    {
                        FuncName = FetchSymbolName(symbol);
                    }
                    else
                    {
                        FuncName = dest.ToString("X8");
                    }
                    string FuncInput = "";
                    for (int i = 0; i < args; i++)
                    {
                        string Op = Stack.Pop();
                        if (i != 0)
                        {
                            FuncInput = Op + "," + FuncInput;
                        }
                        else
                        {
                            FuncInput = Op;
                        }
                    }
                    Stack.Push(FuncName + "(" + FuncInput + ")");
                    break;
                }

                case 0x1D:     //func
                {
                    string FuncName  = FetchSymbolName(FetchSymbol(sReader.ReadS32()));
                    var    args      = sReader.ReadS32();
                    string FuncInput = "";
                    for (int i = 0; i < args; i++)
                    {
                        string Op = Stack.Pop();
                        if (i != 0)
                        {
                            FuncInput = Op + "," + FuncInput;
                        }
                        else
                        {
                            FuncInput = Op;
                        }
                    }
                    Stack.Push(FuncName + "(" + FuncInput + ")");
                    break;
                }

                case 0x1E: sReader.ReadS32(); break;

                case 0x1F: sReader.ReadS32(); break;

                case 0x20:     //ret
                {
                    string     Op      = Stack.Pop();
                    CodeVertex NewLine = new CodeVertex(VertexType.CodeBlock, -1, "return " + Op + ";", pos);
                    FuncCodeGraph.AddVertex(NewLine);

                    break;
                }

                case 0x21:     //ret0
                {
                    CodeVertex NewLine = new CodeVertex(VertexType.CodeBlock, -1, "return 0;", pos);
                    FuncCodeGraph.AddVertex(NewLine);
                    break;
                }

                case 0x22:     //jne
                {
                    var dest = sReader.Read32();
                    nextofs = dest;
                    string     Op      = Stack.Pop();
                    CodeVertex NewLine = new CodeVertex(VertexType.ConditionalBranch, dest, Op, pos);
                    FuncCodeGraph.AddVertex(NewLine);

                    break;
                }

                case 0x23:     //jmp
                {
                    var dest = sReader.Read32();
                    nextofs = dest;
                    CodeVertex NewLine = new CodeVertex(VertexType.Branch, dest, "", pos);
                    FuncCodeGraph.AddVertex(NewLine);
                    break;
                }

                case 0x24:     //pop
                {
                    string     Op      = Stack.Pop();
                    CodeVertex NewLine = new CodeVertex(VertexType.CodeBlock, -1, Op + ";", pos);
                    FuncCodeGraph.AddVertex(NewLine);
                    break;
                }

                case 0x25:     //int0
                {
                    Stack.Push("0");
                    break;
                }

                case 0x26:     //int1
                {
                    Stack.Push("1");
                    break;
                }
                }
                if (nextofs > maxofs)
                {
                    maxofs = nextofs;
                }
            } while (!IsReturnCommand(command) || sReader.Position <= sTextOffset + maxofs);

            WriteCode(FuncCodeGraph, IndentL);

            sWriter.WriteLine();

            sReader.Back();
        }