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 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);
        }
示例#6
0
        public DebugInfo GetDebugInfo(ICodeTransform transform)
        {
            CodeBuilder     Builder = CodeBuilder.Instance;
            IBlockStatement block   = Builder.BlockStmt();
            bool            includeStatementNumbers = false;

            if (includeStatementNumbers)
            {
                List <List <IStatement> > stmts = new List <List <IStatement> >();
                foreach (var entry in indexOf)
                {
                    IStatement ist   = entry.Key;
                    int        index = entry.Value;
                    while (stmts.Count <= index)
                    {
                        stmts.Add(new List <IStatement>());
                    }
                    stmts[index].Add(ist);
                }
                for (int i = 0; i < stmts.Count; i++)
                {
                    block.Statements.Add(Builder.CommentStmt(i.ToString()));
                    foreach (var ist in stmts[i])
                    {
                        block.Statements.Add(ist);
                    }
                }
            }
            for (int edge = 0; edge < graph.EdgeCount(); edge++)
            {
                ICollection <IVariableDeclaration> list = prohibitedLoopVars[edge];
                IBlockStatement body = Builder.BlockStmt();
                body.Statements.Add(GetStatement(graph.SourceOf(edge)));
                body.Statements.Add(GetStatement(graph.TargetOf(edge)));
                if (list != null)
                {
                    foreach (IVariableDeclaration ivd in list)
                    {
                        IForEachStatement ifes = Builder.ForEachStmt();
                        ifes.Variable   = ivd;
                        ifes.Expression = null;
                        ifes.Body       = body;
                        body            = Builder.BlockStmt();
                        body.Statements.Add(ifes);
                    }
                }
                if (body.Statements.Count == 1)
                {
                    block.Statements.Add(body.Statements[0]);
                }
                else
                {
                    block.Statements.Add(body);
                }
            }
            DebugInfo info = new DebugInfo();

            info.Transform = transform;
            info.Name      = "LoopMergingInfo";
            info.Value     = block;
            return(info);
        }
示例#7
0
 public CodeTransformer(ICodeTransform t)
 {
     Transform = t;
 }
示例#8
0
 public void AddTransform(ICodeTransform ict)
 {
     transformers.Add(new CodeTransformer(ict));
 }