private ICode ExpandTargetAddressOfJumpInstructionTo4Bytes(ICode code, IInstructionWithAddressOperandDecider InstructionWithAddressOperandDecider, IInstructionWithAddressOperandTransform InstructionWithAddressOperandTransform, ICodeTransform codeTransform, IStatistics statistics) { TryTransformInstructionDelegate transformInstructionDelegate = (IAssemblyInstructionForTransformation instruction, IBasicBlock basicBlock, IFunction function, out List <IAssemblyInstructionForTransformation> listOfTransformedInstructions) => { listOfTransformedInstructions = null; var wasTransformed = false; //replace jump instruction to jump instructions with 4 bytes operand= if (InstructionWithAddressOperandDecider.IsJumpInstructionWithRelativeAddressOperand(instruction) && IsJumpInstructionToCodeSection(code, instruction)) { if (InstructionWithAddressOperandTransform.TryTransformJumpInstructionTo4BytesOperandSize(instruction, out IAssemblyInstructionForTransformation transformedInstruction)) { wasTransformed = true; listOfTransformedInstructions = new List <IAssemblyInstructionForTransformation>() { transformedInstruction }; statistics.IncrementInstructionExpanded((uint)(transformedInstruction.Bytes.Length - instruction.Bytes.Length)); } } return(wasTransformed); }; return(codeTransform.Transform(code, transformInstructionDelegate)); }
public InstructionWithAddressOperandTransform(IInstructionWithAddressOperandDecider InstructionWithAddressOperandDecider, IDisassemblerFactory disasmFactory) { m_InstructionWithAddressOperandDecider = InstructionWithAddressOperandDecider ?? throw new ArgumentNullException(nameof(InstructionWithAddressOperandDecider)); m_disasmFactory = disasmFactory ?? throw new ArgumentNullException(nameof(disasmFactory)); m_dictionaryJumpInstructionBytes = FillDictionaryJumpInstructionBytes(); m_dictionaryOfJumpToNegativeJump = FillDictionaryOfJumpToNegativeJump(); }
public CodeParser(IFunctionParser functionParser, ICodeFactory codeFactory, IDisassemblerFactory disassemblerFactory, IInstructionWithAddressOperandDecider jumpTargetAddressDecider) { m_functionParser = functionParser ?? throw new ArgumentNullException(nameof(functionParser)); m_codeFactory = codeFactory ?? throw new ArgumentNullException(nameof(codeFactory)); m_disassemblerFactory = disassemblerFactory ?? throw new ArgumentNullException(nameof(disassemblerFactory)); m_jumpTargetAddressDecider = jumpTargetAddressDecider ?? throw new ArgumentNullException(nameof(jumpTargetAddressDecider)); }
private IReadOnlyList <IFunction> parseFunctions( IInstructionWithAddressOperandDecider instructionWithAddressOperandDecider, IReadOnlyList <IAssemblyInstructionForTransformation> listOfInstructions) { AddressesRange addressesRange = new AddressesRange(listOfInstructions[0].Offset, listOfInstructions.Last().Offset); var jumpTargetAddresses = GetJumpTargetAddresses(instructionWithAddressOperandDecider, listOfInstructions); return(m_functionParser.Parse(listOfInstructions[0], addressesRange, jumpTargetAddresses)); }
public TransformationAddingUnconditionalJump(IInstructionWithAddressOperandDecider instructionWithAddressOperandDecider, IInstructionWithAddressOperandTransform instructionWithAddressOperandTransform, ICodeFactory codeFactory, ICodeInMemoryLayoutFactory codeInMemoryLayoutFactory, ICodeTransform codeTransform, IStatistics statistics, IRelocationDirectoryFromNewCode relocationDirectoryFromNewCode, ICodeParser codeParser) : base(instructionWithAddressOperandDecider, instructionWithAddressOperandTransform, codeFactory, codeInMemoryLayoutFactory, codeTransform, statistics, relocationDirectoryFromNewCode) { m_codeParser = codeParser ?? throw new ArgumentNullException(nameof(codeParser)); }
public TransformationBase(IInstructionWithAddressOperandDecider instructionWithAddressOperandDecider, IInstructionWithAddressOperandTransform instructionWithAddressOperandTransform, ICodeFactory codeFactory, ICodeInMemoryLayoutFactory codeInMemoryLayoutFactory, ICodeTransform codeTransform, IStatistics statistics, IRelocationDirectoryFromNewCode relocationDirectoryFromNewCode) { m_instructionWithAddressOperandDecider = instructionWithAddressOperandDecider ?? throw new ArgumentNullException(nameof(instructionWithAddressOperandDecider)); m_instructionWithAddressOperandTransform = instructionWithAddressOperandTransform ?? throw new ArgumentNullException(nameof(instructionWithAddressOperandTransform)); m_codeInMemoryLayoutFactory = codeInMemoryLayoutFactory ?? throw new ArgumentNullException(nameof(codeInMemoryLayoutFactory)); m_codeTransform = codeTransform ?? throw new ArgumentNullException(nameof(codeTransform)); m_statistics = statistics ?? throw new ArgumentNullException(nameof(statistics)); m_relocationDirectoryFromNewCode = relocationDirectoryFromNewCode ?? throw new ArgumentNullException(nameof(relocationDirectoryFromNewCode)); }
/// <summary> /// Create a dictionary that holds the addresses that appears in dictionary /// </summary> /// <param name="code"></param> /// <param name="addressToInstructionMap"></param> /// <param name="InstructionWithAddressOperandDecider"></param> /// <returns></returns> private Dictionary <ulong, ulong> CreateAddresesInInstructionMap(ICode code, Dictionary <ulong, IAssemblyInstructionForTransformation> addressToInstructionMap, IInstructionWithAddressOperandDecider InstructionWithAddressOperandDecider) { var addressesInInstructionsDictionary = new Dictionary <ulong, ulong>(); //this loop prepares the map, and create entry for each old target foreach (var instruction in code.AssemblyInstructions) { bool result = false; ulong instructionTarget = ulong.MaxValue; bool isJumpTargetOperand = InstructionWithAddressOperandDecider.IsJumpInstructionWithRelativeAddressOperand(instruction) || InstructionWithAddressOperandDecider.IsCallInstructionWithAddressOperand(instruction); bool isAbsoluteAddressInOperand = InstructionWithAddressOperandDecider.IsInstructionWithAbsoluteAddressOperand( instruction, code.CodeInMemoryLayout, out instructionTarget); if (isJumpTargetOperand) { result = instruction.TryGetAbsoluteAddressFromRelativeAddress(out instructionTarget); if (result && !addressToInstructionMap.ContainsKey(instructionTarget)) { throw new ApplicationException($"instruction: '{instruction}' with target address {instructionTarget} do not exist!"); } } else if (isAbsoluteAddressInOperand) { instructionTarget -= (code.CodeInMemoryLayout.ImageBaseAddress + code.CodeInMemoryLayout.CodeVirtualAddress); result = true; } if (result) { //Create entry for the instruction target address addressesInInstructionsDictionary[instructionTarget] = 0; } } //add the entry point address to the map, becuase we need to update its new address addressesInInstructionsDictionary[code.CodeInMemoryLayout.EntryPointOffset] = 0; return(addressesInInstructionsDictionary); }
public TransformationAddingJunkBytes(IInstructionWithAddressOperandDecider instructionWithAddressOperandDecider, IInstructionWithAddressOperandTransform instructionWithAddressOperandTransform, ICodeInMemoryLayoutFactory codeInMemoryLayoutFactory, ICodeFactory codeFactory, IInstructionWithAddressOperandTransform jumpInstrucionTransform, ICodeTransform codeTransform, IStatistics statistics, IRelocationDirectoryFromNewCode relocationDirectoryFromNewCode, IJunkBytesProvider junkBytesProvider, IDisassemblerFactory disassemblerFactory) : base(instructionWithAddressOperandDecider, instructionWithAddressOperandTransform, codeFactory, codeInMemoryLayoutFactory, codeTransform, statistics, relocationDirectoryFromNewCode) { m_junkBytesProvider = junkBytesProvider ?? throw new ArgumentNullException(nameof(junkBytesProvider)); m_disassemblerFactory = disassemblerFactory ?? throw new ArgumentNullException(nameof(disassemblerFactory)); }
private void ValidateCodeJumpInstructions(ICode code, IInstructionWithAddressOperandDecider InstructionWithAddressOperandDecider) { var map = new Dictionary <ulong, IAssemblyInstructionForTransformation>(); foreach (var instruction in code.AssemblyInstructions) { map.Add(instruction.Offset, instruction); } foreach (var instruction in code.AssemblyInstructions) { if (InstructionWithAddressOperandDecider.IsJumpInstructionWithRelativeAddressOperand(instruction)) { ulong jumpTarget = instruction.GetAbsoluteAddressFromRelativeAddress(); if (!map.ContainsKey(jumpTarget)) { throw new ApplicationException("code is incorrect, jump target is to no instruction"); } } } }
private Dictionary <ulong, ulong> GetJumpTargetAddresses( IInstructionWithAddressOperandDecider instructionWithAddressOperandDecider, IReadOnlyList <IAssemblyInstructionForTransformation> listOfInstructions) { var addressesInInstructionsDictionary = new Dictionary <ulong, ulong>(); //create the map, and create entry for each jump target foreach (var instruction in listOfInstructions) { ulong instructionTarget = ulong.MaxValue; bool isJumpTargetOperand = instructionWithAddressOperandDecider.IsJumpInstructionWithRelativeAddressOperand(instruction) || instructionWithAddressOperandDecider.IsUnconditionalJumpInstruction(instruction.Mnemonic) || instructionWithAddressOperandDecider.IsCallInstructionWithAddressOperand(instruction); if (!isJumpTargetOperand) { continue; } bool result = false; result = instruction.TryGetAbsoluteAddressFromRelativeAddress(out instructionTarget); if (!result) { result = instruction.TryGetAbsoluteAddress(out instructionTarget); } if (!result) { continue; } addressesInInstructionsDictionary[instructionTarget] = 0; } return(addressesInInstructionsDictionary); }
private ICode UpdateJumpInstructionsTargetAddress(ICode code, IInstructionWithAddressOperandDecider InstructionWithAddressOperandDecider, IInstructionWithAddressOperandTransform InstructionWithAddressOperandTransform, ICodeTransform codeTransform, Dictionary <ulong, IAssemblyInstructionForTransformation> addressToInstructionMap, ICodeInMemoryLayoutFactory codeInMemoryLayoutFactory, IRelocationDirectoryFromNewCode relocationDirectoryFromNewCode, Dictionary <ulong, ulong> jumpInstructionsMap) { if (code == null) { throw new ArgumentNullException(nameof(code)); } if (code.AssemblyInstructions == null || code.AssemblyInstructions.Count == 0) { throw new ArgumentException("code.AssemblyInstructions"); } if (InstructionWithAddressOperandDecider == null) { throw new ArgumentNullException(nameof(InstructionWithAddressOperandDecider)); } if (InstructionWithAddressOperandTransform == null) { throw new ArgumentNullException(nameof(InstructionWithAddressOperandTransform)); } if (codeInMemoryLayoutFactory == null) { throw new ArgumentNullException(nameof(codeInMemoryLayoutFactory)); } if (relocationDirectoryFromNewCode == null) { throw new ArgumentNullException(nameof(relocationDirectoryFromNewCode)); } //this is used map for the new and old addresses var oldToNewAddressDictionary = jumpInstructionsMap; //PASS 1: //map old instruction address to new address, //because new instructions are going to be added in between, and other instructions //are going to be expanded. ulong newOffset = 0; foreach (var instruction in code.AssemblyInstructions) { //look for each byte in instruction, because the addresses in operand //can be an instruction or somewhere INSIDE the instruction //for example: movzx eax, byte [edx+0x411d8c] //where edx = 0xbc, and 0x411d8c is no instruction for (ulong i = 0; i < (ulong)instruction.Bytes.Length; i++) { if (oldToNewAddressDictionary.ContainsKey(instruction.Offset + i)) { oldToNewAddressDictionary[instruction.Offset + i] = newOffset + i; } } newOffset = newOffset + (ulong)instruction.Bytes.Length; } //PASS 2:Create the new relocation directory var newRelocationDirectoryInfo = relocationDirectoryFromNewCode.CreateNewRelocationDirectoryInfo(code); //PASS 3: //set the target jump address to the new address and then change the instruction offset newOffset = 0; ulong newProgramCounter = 0; TryTransformInstructionDelegate tryTransformDelegate = (IAssemblyInstructionForTransformation instruction, IBasicBlock basicBlock, IFunction function, out List <IAssemblyInstructionForTransformation> transformedInstructions) => { transformedInstructions = null; var retVal = false; //old jump target address or old address in operand ulong oldAddress; newProgramCounter = newProgramCounter + (ulong)instruction.Bytes.Length; bool isJumpTargetOperand = InstructionWithAddressOperandDecider.IsJumpInstructionWithRelativeAddressOperand(instruction) || InstructionWithAddressOperandDecider.IsCallInstructionWithAddressOperand(instruction); bool isAbsoluteAddressInOperand = InstructionWithAddressOperandDecider.IsInstructionWithAbsoluteAddressOperand(instruction, code.CodeInMemoryLayout, out oldAddress); if (isJumpTargetOperand) { transformedInstructions = new List <IAssemblyInstructionForTransformation>(); oldAddress = instruction.GetAbsoluteAddressFromRelativeAddress(); if (!oldToNewAddressDictionary.TryGetValue(oldAddress, out ulong newTargetAddress)) { throw new ApplicationException("jump instruction target should exist on map"); } var transformedInstruction = InstructionWithAddressOperandTransform. CreateJumpInstructionWithNewTargetAddress(instruction, newProgramCounter, newOffset, newTargetAddress); transformedInstructions.Add(transformedInstruction); retVal = true; } else if (isAbsoluteAddressInOperand) { transformedInstructions = new List <IAssemblyInstructionForTransformation>(); ulong virtualOldAddress = (oldAddress - code.CodeInMemoryLayout.ImageBaseAddress) - code.CodeInMemoryLayout.CodeVirtualAddress; if (!oldToNewAddressDictionary.TryGetValue(virtualOldAddress, out ulong newAddressInOperand)) { throw new ApplicationException("jump instruction target should exist on map"); } newAddressInOperand += (code.CodeInMemoryLayout.ImageBaseAddress + code.CodeInMemoryLayout.CodeVirtualAddress); var transformedInstruction = InstructionWithAddressOperandTransform. CreateInstructionWithNewAddress(code, instruction, newProgramCounter, newOffset, oldAddress, newAddressInOperand); transformedInstructions.Add(transformedInstruction); retVal = true; } else { instruction.SetPC(newProgramCounter); instruction.SetOffset(newOffset); } newOffset = newProgramCounter; return(retVal); }; //take care for updating the new entry point address, and new relocation diretory //define a factory to create the new code in memory layout instance Func <ICodeInMemoryLayout> codeInMemoryLayoutFactoryDelegate = () => codeInMemoryLayoutFactory.Create( code.CodeInMemoryLayout.ImageBaseAddress, code.CodeInMemoryLayout.OffsetOfCodeInBytes, newProgramCounter, code.CodeInMemoryLayout.CodePhysicalSizeInBytes, oldToNewAddressDictionary[code.CodeInMemoryLayout.EntryPointOffset], code.CodeInMemoryLayout.CodeVirtualAddress, newRelocationDirectoryInfo); var newCode = codeTransform.Transform(code, tryTransformDelegate, codeInMemoryLayoutFactoryDelegate); return(newCode); }
public BasicBlockEpilogParser(IInstructionWithAddressOperandDecider jumpInstructionDecider) { m_jumpInstructionDecider = jumpInstructionDecider ?? throw new ArgumentNullException("jumpInstructionDecider"); }