示例#1
0
        public virtual NativeCodeSequence getNativeCodeSequence(CodeInstruction codeInstruction, CodeBlock codeBlock)
        {
            int firstOpcode = codeInstruction.Opcode;

            // Fast lookup using the first opcode
            if (nativeCodeSequencesByFirstOpcode.ContainsKey(firstOpcode))
            {
                for (IEnumerator <NativeCodeSequence> it = nativeCodeSequencesByFirstOpcode[firstOpcode].GetEnumerator(); it.MoveNext();)
                {
                    NativeCodeSequence nativeCodeSequence = it.Current;
                    if (isNativeCodeSequence(nativeCodeSequence, codeInstruction, codeBlock))
                    {
                        return(nativeCodeSequence);
                    }
                }
            }

            // Slow lookup for sequences having an opcode mask in the first opcode
            foreach (NativeCodeSequence nativeCodeSequence in nativeCodeSequenceWithMaskInFirstOpcode)
            {
                if (isNativeCodeSequence(nativeCodeSequence, codeInstruction, codeBlock))
                {
                    return(nativeCodeSequence);
                }
            }

            return(null);
        }
示例#2
0
        private bool isNativeCodeSequence(NativeCodeSequence nativeCodeSequence, CodeInstruction codeInstruction, CodeBlock codeBlock)
        {
            int address    = codeInstruction.Address;
            int numOpcodes = nativeCodeSequence.NumOpcodes;

            // Can this NativeCodeSequence only match a whole CodeBlock?
            if (nativeCodeSequence.WholeCodeBlock)
            {
                // Match only a whole CodeBlock: same StartAddress, same Length
                if (codeBlock.StartAddress != address)
                {
                    return(false);
                }

                if (codeBlock.Length != numOpcodes)
                {
                    return(false);
                }
            }

            for (int i = 0; i < numOpcodes; i++)
            {
                int opcode = codeBlock.getCodeInstructionOpcode(address + (i << 2));
                if (!nativeCodeSequence.isMatching(i, opcode))
                {
                    return(false);
                }
            }

            return(true);
        }
示例#3
0
        private void loadBeforeCodeInstructions(NativeCodeSequence nativeCodeSequence, string codeInstructions)
        {
            System.IO.StreamReader reader = new System.IO.StreamReader(new StringReader(codeInstructions));
            if (reader == null)
            {
                return;
            }

            Pattern   codeInstructionPattern = Pattern.compile("\\s*(\\w+\\s*:?\\s*)?\\[(\\p{XDigit}+)\\].*");
            const int opcodeGroup            = 2;
            const int address = 0;

            try
            {
                while (true)
                {
                    string line = reader.ReadLine();
                    if (string.ReferenceEquals(line, null))
                    {
                        break;
                    }

                    line = line.Trim();
                    if (line.Length > 0)
                    {
                        try
                        {
                            Matcher codeInstructionMatcher = codeInstructionPattern.matcher(line);
                            int     opcode = 0;
                            if (codeInstructionMatcher.matches())
                            {
                                opcode = Utilities.parseAddress(codeInstructionMatcher.group(opcodeGroup));
                            }
                            else
                            {
                                opcode = Utilities.parseAddress(line.Trim());
                            }

                            Common.Instruction insn            = Decoder.instruction(opcode);
                            CodeInstruction    codeInstruction = new CodeInstruction(address, opcode, insn, false, false, 0);

                            nativeCodeSequence.addBeforeCodeInstruction(codeInstruction);
                        }
                        catch (System.FormatException e)
                        {
                            Compiler.Console.WriteLine(e);
                        }
                    }
                }
            }
            catch (IOException e)
            {
                Compiler.Console.WriteLine(e);
            }
        }
示例#4
0
        private void setParameter(NativeCodeSequence nativeCodeSequence, int parameter, string valueString)
        {
            if (string.ReferenceEquals(valueString, null) || valueString.Length <= 0)
            {
                nativeCodeSequence.setParameter(parameter, 0, false);
                return;
            }

            for (int i = 0; i < Common.gprNames.Length; i++)
            {
                if (Common.gprNames[i].Equals(valueString))
                {
                    nativeCodeSequence.setParameter(parameter, i, false);
                    return;
                }
            }

            for (int i = 0; i < Common.fprNames.Length; i++)
            {
                if (Common.fprNames[i].Equals(valueString))
                {
                    nativeCodeSequence.setParameter(parameter, i, false);
                    return;
                }
            }

            if (valueString.StartsWith("@", StringComparison.Ordinal))
            {
                string label      = valueString.Substring(1);
                int    labelIndex = nativeCodeSequence.getLabelIndex(label);
                if (labelIndex >= 0)
                {
                    nativeCodeSequence.setParameter(parameter, labelIndex, true);
                    return;
                }
            }

            try
            {
                int value;
                if (valueString.StartsWith("0x", StringComparison.Ordinal))
                {
                    value = Convert.ToInt32(valueString.Substring(2), 16);
                }
                else
                {
                    value = int.Parse(valueString);
                }
                nativeCodeSequence.setParameter(parameter, value, false);
            }
            catch (System.FormatException e)
            {
                Compiler.Console.WriteLine(e);
            }
        }
示例#5
0
        private void addNativeCodeSequence(NativeCodeSequence nativeCodeSequence)
        {
            if (nativeCodeSequence.NumOpcodes > 0)
            {
                int firstOpcodeMask = nativeCodeSequence.FirstOpcodeMask;
                if (firstOpcodeMask == defaultOpcodeMask)
                {
                    // First opcode has not mask: fast lookup allowed
                    int firstOpcode = nativeCodeSequence.FirstOpcode;

                    if (!nativeCodeSequencesByFirstOpcode.ContainsKey(firstOpcode))
                    {
                        nativeCodeSequencesByFirstOpcode[firstOpcode] = new LinkedList <NativeCodeSequence>();
                    }
                    nativeCodeSequencesByFirstOpcode[firstOpcode].Add(nativeCodeSequence);
                }
                else
                {
                    // First opcode has not mask: only slow lookup possible
                    nativeCodeSequenceWithMaskInFirstOpcode.Add(nativeCodeSequence);
                }
            }
        }
示例#6
0
 public NativeCodeInstruction(int address, NativeCodeSequence nativeCodeSequence)
 {
     this.nativeCodeSequence = nativeCodeSequence;
     this.address            = address;
     init();
 }
示例#7
0
 public virtual void setCompiledNativeCodeBlock(int address, NativeCodeSequence nativeCodeBlock)
 {
     compiledNativeCodeBlocks[address] = nativeCodeBlock;
 }
示例#8
0
        private void loadNativeCodeSequence(Element element)
        {
            string name      = element.getAttribute("name");
            string className = getContent(element.getElementsByTagName("Class"));

            Type <INativeCodeSequence> nativeCodeSequenceClass = getNativeCodeSequenceClass(className);

            if (nativeCodeSequenceClass == null)
            {
                return;
            }

            NativeCodeSequence nativeCodeSequence = new NativeCodeSequence(name, nativeCodeSequenceClass);

            string isReturningString = getContent(element.getElementsByTagName("IsReturning"));

            if (!string.ReferenceEquals(isReturningString, null))
            {
                nativeCodeSequence.Returning = bool.Parse(isReturningString);
            }

            string wholeCodeBlockString = getContent(element.getElementsByTagName("WholeCodeBlock"));

            if (!string.ReferenceEquals(wholeCodeBlockString, null))
            {
                nativeCodeSequence.WholeCodeBlock = bool.Parse(wholeCodeBlockString);
            }

            string methodName = getContent(element.getElementsByTagName("Method"));

            if (!string.ReferenceEquals(methodName, null))
            {
                nativeCodeSequence.MethodName = methodName;
            }

            string isHookString = getContent(element.getElementsByTagName("IsHook"));

            if (!string.ReferenceEquals(isHookString, null))
            {
                nativeCodeSequence.Hook = bool.Parse(isHookString);
            }

            string isMethodRetuningString = getContent(element.getElementsByTagName("IsMethodReturning"));

            if (!string.ReferenceEquals(isMethodRetuningString, null))
            {
                nativeCodeSequence.MethodReturning = bool.Parse(isMethodRetuningString);
            }

            string codeInstructions = getContent(element.getElementsByTagName("CodeInstructions"));

            loadNativeCodeOpcodes(nativeCodeSequence, codeInstructions);

            // The "Parameters" and "BranchInstruction" have to be parsed after "CodeInstructions"
            // because they are using them (e.g. instruction labels)
            string parametersList = getContent(element.getElementsByTagName("Parameters"));

            if (!string.ReferenceEquals(parametersList, null))
            {
                string[] parameters = parametersList.Split(" *, *", true);
                for (int parameter = 0; parameters != null && parameter < parameters.Length; parameter++)
                {
                    setParameter(nativeCodeSequence, parameter, parameters[parameter].Trim());
                }
            }

            string branchInstructionLabel = getContent(element.getElementsByTagName("BranchInstruction"));

            if (!string.ReferenceEquals(branchInstructionLabel, null))
            {
                if (branchInstructionLabel.StartsWith("@", StringComparison.Ordinal))
                {
                    branchInstructionLabel = branchInstructionLabel.Substring(1);
                }
                int branchInstructionOffset = nativeCodeSequence.getLabelIndex(branchInstructionLabel.Trim());
                if (branchInstructionOffset >= 0)
                {
                    nativeCodeSequence.BranchInstruction = branchInstructionOffset;
                }
                else
                {
                    Compiler.Console.WriteLine(string.Format("BranchInstruction: label '{0}' not found", branchInstructionLabel));
                }
            }

            string beforeCodeInstructions = getContent(element.getElementsByTagName("BeforeCodeInstructions"));

            if (!string.ReferenceEquals(beforeCodeInstructions, null))
            {
                loadBeforeCodeInstructions(nativeCodeSequence, beforeCodeInstructions);
            }

            addNativeCodeSequence(nativeCodeSequence);
        }
示例#9
0
        private void loadNativeCodeOpcodes(NativeCodeSequence nativeCodeSequence, string codeInstructions)
        {
            System.IO.StreamReader reader = new System.IO.StreamReader(new StringReader(codeInstructions));
            if (reader == null)
            {
                return;
            }

            Pattern   codeInstructionPattern = Pattern.compile("\\s*((\\w+)\\s*:?\\s*)?\\[(\\p{XDigit}+)(/(\\p{XDigit}+))?\\].*");
            const int labelGroup             = 2;
            const int opcodeGroup            = 3;
            const int opcodeMaskGroup        = 5;

            try
            {
                while (true)
                {
                    string line = reader.ReadLine();
                    if (string.ReferenceEquals(line, null))
                    {
                        break;
                    }

                    line = line.Trim();
                    if (line.Length > 0)
                    {
                        try
                        {
                            Matcher codeInstructionMatcher = codeInstructionPattern.matcher(line);
                            int     opcode = 0;
                            int     mask   = defaultOpcodeMask;
                            string  label  = null;
                            if (codeInstructionMatcher.matches())
                            {
                                opcode = Utilities.parseAddress(codeInstructionMatcher.group(opcodeGroup));
                                string opcodeMaskString = codeInstructionMatcher.group(opcodeMaskGroup);
                                if (!string.ReferenceEquals(opcodeMaskString, null))
                                {
                                    mask = Utilities.parseAddress(opcodeMaskString);
                                }
                                label = codeInstructionMatcher.group(labelGroup);
                            }
                            else
                            {
                                opcode = Utilities.parseAddress(line.Trim());
                            }

                            nativeCodeSequence.addOpcode(opcode, mask, label);
                        }
                        catch (System.FormatException e)
                        {
                            Compiler.Console.WriteLine(e);
                        }
                    }
                }
            }
            catch (IOException e)
            {
                Compiler.Console.WriteLine(e);
            }
        }
示例#10
0
 public HookCodeInstruction(NativeCodeSequence nativeCodeSequence, CodeInstruction codeInstruction) : base(codeInstruction)
 {
     this.nativeCodeSequence = nativeCodeSequence;
 }