protected override Address ResolveFlowInstructionTarget(RelativeOperand operand) { SymbolicTarget symbolicTarget = operand.Tag as SymbolicTarget; if (symbolicTarget != null) { Address symbolicAddress = ResolveSymbolicTarget(symbolicTarget); if (symbolicAddress != Address.Invalid) { Address target = symbolicAddress + operand.Offset.Value; return(new Address(target.Segment, (UInt16)target.Offset)); } return(Address.Invalid); } return(base.ResolveFlowInstructionTarget(operand)); }
public SourceAwareRelativeOperand(RelativeOperand opr, Address source) : base(opr.Offset) { this.source = source; }
public virtual string FormatOperand(RelativeOperand operand) { string str = FormatFixableLocation(operand); if (str != null) return str; else return operand.Offset.Value.ToString("+0;-0"); }
protected virtual Address ResolveFlowInstructionTarget(RelativeOperand operand) { return(((SourceAwareRelativeOperand)operand).Target); }
protected override Address ResolveFlowInstructionTarget(RelativeOperand operand) { SymbolicTarget symbolicTarget = operand.Tag as SymbolicTarget; if (symbolicTarget != null) { Address symbolicAddress = ResolveSymbolicTarget(symbolicTarget); if (symbolicAddress != Address.Invalid) { Address target = symbolicAddress + operand.Offset.Value; return new Address(target.Segment, (UInt16)target.Offset); } return Address.Invalid; } return base.ResolveFlowInstructionTarget(operand); }
protected virtual Address ResolveFlowInstructionTarget(RelativeOperand operand) { return ((SourceAwareRelativeOperand)operand).Target; }
public SourceAwareRelativeOperand(RelativeOperand opr, Address source) : base(opr.Offset) { this.source = source; }
/// <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 )); }