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));
        }
        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);
        }
        protected override ICode TransformCode(ICode code,
                                               Dictionary <ulong, IAssemblyInstructionForTransformation> addressToInstructionMap,
                                               Dictionary <ulong, ulong> addressesInInstructionMap)
        {
            //inicate weather to try insert junk in the next instruction.
            //a junk will be inserted if the instruction right after is the first in basic block
            bool insertJunk = false;


            //define the delegate that transform a single instruction.
            //this delegate is passes to a code transformer that execute this delegate on each assembly instruction
            TryTransformInstructionDelegate transformInstructionDelegate =
                (IAssemblyInstructionForTransformation instruction, IBasicBlock basicBlock, IFunction function,
                 out List <IAssemblyInstructionForTransformation> listOfTransformedInstructions) =>
            {
                var wasTransformed = false;
                listOfTransformedInstructions = null;

                //insert junk only inside a basic block
                if (basicBlock == null)
                {
                    //if the should insert junk is set, but next instructions are not nops turn off the junk
                    //insertion flag, because there is no basic block to insert the junk into
                    if (!instruction.IsNopInstruction())
                    {
                        insertJunk = false;
                    }
                    return(wasTransformed);
                }

                //try insert junk instruction
                if (insertJunk)
                {
                    if (TryGenerateJunkInstruction(basicBlock, m_junkBytesProvider, m_statistics,
                                                   out IAssemblyInstructionForTransformation junkInstruction))
                    {
                        m_statistics.IncrementAddedInstructions(1, (uint)junkInstruction.Bytes.Length);
                        listOfTransformedInstructions = new List <IAssemblyInstructionForTransformation>
                        {
                            //insert junk insruction before the first instruction of the basic block
                            junkInstruction,
                            instruction
                        };
                        insertJunk     = false;
                        wasTransformed = true;
                    }
                    //can not insert junk in the basic block. do not try to insert junk bytes
                    else
                    {
                        insertJunk = false;
                        return(wasTransformed);
                    }
                }

                //The it is last instruction in basic block, and if it is unconditional
                if (basicBlock.AssemblyInstructions.Last() == instruction)
                {
                    if (m_instructionWithAddressOperandDecider.IsUnconditionalJumpInstruction(instruction.Mnemonic) ||
                        m_instructionWithAddressOperandDecider.IsReturnInstruction(instruction))
                    {
                        insertJunk = true;
                    }
                }

                return(wasTransformed);
            };


            return(m_codeTransform.Transform(code, transformInstructionDelegate));
        }
        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);
        }
        protected override ICode TransformCode(ICode code, Dictionary <ulong,
                                                                       IAssemblyInstructionForTransformation> addressToInstructionMap,
                                               Dictionary <ulong, ulong> addressesInInstructionMap)
        {
            //define the delegate that transform a single instruction.
            //this delegate is passes to a code transformer that execute this delegate on each assembly instruction
            TryTransformInstructionDelegate transformInstructionDelegate =
                (IAssemblyInstructionForTransformation instruction, IBasicBlock basicBlock, IFunction function,
                 out List <IAssemblyInstructionForTransformation> listOfTransformedInstructions) =>
            {
                listOfTransformedInstructions = null;

                //change unconditional jumps only inside a basic block
                if (basicBlock == null)
                {
                    return(false);
                }
                //transformation made only on conditional jump intructions
                if (!m_instructionWithAddressOperandDecider.IsConditionalJumpInstruction(instruction.Mnemonic))
                {
                    return(false);
                }

                //because the new inserted jump instruction target address is the instruction after
                if (instruction.NextInstruction == null)
                {
                    return(false);
                }

                //transform an unconditional jump instruction.
                //jump by condition C to address A
                //instruction after
                //=>
                // jump by inverse condition to address of instruction after
                //Jump to address A
                //instruction after

                //for example
                //            instruction address    instruction    operands
                //            000017ba               ja             0x17e7
                //            000017c0               mov            ecx, [eax * 4 + 0x41a00c]
                // is tranformed into
                //            000017ba               jbe            000017c5
                //            000017c0               jmp            0x17e7
                //            000017c5               mov            ecx, [eax * 4 + 0x41a00c]



                //IGenericTransform.UpdateJumpInstructionsTargetAddress updates the target address
                //of all instructions to the new one so, this transformation create those instructions
                //            instruction address    instruction    operands
                //            000017ba               jbe            000017c0 (will be updated to 000017c5)
                //            000017ba               jmp            0x17e7 (will updated to 0x17e7 +5)
                //            000017c0               mov            ecx, [eax * 4 + 0x41a00c]


                //create a new negative jump to the next instruction
                IAssemblyInstructionForTransformation newConditionalJumpInstruction;
                if (!m_instructionWithAddressOperandTransform.TryCreateNegativeJumpIntruction(
                        instruction, 0, out newConditionalJumpInstruction))
                {
                    return(false);
                }
                newConditionalJumpInstruction.SetOffset(instruction.Offset);
                newConditionalJumpInstruction.SetPC(instruction.PC);

                //create a new jump instruction to the same address as the original condition jump condition
                var jumpAddress        = instruction.GetRelativeAddress();
                var newJumpInstruction = m_instructionWithAddressOperandTransform.
                                         CreateUnconditionalJumpInstruction(jumpAddress);
                newJumpInstruction.IsNew = true;
                newJumpInstruction.SetPC(instruction.PC);
                newJumpInstruction.SetOffset(instruction.Offset);

                listOfTransformedInstructions = new List <IAssemblyInstructionForTransformation>()
                {
                    newConditionalJumpInstruction, newJumpInstruction
                };

                //update dictionary of target addresses that apears in program.
                //this addresses have to be replaced later in the instructions that contain them (as operand).
                addressesInInstructionMap[instruction.NextInstruction.Offset] = 0;

                var addedBytesForConditionalJump = instruction.Bytes.Length -
                                                   newConditionalJumpInstruction.Bytes.Length;
                m_statistics.IncrementAddedInstructions(1,
                                                        (uint)(newJumpInstruction.Bytes.Length + addedBytesForConditionalJump));
                return(true);
            };

            var newCode = m_codeTransform.Transform(code, transformInstructionDelegate);

            //after this transformation there are more basic blocks, so parse them again
            return(m_codeParser.ParseCode(newCode.AssemblyInstructions, newCode.CodeInMemoryLayout));
        }