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
                       ));
        }