Exemple #1
0
        public static OpCode DecodeOpCode(IMemoryManager memory, ulong address, ExecutionMode mode)
        {
            int opCode = memory.Read <int>(address);

            InstDescriptor inst;

            OpCodeTable.MakeOp makeOp;

            if (mode == ExecutionMode.Aarch64)
            {
                (inst, makeOp) = OpCodeTable.GetInstA64(opCode);
            }
            else
            {
                if (mode == ExecutionMode.Aarch32Arm)
                {
                    (inst, makeOp) = OpCodeTable.GetInstA32(opCode);
                }
                else /* if (mode == ExecutionMode.Aarch32Thumb) */
                {
                    (inst, makeOp) = OpCodeTable.GetInstT32(opCode);
                }
            }

            if (makeOp != null)
            {
                return((OpCode)makeOp(inst, address, opCode));
            }
            else
            {
                return(new OpCode(inst, address, opCode));
            }
        }
Exemple #2
0
        public static OpCode64 DecodeOpCode(MemoryManager memory, long position, ExecutionMode mode)
        {
            int opCode = memory.ReadInt32(position);

            Inst inst;

            if (mode == ExecutionMode.Aarch64)
            {
                inst = OpCodeTable.GetInstA64(opCode);
            }
            else
            {
                if (mode == ExecutionMode.Aarch32Arm)
                {
                    inst = OpCodeTable.GetInstA32(opCode);
                }
                else /* if (mode == ExecutionMode.Aarch32Thumb) */
                {
                    inst = OpCodeTable.GetInstT32(opCode);
                }
            }

            OpCode64 decodedOpCode = new OpCode64(Inst.Undefined, position, opCode);

            if (inst.Type != null)
            {
                decodedOpCode = MakeOpCode(inst.Type, inst, position, opCode);
            }

            return(decodedOpCode);
        }
        public override Instruction ReadInstruction(Function function)
        {
            var instr = new Instruction();

            var  instruction = Reader.ReadBEInt32();
            var  opcode      = (instruction & 0xFF000000) >> 25;
            var  a           = instruction & 0xFF;
            int  c           = (int)(instruction & 0x1FF00) >> 8;
            int  b           = (int)(instruction & 0x1FE0000) >> 17;
            bool szero       = false;

            if (c >= 256)
            {
                c    -= 256;
                szero = true;
            }

            instr.A         = (uint)a;
            instr.B         = (uint)b;
            instr.C         = (uint)c;
            instr.Bx        = (uint)((instruction & 0x1FFFF00) >> 8);
            instr.SBx       = (int)(instr.Bx - 65536 + 1);
            instr.ExtraCBit = szero;
            instr.OpCode    = LuaOpCode.HKS_OPCODE_UNK;
            if (OpCodeTable.TryGetValue((int)opcode, out LuaOpCode opCode))
            {
                instr.OpCode = opCode;
            }

            return(instr);
        }
Exemple #4
0
        public static OpCode64 DecodeOpCode(CpuThreadState state, MemoryManager memory, long position)
        {
            int opCode = memory.ReadInt32(position);

            Inst inst;

            if (state.ExecutionMode == ExecutionMode.AArch64)
            {
                inst = OpCodeTable.GetInstA64(opCode);
            }
            else
            {
                //TODO: Thumb support.
                inst = OpCodeTable.GetInstA32(opCode);
            }

            OpCode64 decodedOpCode = new OpCode64(Inst.Undefined, position, opCode);

            if (inst.Type != null)
            {
                decodedOpCode = MakeOpCode(inst.Type, inst, position, opCode);
            }

            return(decodedOpCode);
        }
Exemple #5
0
        public static OpCode DecodeOpCode(MemoryManager memory, ulong address, ExecutionMode mode)
        {
            int opCode = memory.ReadInt32((long)address);

            InstDescriptor inst;

            Type type;

            if (mode == ExecutionMode.Aarch64)
            {
                (inst, type) = OpCodeTable.GetInstA64(opCode);
            }
            else
            {
                if (mode == ExecutionMode.Aarch32Arm)
                {
                    (inst, type) = OpCodeTable.GetInstA32(opCode);
                }
                else /* if (mode == ExecutionMode.Aarch32Thumb) */
                {
                    (inst, type) = OpCodeTable.GetInstT32(opCode);
                }
            }

            if (type != null)
            {
                return(MakeOpCode(inst, type, address, opCode));
            }
            else
            {
                return(new OpCode(inst, address, opCode));
            }
        }
Exemple #6
0
            public OpArray(OpCodeTable table)
            {
                List <Op> ops = new List <Op>();

                foreach (string opName in table.NameToOpCode.Keys)
                {
                    ops.Add(new Op(opName, true));
                }
                _ops    = ops.ToArray();
                _length = _ops.Length;
            }
Exemple #7
0
 public VexHandler(uint dword1, uint dword2, uint dword3)
     : base(GetCode(dword1), GetOpCode(dword1), GetGroupIndex(dword2), (Encodable)((dword2 >> (int)VexFlags.EncodableShift) & (int)VexFlags.EncodableMask), OperandSize.None, AddressSize.None, null, CreateOps(dword3))
 {
     opCodeTable     = (OpCodeTable)((dword2 >> (int)VexFlags.OpCodeTableShift) & (int)VexFlags.OpCodeTableMask);
     mandatoryPrefix = (MandatoryPrefix)((dword2 >> (int)VexFlags.MandatoryPrefixShift) & (int)VexFlags.MandatoryPrefixMask);
     W1       = (dword2 & (uint)VexFlags.VEX_W1) != 0;
     lastByte = (dword2 >> ((int)VexFlags.VEX_LShift - 2)) & 4;
     if (W1)
     {
         lastByte |= 0x80;
     }
 }
Exemple #8
0
        public void AddOpTable(OpCodeTable table)
        {
            Action action = () =>
            {
                _ops = new OpArray(table);
                //string[] uck = new string[] { "BALLOON", "LOCATION", "DOOR", "SHUTTLE", "SPAWN", "S_SOCIAL" };
                //foreach (string filter in uck)
                //{
                //    foreach (Op op in _ops.GetByFilter(filter)) _ops[op.Name].Checked = false;
                //}
            };

            Invoke(action);
        }
Exemple #9
0
 public EvexHandler(uint dword1, uint dword2, uint dword3)
     : base(GetCode(dword1), GetOpCode(dword1), GetGroupIndex(dword2), (Encodable)((dword2 >> (int)EvexFlags.EncodableShift) & (int)EvexFlags.EncodableMask), OperandSize.None, AddressSize.None, tryConvertToDisp8N, CreateOps(dword3))
 {
     flags       = (EvexFlags)dword2;
     tupleType   = (TupleType)((dword2 >> (int)EvexFlags.TupleTypeShift) & (uint)EvexFlags.TupleTypeMask);
     opCodeTable = (OpCodeTable)((dword2 >> (int)EvexFlags.OpCodeTableShift) & (int)EvexFlags.OpCodeTableMask);
     Debug.Assert((int)MandatoryPrefix.None == 0);
     Debug.Assert((int)MandatoryPrefix.P66 == 1);
     Debug.Assert((int)MandatoryPrefix.PF3 == 2);
     Debug.Assert((int)MandatoryPrefix.PF2 == 3);
     p1Bits = 4 | ((dword2 >> (int)EvexFlags.MandatoryPrefixShift) & (int)EvexFlags.MandatoryPrefixMask);
     if ((dword2 & (uint)EvexFlags.EVEX_W1) != 0)
     {
         p1Bits |= 0x80;
     }
     llBits = (dword2 >> ((int)EvexFlags.EVEX_LShift - 5)) & 0x60;
 }
        private static void LinkNode(IGraphNode node, IDictionary <ushort, CallGraphNode> nodes, ushort targetIP)
        {
            CallGraphNode targetNode;

            if (nodes.TryGetValue(targetIP, out targetNode))
            {
                node.OutEdges.Add(targetNode);
                targetNode.InEdges.Add(node);
            }
            else
            {
                // Create a new empty node at the IP
                IList <IInstruction> instructions = new List <IInstruction>();
                instructions.Add(OpCodeTable.GetInstruction(OpCodes.Nop, targetIP, null));
                CallGraphNode emptyNode = new CallGraphNode(instructions);
                nodes.Add(targetIP, emptyNode);
                node.OutEdges.Add(emptyNode);
                emptyNode.InEdges.Add(node);
            }
        }
Exemple #11
0
        protected override Instruction ReadInstruction()
        {
            var instruction = new HavokInstruction();

            // Reading the values attached to the instruction
            // A = 8 bits
            // C = 9 bits
            // B = 8 bits
            // OpCode = 7 bits
            instruction.A = Reader.ReadByte();

            int  cValue = Reader.ReadByte();
            byte bValue = Reader.ReadByte();

            if (GetBit(bValue, 0) == 1)
            {
                instruction.ExtraCBit = true;
            }
            instruction.C = (uint)cValue;

            instruction.B = (uint)(bValue >> 1);
            byte flagsB = Reader.ReadByte();

            if (GetBit(flagsB, 0) == 1)
            {
                instruction.B += 128;
            }

            instruction.HavokOpCode = LuaHavokOpCode.HKS_OPCODE_UNK;

            if (OpCodeTable.TryGetValue(flagsB >> 1, out var opCode))
            {
                instruction.HavokOpCode = opCode;
            }

            instruction.Bx  = (uint)(instruction.B * 512 + instruction.C + (instruction.ExtraCBit ? 256 : 0));
            instruction.SBx = (int)(instruction.Bx - 65536 + 1);

            return(instruction);
        }
        private void Test(String methodName)
        {
            MethodInfo       method          = typeof(ExceptionHandlerTest).GetMethod(methodName);
            MethodBody       body            = method.GetMethodBody();
            IMethodReference methodReference = AssemblyManager.FindMethod(method);

            ushort ip = 0;

            byte[] il = body.GetILAsByteArray();
            SortedList <ushort, IInstruction> instructions = new SortedList <ushort, IInstruction>();

            while (ip < il.Length)
            {
                instructions.Add(ip, OpCodeTable.GetInstruction(il, ref ip, (NDecompile.Model.Impl.Module)methodReference.Resolve().DeclaringType.Resolve().Module, new Type[0], new Type[0]));
            }


            foreach (ExceptionHandlingClause clause in body.ExceptionHandlingClauses)
            {
                Console.WriteLine(clause.Flags);
                Console.WriteLine(clause.TryOffset + " " + (clause.TryOffset + clause.TryLength));
                Console.WriteLine(clause.HandlerOffset + " " + (clause.HandlerOffset + clause.HandlerLength));
                Console.WriteLine();
            }

            Node rootNode = new Node();

            rootNode.StartIP = 0;
            rootNode.EndIP   = (ushort)body.GetILAsByteArray().Length;
            rootNode.Type    = "Return";
            rootNode.Instructions.AddRange(instructions.Values);

            List <Node> nodes = new List <Node>();

            nodes.Add(rootNode);

            // Add the exception information - build a sorted tree of clauses
            SortedList <int, TryHandler> clauses = new SortedList <int, TryHandler>();

            foreach (ExceptionHandlingClause clause in body.ExceptionHandlingClauses)
            {
                Add(new TryHandler(clause), clauses);
            }

            Print(clauses, 0);
            Console.WriteLine();

            foreach (TryHandler tryHandler in clauses.Values)
            {
                TraverseExceptionTree(tryHandler, nodes);
            }

            foreach (Node node in nodes)
            {
                Console.Write(node.StartIP + " " + node.EndIP + " " + node.Type);

                if (node.Type == "Try")
                {
                    //Console.Write(" - Handler Node " + node.OutEdges[1].StartIP + " - Follow Node " + node.OutEdges[2].StartIP);
                    Console.Write(" - Handler Node " + node.HandlerNode.StartIP + " - Follow Node " + node.FollowNode.StartIP);
                }
                ;

                Console.WriteLine();

                foreach (IInstruction instruction in node.Instructions)
                {
                    Console.WriteLine("    " + instruction.IP + " " + instruction.OpCode.Name);
                }
            }
        }
 public Instruction(NetOpCode opCode, ushort ip, Object argument)
 {
     _opCode   = OpCodeTable.Get(opCode.Value);
     _ip       = ip;
     _argument = argument;
 }
Exemple #14
0
 public void generateOpcodeTable(int key)
 {
     if (key == 0)
     {
         byte[] opcodes = new byte[0xd1]; // d0 + 1
         for (int i = 0; i < opcodes.Length; i++)
         {
             opcodes[i] = (byte)i;
         }
         short[] exOpcodes = new short[0x4e];
         for (int i = 0; i < exOpcodes.Length; i++)
         {
             exOpcodes[i] = (byte)i;
         }
         _table = new OpCodeTable(opcodes, exOpcodes);
     }
     else
     {
         _table = OpcodeObfuscator.getObfuscatedTable(key);
     }
 }
Exemple #15
0
 public static void AddTable(OpCodeTable table) => Instance.AddOpTable(table);
        public ControlFlowGraph(NetMethodBody body, Module module, Type[] genericTypeArguments, Type[] genericMethodArguments)
        {
            // Convert the byte code into instruction objects
            ushort ip = 0;

            byte[] il = body.GetILAsByteArray();

            List <IInstruction> instructions = new List <IInstruction>();

            while (ip < il.Length)
            {
                instructions.Add(OpCodeTable.GetInstruction(il, ref ip, module, genericTypeArguments, genericMethodArguments));
            }

            // Iterate the instructions building a list of call graph nodes
            SortedList <ushort, CallGraphNode> nodes = new SortedList <ushort, CallGraphNode>();
            CallGraphNode node = new CallGraphNode(0);

            nodes.Add(0, node);

            int          index       = 0;
            IInstruction instruction = instructions[index];

            do
            {
                Console.Write(instruction);

                // Create the nodes that this instruction branches to
                switch (instruction.OpCode.FlowControl)
                {
                case FlowControl.Branch:
                {
                    if ((instruction.OpCode != OpCodes.Leave) &&
                        (instruction.OpCode != OpCodes.Leave_S))
                    {
                        // Direct branch to a new instruction that is not a leave instruction from a try-catch block.
                        // Create a call graph node for the target of the branch.
                        MakeNode((ushort)instruction.Argument, nodes);

                        Console.Write(" <-- Branch {0:x4}", instruction.Argument);
                    }

                    break;
                }

                case FlowControl.Cond_Branch:
                {
                    if (instruction.OpCode.Value == OpCodes.Switch.Value)
                    {
                        // Conditional branch to n-blocks
                        foreach (ushort switchTargetIp in (ushort[])instruction.Argument)
                        {
                            MakeNode(switchTargetIp, nodes);
                        }
                    }
                    else
                    {
                        // Conditional branch to two blocks
                        MakeNode((ushort)instruction.Argument, nodes);

                        Console.WriteLine("Making " + instruction.Argument);
                    }

                    // Set the next instruction of a branch to also be a target
                    MakeNode(instructions[index + 1].IP, nodes);
                    Console.Write(" <-- If Node {0:x4}", instruction.Argument);
                    break;
                }

                case FlowControl.Return:
                    // Set the next instruction of a branch to also be a target
                    Console.Write(" <-- Exit Node");
                    break;

                case FlowControl.Throw:
                    // End of graph
                    Console.Write(" <-- Throw Node");
                    break;

                case FlowControl.Break:
                case FlowControl.Call:
                case FlowControl.Meta:
                case FlowControl.Next:
#pragma warning disable 612,618
                case FlowControl.Phi:
#pragma warning restore 612,618
                    // Add the continuation link
                    //node.NodeType = NodeType.FallThrough;
                    //MakeNode(ip, node, nodes);
                    break;
                }

                Console.WriteLine();

                // Get the next instruction
                index++;
                if (index < instructions.Count)
                {
                    instruction = instructions[index];

                    // Find the node to add the next instruction to
                    CallGraphNode nextNode;
                    if (nodes.TryGetValue(instruction.IP, out nextNode))
                    {
                        /*if (node.NodeType == NodeType.FallThrough)
                         * {
                         *      Console.Write("added fall through link ");
                         *      node.OutEdges.Add(nextNode);
                         *      nextNode.InEdges.Add(node);
                         * }*/



                        node = nextNode;

                        Console.Write("New Node --> ");
                    }
                }
            } while (index < instructions.Count);

            Console.WriteLine();

            // Iterate the instructions a second time adding them to the correct nodes
            //CallGraphNode node;
            node = nodes[0];
            for (index = 0; index < instructions.Count; index++)
            {
                instruction = instructions[index];

                if (index > 0)
                {
                    CallGraphNode nextNode;
                    if (nodes.TryGetValue(instruction.IP, out nextNode))
                    {
                        if (node.OutEdges.Count == 0)
                        {
                            Console.WriteLine("ff");
                            node.NodeType = NodeType.FallThrough;
                            LinkNode(node, nextNode);
                        }
                        Console.Write("--" + node.OutEdges.Count + "--");
                        node = nextNode;
                        Console.Write("new node ");
                    }
                }

                Console.WriteLine(instruction);
                node.Instructions.Add(instruction);

                // Create the nodes that this instruction branches to
                switch (instruction.OpCode.FlowControl)
                {
                case FlowControl.Branch:
                {
                    if ((instruction.OpCode != OpCodes.Leave) &&
                        (instruction.OpCode != OpCodes.Leave_S))
                    {
                        // Direct branch to a new instruction that is not a leave instruction from a try-catch block.
                        // Create a call graph node for the target of the branch.
                        node.NodeType = NodeType.OneBranch;
                        LinkNode(node, nodes[(ushort)instruction.Argument]);

                        Console.Write(" <-- Branch {0:x4}", instruction.Argument);
                    }

                    break;
                }

                case FlowControl.Cond_Branch:
                {
                    if (instruction.OpCode.Value == OpCodes.Switch.Value)
                    {
                        // Conditional branch to n-blocks
                        node.NodeType = NodeType.MultiBranch;
                        foreach (ushort switchTargetIp in (ushort[])instruction.Argument)
                        {
                            LinkNode(node, nodes[switchTargetIp]);
                        }
                    }
                    else
                    {
                        // Conditional branch to two blocks
                        node.NodeType = NodeType.TwoBranch;
                        LinkNode(node, nodes[(ushort)instruction.Argument]);
                        Console.Write("Linking " + instruction.Argument);
                    }

                    // Set the next instruction of a branch to also be a target
                    LinkNode(node, nodes[instructions[index + 1].IP]);
                    Console.Write(" <-- If Node {0:x4}", instruction.Argument);
                    break;
                }

                case FlowControl.Return:
                    // Set the next instruction of a branch to also be a target
                    node.NodeType = NodeType.Exit;
                    Console.Write(" <-- Exit Node");
                    break;

                case FlowControl.Throw:
                    // End of graph
                    node.NodeType = NodeType.Throw;
                    Console.Write(" <-- Throw Node");
                    break;
                }
            }



            // Copy the nodes to a simple list
            _nodes.AddRange(nodes.Values);

            Console.WriteLine();
            Console.WriteLine(_nodes.Count);
            foreach (CallGraphNode n in _nodes)
            {
                Console.WriteLine(n.StartIP + " " + n.NodeType + " " + n.OutEdges.Count);
            }

            CheckGraph();

            // Add the exception information - build a sorted tree of clauses
            SortedList <int, TryHandler> clauses = new SortedList <int, TryHandler>();
            foreach (ExceptionHandlingClause clause in body.ExceptionHandlingClauses)
            {
                Add(new TryHandler(clause), clauses);
            }

            foreach (TryHandler clause in clauses.Values)
            {
                TraverseExceptionTree(clause);
            }

            // Find the root node -- This fails when there are multiple try statements on the first instruction
            for (int i = 0; i < _nodes.Count; i++)
            {
                if (_nodes[i].StartIP == 0)
                {
                    _rootNode = _nodes[i];
                    break;
                }
            }

            if (_rootNode == null)
            {
                throw new ApplicationException("Unable to find a root node");
            }

            CheckGraph();

            // Remove redundancies and add in-edge information
            Optimize();

            CheckGraph();

            // Visit the graph in depth first order and label the nodes
            _depthFirstSearchLast = new CallGraphNode[_nodes.Count];
            int last = _nodes.Count - 1;
            DepthFirstTraverse(_rootNode, ref last);

            // Find the immediate dominators of each node
            FindImmediateDominators();

            // Check the graph for reducibility
            FindDerivedSequence();

            // Work out the graphs back edges
            DetermineBackEdges();

            ResetTraversal();
            StructureCases();
            StructureLoops();
            StructureIfs();
            ResetTraversal();
        }
        protected override Instruction ReadInstruction()
        {
            var instr = new LuaJitInstruction();

            var codeword = Reader.ReadUInt32();

            instr.OpCode = LuaJitOpCode.UNKNW;
            if (OpCodeTable.TryGetValue((int)(codeword & 0xFF), out var opCode))
            {
                instr.OpCode = opCode;
            }

            dynamic ProcessOperand(LuaJitArgumentType type, dynamic operand)
            {
                if (type is LuaJitArgumentType.Str or LuaJitArgumentType.Tab or LuaJitArgumentType.Fun or LuaJitArgumentType.Cdt)
                {
                    return(((long)((LuaJitFunctionHeader)Header).ComplexConstantsCount) - operand - 1);
                }

                if (type == LuaJitArgumentType.Jmp)
                {
                    return(operand - 0x8000);
                }

                if (type == LuaJitArgumentType.Slit || type == LuaJitArgumentType.Num)
                {
                    return(BitConverter.ToInt16(BitConverter.GetBytes(operand)));
                }

                return(operand);
            }

            var  a = (codeword >> 8) & 0xFF;
            uint b = 0;
            long cd;

            if (instr.OpCode.ArgumentsCount == 3)
            {
                cd = (codeword >> 16) & 0xFF;
                b  = (codeword >> 24) & 0xFF;
            }
            else
            {
                cd = (codeword >> 16) & 0xFFFF;
            }

            if (instr.OpCode.AType != LuaJitArgumentType.None)
            {
                instr.A = ProcessOperand(instr.OpCode.AType, a);
            }
            if (instr.OpCode.BType != LuaJitArgumentType.None)
            {
                instr.B = ProcessOperand(instr.OpCode.BType, b);
            }
            if (instr.OpCode.CDType != LuaJitArgumentType.None)
            {
                instr.CD = ProcessOperand(instr.OpCode.CDType, cd);
            }

            return(instr);
        }