public bool IsInstructionWithAbsoluteAddressOperand(
            IAssemblyInstructionForTransformation instruction,
            ICodeInMemoryLayout codeInMemoryLayout, out ulong addressOperand)
        {
            var codeBeginAddress = codeInMemoryLayout.CodeVirtualAddress +
                                   codeInMemoryLayout.ImageBaseAddress;
            var codeEndAddress = codeInMemoryLayout.CodeVirtualAddress +
                                 codeInMemoryLayout.CodePhysicalSizeInBytes +
                                 codeInMemoryLayout.ImageBaseAddress;

            addressOperand = ulong.MaxValue;

            if (instruction.Operands == null || instruction.Operands.Length == 0)
            {
                return(false);
            }
            for (int i = 0; i < instruction.Operands.Length; i++)
            {
                if (instruction.Operands[i].SignedValue >= (long)codeBeginAddress &&
                    instruction.Operands[i].SignedValue < (long)codeEndAddress)
                {
                    if (instruction.Mnemonic == ud_mnemonic_code.UD_Ijmp)
                    {
                        System.Diagnostics.Debugger.Break();
                    }
                    addressOperand = (ulong)instruction.Operands[i].SignedValue;
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 2
0
 public Code(IReadOnlyList <IAssemblyInstructionForTransformation> assemblyInstructions,
             IReadOnlyList <IFunction> functions,
             ICodeInMemoryLayout codeInMemoryLayout)
 {
     AssemblyInstructions = assemblyInstructions ?? throw new ArgumentNullException(nameof(assemblyInstructions));
     Functions            = functions ?? throw new ArgumentNullException(nameof(functions));
     CodeInMemoryLayout   = codeInMemoryLayout ?? throw new ArgumentNullException(nameof(codeInMemoryLayout));
 }
Ejemplo n.º 3
0
 public ICode Create(IReadOnlyList <IAssemblyInstructionForTransformation> assemblyInstructions,
                     IReadOnlyList <IFunction> functions,
                     ICodeInMemoryLayout codeInMemoryLayout)
 {
     return(Container.Container.Resolve <ICode>(
                new Parameter(nameof(assemblyInstructions), assemblyInstructions),
                new Parameter(nameof(functions), functions),
                new Parameter(nameof(codeInMemoryLayout), codeInMemoryLayout)));
 }
Ejemplo n.º 4
0
        public ICode Create(IAssemblyInstructionForTransformation firstInstruction,
                            IReadOnlyList <IFunction> functions,
                            ICodeInMemoryLayout codeInMemoryLayout)
        {
            if (firstInstruction == null)
            {
                throw new ArgumentNullException(nameof(firstInstruction));
            }
            var instruction      = firstInstruction;
            var instructionsList = new List <IAssemblyInstructionForTransformation>();

            return(Create(instructionsList, functions, codeInMemoryLayout));
        }
Ejemplo n.º 5
0
        public ICode ParseCode(IReadOnlyList <IAssemblyInstructionForTransformation> listOfInstructions,
                               ICodeInMemoryLayout codeInMemoryLayout)
        {
            if (listOfInstructions == null)
            {
                throw new ArgumentNullException(nameof(listOfInstructions));
            }
            if (codeInMemoryLayout == null)
            {
                throw new ArgumentNullException(nameof(codeInMemoryLayout));
            }
            IReadOnlyList <IFunction> listOfFunctions = parseFunctions(m_jumpTargetAddressDecider, listOfInstructions);

            return(m_codeFactory.Create(listOfInstructions, listOfFunctions, codeInMemoryLayout));
        }
Ejemplo n.º 6
0
        public ICode ParseCode(byte[] code, ICodeInMemoryLayout codeInMemoryLayout)
        {
            if (code == null || code.Length == 0)
            {
                throw new ArgumentNullException(nameof(code), "code buffer can not be empty nor null");
            }
            if (codeInMemoryLayout == null)
            {
                throw new ArgumentNullException(nameof(codeInMemoryLayout));
            }
            IReadOnlyList <IAssemblyInstructionForTransformation> listOfInstructions = ParseInstructions(code);
            IReadOnlyList <IFunction> listOfFunctions = parseFunctions(m_jumpTargetAddressDecider, listOfInstructions);

            return(m_codeFactory.Create(listOfInstructions, listOfFunctions, codeInMemoryLayout));
        }
Ejemplo n.º 7
0
        public static bool TryGetAbsoluteAddressFromAnyOperand(this IInstruction instruction,
                                                               ICodeInMemoryLayout codeInMemoryLayout,
                                                               out ulong targetAddress)
        {
            if (instruction == null)
            {
                throw new ArgumentNullException(nameof(instruction));
            }
            if (instruction.Operands == null)
            {
                throw new ArgumentNullException(nameof(instruction) + "Operands");
            }
            if (instruction.Operands.Count() == 0)
            {
                throw new ArgumentException("parameters operands can be 0");
            }
            if (codeInMemoryLayout == null)
            {
                throw new ArgumentNullException(nameof(codeInMemoryLayout), "code can not be null");
            }

            targetAddress = ulong.MaxValue;
            var startOfCodeAddress = codeInMemoryLayout.ImageBaseAddress +
                                     codeInMemoryLayout.CodeVirtualAddress;
            var endOfCodeAddress = startOfCodeAddress +
                                   codeInMemoryLayout.CodeActualSizeInBytes;

            for (int i = 0; i < instruction.Operands.Length; i++)
            {
                if ((ulong)instruction.Operands[i].SignedValue >= startOfCodeAddress &&
                    (ulong)instruction.Operands[i].SignedValue < endOfCodeAddress)
                {
                    targetAddress = (ulong)instruction.Operands[i].SignedValue;
                    return(true);
                }
            }

            return(false);
        }
        public static ICodeInMemoryLayout GetCodeInMemoryLayout(this PeFile peFile)
        {
            if (peFile == null)
            {
                throw new ArgumentNullException(nameof(peFile));
            }
            ICodeInMemoryLayout codeInMemoryLayout = null;

            var optionalHeader = peFile.ImageNtHeaders.OptionalHeader;
            IMAGE_SECTION_HEADER codeSectionHeader = null;

            foreach (var sectionHeader in peFile.ImageSectionHeaders)
            {
                if ((sectionHeader.Characteristics & (uint)PeNet.Constants.SectionFlags.IMAGE_SCN_CNT_CODE) != 0 &&
                    sectionHeader.SizeOfRawData > 0)
                {
                    codeSectionHeader = sectionHeader;

                    var relocationDirectorySize = peFile.ImageNtHeaders.OptionalHeader.
                                                  DataDirectory[(int)Constants.DataDirectoryIndex.BaseReloc].Size;
                    var relocationDirectoryOffset = peFile.ImageNtHeaders.OptionalHeader.
                                                    DataDirectory[(int)Constants.DataDirectoryIndex.BaseReloc].VirtualAddress.
                                                    RVAtoFileMapping(peFile.ImageSectionHeaders);
                    var codeInMemoryLayoutFactory = Container.Container.Resolve <ICodeInMemoryLayoutFactory>();
                    var addressesOfCodeInData     = peFile.GetAddressesOfCodeInData(sectionHeader);

                    if (peFile.ImageRelocationDirectory != null)
                    {
                        var relocationInfo = Container.Container.Resolve <IRelocationDirectoryInfoFactory>().Create(
                            peFile.ImageRelocationDirectory,
                            relocationDirectorySize,
                            peFile.Buff,
                            relocationDirectoryOffset,
                            addressesOfCodeInData);

                        codeInMemoryLayout = codeInMemoryLayoutFactory.Create(
                            peFile.ImageNtHeaders.OptionalHeader.ImageBase,
                            codeSectionHeader.PointerToRawData,
                            codeSectionHeader.VirtualSize,
                            codeSectionHeader.SizeOfRawData,
                            codeSectionHeader.PointerToRawData +
                            optionalHeader.AddressOfEntryPoint - sectionHeader.VirtualAddress,
                            codeSectionHeader.VirtualAddress,
                            relocationInfo);
                    }
                    else
                    {
                        codeInMemoryLayout = codeInMemoryLayoutFactory.Create(
                            peFile.ImageNtHeaders.OptionalHeader.ImageBase,
                            codeSectionHeader.PointerToRawData,
                            codeSectionHeader.VirtualSize,
                            codeSectionHeader.SizeOfRawData,
                            codeSectionHeader.PointerToRawData +
                            optionalHeader.AddressOfEntryPoint - sectionHeader.VirtualAddress,
                            codeSectionHeader.VirtualAddress,
                            null);
                    }


                    break;
                }
            }

            return(codeInMemoryLayout);
        }
        public ICode Transform(ICode code, TryTransformInstructionDelegate transformInstructionDelegate,
                               Func <ICodeInMemoryLayout> codeInLayoutFactoryDelegate = null)
        {
            var newInstructionsList        = new List <IAssemblyInstructionForTransformation>();
            var newFunctionsList           = new List <IFunction>();
            var instructionListIterator    = code.AssemblyInstructions.GetEnumerator();
            var lastInstructionInLastBlock = code.Functions.Last().BasicBlocks.Last().AssemblyInstructions.Last();
            IAssemblyInstructionForTransformation previousInstruction = null;
            bool afterInstructionOfLastBlock = false;

            //move to the first instruction
            instructionListIterator.MoveNext();

            //iterate through all functions
            foreach (var function in code.Functions)
            {
                var basicBlockList = new List <IBasicBlock>();
                //iterate through all basic block
                foreach (var basicBlock in function.BasicBlocks)
                {
                    var instructionsListOfBlock = new List <IAssemblyInstructionForTransformation>();
                    foreach (var instructionInBasicBlock in basicBlock.AssemblyInstructions)
                    {
                        bool isInstructionInBasicBlock;
                        bool done = false;

                        //transform instructions from instruction list.
                        //this loop transform:
                        //1. instructions before the basic block which are left to process
                        //2. instructions inside a basic block
                        //3. instructions after the last basic block
                        while (!done)
                        {
                            isInstructionInBasicBlock = instructionListIterator.Current == instructionInBasicBlock;
                            IAssemblyInstructionForTransformation instructionToTransform =
                                instructionListIterator.Current;

                            //perfom the transformation of the instruction
                            List <IAssemblyInstructionForTransformation> transformedInstructionList;
                            var wasTransformed = transformInstructionDelegate(instructionToTransform,
                                                                              isInstructionInBasicBlock ? basicBlock : null,
                                                                              isInstructionInBasicBlock ? function : null,
                                                                              out transformedInstructionList);

                            if (wasTransformed)
                            {
                                if (transformedInstructionList.Count == 0)
                                {
                                    throw new ApplicationException("transformation should return at least one instruction");
                                }

                                if (isInstructionInBasicBlock)
                                {
                                    instructionsListOfBlock.AddRange(transformedInstructionList);
                                }
                                newInstructionsList.AddRange(transformedInstructionList);

                                if (previousInstruction != null)
                                {
                                    transformedInstructionList[0].PreviousInstruction = previousInstruction;
                                    previousInstruction.NextInstruction = transformedInstructionList[0];
                                }

                                if (transformedInstructionList.Count > 1)
                                {
                                    for (int i = 1; i < transformedInstructionList.Count; i++)
                                    {
                                        transformedInstructionList[i].PreviousInstruction = transformedInstructionList[i - 1];
                                        transformedInstructionList[i - 1].NextInstruction = transformedInstructionList[i];
                                    }
                                }

                                previousInstruction = transformedInstructionList.Last();
                            }
                            else
                            {
                                if (isInstructionInBasicBlock)
                                {
                                    instructionsListOfBlock.Add(instructionToTransform);
                                }
                                newInstructionsList.Add(instructionToTransform);
                                if (previousInstruction != null)
                                {
                                    instructionToTransform.PreviousInstruction = previousInstruction;
                                    previousInstruction.NextInstruction        = instructionToTransform;
                                }
                                previousInstruction = instructionToTransform;
                            }

                            //check weather this is the last instruction in the last basic block
                            if (isInstructionInBasicBlock && !afterInstructionOfLastBlock)
                            {
                                //The transformed instruction is now in the end of program
                                //after the last basic block instruction
                                afterInstructionOfLastBlock = (instructionToTransform == lastInstructionInLastBlock);
                            }

                            instructionListIterator.MoveNext();

                            //stop transforming intructions in loop when all instruction in scope are processed
                            done = (isInstructionInBasicBlock ||
                                    instructionListIterator.Current == null);

                            //keep transforming after the last basic block instruction to the end of the program
                            if (afterInstructionOfLastBlock && instructionListIterator.Current != null)
                            {
                                done = false;
                            }
                        }
                    }

                    IBasicBlock newBasicBlock = m_basicBlockFactory.Create(instructionsListOfBlock);
                    basicBlockList.Add(newBasicBlock);
                }

                var newFunction = m_functionFactory.Create(basicBlockList.First().AssemblyInstructions.First(),
                                                           basicBlockList.Last().AssemblyInstructions.Last(),
                                                           basicBlockList);
                newFunctionsList.Add(newFunction);
            }


            //if there is a factory to create a new code in memory layout structure than use it, otherwise use
            //the original code layout in memrory instance
            ICodeInMemoryLayout codeInMemoryLayout = codeInLayoutFactoryDelegate == null ? code.CodeInMemoryLayout:codeInLayoutFactoryDelegate();

            //return m_codeFactory.Create(newInstructionsList, newFunctionsList,codeInMemoryLayout);
            var newcode = m_codeFactory.Create(newInstructionsList, newFunctionsList, codeInMemoryLayout);

            ValidateNewCode(newcode);
            return(newcode);
        }