protected override Address ResolveFlowInstructionTarget(PointerOperand operand) { SymbolicTarget symbolicTarget = operand.Tag as SymbolicTarget; if (symbolicTarget != null) { Address symbolicAddress = ResolveSymbolicTarget(symbolicTarget); return(symbolicAddress); } return(base.ResolveFlowInstructionTarget(operand)); }
protected override Address ResolveFlowInstructionTarget(PointerOperand operand) { // TBD: need to perform mapping from segment address to segment id. // TBD: need to check fixups and avoid absolute calls. int segment = executable.Image.MapFrameToSegment(operand.Segment.Value); return new Address(segment, (int)operand.Offset.Value); //int segmentId = executable.GetSegment((int)operand.Segment.Value); //return new Address(segmentId, (int)operand.Offset.Value); //return new Address(operand.Segment.Value, (int)operand.Offset.Value); }
protected override Address ResolveFlowInstructionTarget(PointerOperand operand) { // TBD: need to perform mapping from segment address to segment id. // TBD: need to check fixups and avoid absolute calls. int segment = executable.Image.MapFrameToSegment(operand.Segment.Value); return(new Address(segment, (int)operand.Offset.Value)); //int segmentId = executable.GetSegment((int)operand.Segment.Value); //return new Address(segmentId, (int)operand.Offset.Value); //return new Address(operand.Segment.Value, (int)operand.Offset.Value); }
public virtual string FormatOperand(PointerOperand operand) { string str = FormatFixableLocation(operand); if (str != null) return str; else return string.Format("{0:X4}:{1:X4}", operand.Segment.Value, operand.Offset.Value); }
protected virtual Address ResolveFlowInstructionTarget(PointerOperand operand) { // Since there's no mapping from absolute frame number to // a segment, the base implementation always returns Invalid. return(Address.Invalid); }
protected override Address ResolveFlowInstructionTarget(PointerOperand operand) { SymbolicTarget symbolicTarget = operand.Tag as SymbolicTarget; if (symbolicTarget != null) { Address symbolicAddress = ResolveSymbolicTarget(symbolicTarget); return symbolicAddress; } return base.ResolveFlowInstructionTarget(operand); }
protected virtual Address ResolveFlowInstructionTarget(PointerOperand operand) { // Since there's no mapping from absolute frame number to // a segment, the base implementation always returns Invalid. return Address.Invalid; }
/// <summary> /// Analyzes an instruction and returns a xref if the instruction is /// one of the branch/call/jump instructions. Note that the 'no-jump' /// branch of a conditional jump instruction is not returned. The /// caller must manually create such a xref if needed. /// </summary> /// <param name="instruction">The instruction to analyze.</param> /// <returns>XRef if the instruction is a b/c/j instruction; /// null otherwise.</returns> /// TBD: address wrapping if IP is above 0xFFFF is not handled. It should be. private XRef AnalyzeFlowInstruction(Pointer start, Instruction instruction) { Operation op = instruction.Operation; // Find the type of branch/call/jump instruction being processed. // // Note: If the instruction is a conditional jump, we assume that // the condition may be true or false, so that both "jump" and // "no jump" is a reachable branch. If the code is malformed such // that either branch will never be executed, the analysis may not // work correctly. // // Note: If the instruction is a function call, we assume that the // subroutine being called will return. If the subroutine never // returns the analysis may not work correctly. XRefType bcjType; switch (op) { case Operation.JO: case Operation.JNO: case Operation.JB: case Operation.JAE: case Operation.JE: case Operation.JNE: case Operation.JBE: case Operation.JA: case Operation.JS: case Operation.JNS: case Operation.JP: case Operation.JNP: case Operation.JL: case Operation.JGE: case Operation.JLE: case Operation.JG: case Operation.JCXZ: case Operation.LOOP: case Operation.LOOPZ: case Operation.LOOPNZ: bcjType = XRefType.ConditionalJump; break; case Operation.JMP: bcjType = XRefType.NearJump; break; case Operation.JMPF: bcjType = XRefType.FarJump; break; case Operation.CALL: bcjType = XRefType.NearCall; break; case Operation.CALLF: bcjType = XRefType.FarCall; break; default: // Not a b/c/j instruction; do nothing. return(null); } // Create a cross-reference depending on the type of operand. if (instruction.Operands[0] is RelativeOperand) // near jump/call to relative address { RelativeOperand opr = (RelativeOperand)instruction.Operands[0]; return(new XRef( type: bcjType, source: start, target: start.IncrementWithWrapping(instruction.EncodedLength + opr.Offset.Value) )); } if (instruction.Operands[0] is PointerOperand) // far jump/call to absolute address { PointerOperand opr = (PointerOperand)instruction.Operands[0]; return(new XRef( type: bcjType, source: start, target: new Pointer(opr.Segment.Value, (UInt16)opr.Offset.Value) )); } if (instruction.Operands[0] is MemoryOperand) // indirect jump/call { MemoryOperand opr = (MemoryOperand)instruction.Operands[0]; // Handle static near jump table. We recognize a jump table // heuristically if the instruction looks like the following: // // jmpn word ptr cs:[bx+3782h] // // That is, it meets the requirements that // - the instruction is JMPN // - the jump target is a word-ptr memory location // - the memory location has CS prefix // - a base register (e.g. bx) specifies the entry index // // Note that a malformed executable may create a jump table // not conforming to the above rules, or create a non-jump // table that conforms to the above rules. We do not deal with // these cases for the moment. if (op == Operation.JMP && opr.Size == CpuSize.Use16Bit && opr.Segment == Register.CS && opr.Base != Register.None && opr.Index == Register.None) { return(new XRef( type: XRefType.NearIndexedJump, source: start, target: Pointer.Invalid, dataLocation: new Pointer(start.Segment, (UInt16)opr.Displacement.Value) )); } } // Other jump/call targets that we cannot recognize. AddError(start, ErrorCategory.Message, "Cannot determine target of {0} instruction.", op); return(new XRef( type: bcjType, source: start, target: Pointer.Invalid )); }