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