Exemple #1
0
        public string OutputCode(int IndentL)
        {
            for (int i = 0; i < Graph.Count; i++)
            {
                if (Graph[i].Type == VertexType.Branch)
                {
                    int BranchIndex = IndexFromAddr(Graph[i].BranchTo);
                    if (BranchIndex == -1)
                    {
                        Graph[i].Code = "break " + Graph[i].BranchTo.ToString() + ";";//Branch to label
                        long       EndAddr = Graph[Graph.Count - 1].Addr;
                        CodeVertex Label   = new CodeVertex(VertexType.Label, -1, Graph[i].BranchTo.ToString() + ":", EndAddr + 1);
                        Graph.Add(Label);
                    }
                    else
                    {
                        VertexType DestType = Graph[BranchIndex].Type;

                        if (DestType == VertexType.CodeBlock || DestType == VertexType.Branch)
                        {
                            Graph[i].Code = "break " + Graph[i].BranchTo.ToString() + ";";//Branch to label
                            CodeVertex NewLine = new CodeVertex(VertexType.Label, -1, Graph[i].BranchTo.ToString() + ":", Graph[i].BranchTo);
                            Graph.Insert(BranchIndex, NewLine);
                            if (BranchIndex <= i)
                            {
                                i++;
                            }
                        }
                        else if (DestType == VertexType.Label)
                        {
                            string LabelName = Graph[BranchIndex].Code.Replace(':', ' ');
                            Graph[i].Code = "break " + LabelName + ";";//Branch to label
                        }
                        else if (DestType == VertexType.ConditionalBranch)
                        {
                            //While Loop Detected
                            Graph[BranchIndex].Code = "while(" + Graph[BranchIndex].Code + ")" + Environment.NewLine + "{";//Put while loop
                            int ClosingIndex = IndexFromAddr(Graph[BranchIndex].BranchTo);
                            if (ClosingIndex == -1)
                            {
                                CodeVertex NewLine = new CodeVertex(VertexType.CodeBlock, -1, "}", Graph[BranchIndex].BranchTo);
                                Graph.Add(NewLine);
                            }
                            else
                            {
                                CodeVertex NewLine = new CodeVertex(VertexType.CodeBlock, -1, "}", Graph[BranchIndex].BranchTo);
                                Graph.Insert(ClosingIndex, NewLine);
                                if (ClosingIndex <= i)
                                {
                                    i++;
                                }
                            }
                        }
                    }
                }
            }

            for (int i = 0; i < Graph.Count; i++)
            {
                if (Graph[i].Type == VertexType.ConditionalBranch && !Graph[i].Code.StartsWith("while"))
                {
                    if (Graph[i].Addr < Graph[i].BranchTo)
                    {
                        //If Statement Detected
                        Graph[i].Code = "if(" + Graph[i].Code + ")" + Environment.NewLine + "{";//Put if
                        int ClosingIndex = IndexFromAddr(Graph[i].BranchTo);
                        if (ClosingIndex == -1)
                        {
                            CodeVertex NewLine = new CodeVertex(VertexType.CodeBlock, -1, "}", Graph[i].BranchTo);
                            Graph.Add(NewLine);
                        }
                        else
                        {
                            CodeVertex NewLine = new CodeVertex(VertexType.CodeBlock, -1, "}", Graph[i].BranchTo);
                            Graph.Insert(ClosingIndex, NewLine);
                            if (ClosingIndex <= i)
                            {
                                i++;
                            }
                        }
                    }
                    else
                    {
                        //Do loop detected
                        Graph[i].Code = "} while(" + Graph[i].Code + ")";//Put do loop
                        int        ClosingIndex = IndexFromAddr(Graph[i].BranchTo);
                        CodeVertex NewLine      = new CodeVertex(VertexType.CodeBlock, -1, "do" + Environment.NewLine + "{", Graph[i].BranchTo);
                        Graph.Insert(ClosingIndex, NewLine);
                        if (ClosingIndex <= i)
                        {
                            i++;
                        }
                    }
                }
            }

            string DecompiledCode = "";

            for (int i = 0; i < Graph.Count; i++)
            {
                DecompiledCode = DecompiledCode + Environment.NewLine + Graph[i].Code;
            }

            string[] lines = DecompiledCode.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
            DecompiledCode = "";

            int IndentLevel = IndentL;

            for (int i = 0; i < lines.Length; i++)
            {
                if (lines[i] == "")
                {
                    continue;
                }
                string IndentedString = new String(' ', IndentLevel * 4) + lines[i];
                if (lines[i].Contains("{"))
                {
                    IndentLevel++;
                }
                else if (lines[i].Contains("}"))
                {
                    IndentLevel    = System.Math.Max(0, IndentLevel - 1);
                    IndentedString = new String(' ', IndentLevel * 4) + lines[i];
                }
                if (DecompiledCode == "")
                {
                    DecompiledCode = IndentedString;
                }
                else
                {
                    DecompiledCode = DecompiledCode + Environment.NewLine + IndentedString;
                }
            }

            return(DecompiledCode);
        }
Exemple #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();
        }
Exemple #3
0
 public void AddVertex(CodeVertex NewVertex)//Adds a vertex
 {
     Graph.Add(NewVertex);
 }