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