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); }
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)); }
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))); }
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)); }
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)); }
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)); }
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); }