public static CodeFeatures GetFeatures(Instruction instruction) { CodeFeatures features = CodeFeatures.None; switch (instruction.Operation) { case Operation.INT: case Operation.INTO: features |= CodeFeatures.HasInterrupt; break; case Operation.RET: features |= CodeFeatures.HasRETN; break; case Operation.RETF: features |= CodeFeatures.HasRETF; break; case Operation.IRET: features |= CodeFeatures.HasIRET; break; case Operation.FCLEX: features |= CodeFeatures.HasFpu; break; } return(features); }
public static CodeFeatures GetFeatures(IEnumerable <Instruction> instructions) { CodeFeatures features = CodeFeatures.None; foreach (Instruction instruction in instructions) { features |= GetFeatures(instruction); } return(features); }
public BasicBlock(Address begin, Address end, BasicBlockType type, BinaryImage image) { if (begin.Segment != end.Segment) { throw new ArgumentException("Basic block must be on the same segment."); } this.location = begin; this.length = end.Offset - begin.Offset; this.type = type; this.features = CodeFeaturesHelper.GetFeatures(GetInstructions(image)); }
public void AddBasicBlock(BasicBlock block) { basicBlocks.Add(block, block); this.features |= block.Features; }
/// <summary> /// Creates a procedure with the given entry point. /// </summary> /// <returns></returns> protected virtual Procedure CreateProcedure(Address entryPoint) { // If there is already a procedure defined at the given entry // point, return that procedure. Procedure proc = Procedures.Find(entryPoint); if (proc != null) { return(proc); } // Create a procedure at the entry point. The entry point must be // be the first byte of a basic block, or otherwise some flow // analysis error must have occurred. On the other hand, note // that multiple procedures may share one or more basic blocks // as part of their implementation. proc = new Procedure(entryPoint); AddBasicBlocksToProcedure(proc); //proc.Name = "TBD"; // To determine the call type of the procedure, examine the // features of the basic blocks. CodeFeatures features = proc.Features; #if false foreach (BasicBlock block in proc.BasicBlocks) { features |= block.Features; } #endif CodeFeatures callFeatures = features & ( CodeFeatures.HasRETN | CodeFeatures.HasRETF | CodeFeatures.HasIRET); switch (callFeatures) { case CodeFeatures.HasRETN: proc.ReturnType |= ReturnType.Near; break; case CodeFeatures.HasRETF: proc.ReturnType |= ReturnType.Far; break; case CodeFeatures.HasIRET: proc.ReturnType |= ReturnType.Interrupt; break; case CodeFeatures.None: AddError(entryPoint, ErrorCode.InconsistentCall, "Procedure at entry point {0} does not contain a RET/RETF/IRET instruction.", entryPoint); break; default: AddError(entryPoint, ErrorCode.InconsistentCall, "Procedure at entry point {0} contains inconsistent return instructions: {1}.", entryPoint, callFeatures); break; } return(proc); }