Example #1
0
        /*
         * the C0 bit becomes the CF (carry) flag, 
 the C2 bit becomes the PF(parity) flag, and 
 the C3 bit becomes the ZF (zero) flag. 
         */
        //  >              0
        //  <              1
        //  =             40
        //  inordered     45

        public FstswChainMatcher(IntelInstruction[] instrs, OperandRewriter orw)
        {
            this.instrs = instrs;
            this.orw = orw;
            this.zappedInstructions = new Dictionary<int, Opcode>();
            this.rewritten = new List<Instruction>();
        }
		public void DcffLiveAtEnd()
		{
			IntelInstruction [] instrs =
				new IntelInstruction[] {
										   new IntelInstruction(Opcode.cmp, PrimitiveType.Word32, PrimitiveType.Word32, new RegisterOperand(Registers.eax), new RegisterOperand(Registers.eax)),
										   new IntelInstruction(Opcode.jnz, PrimitiveType.Word32, PrimitiveType.Word32, new ImmediateOperand(Constant.Word32(0x10001010)))
									   };
			FlagM [] deadOut = dcff.DeadOutFlags(instrs);
			Assert.AreEqual(0, (int) deadOut[0]);
		}
		public void DcffConsecutiveAdds()
		{
			IntelInstruction [] instrs = 
				new IntelInstruction[] {
										   new IntelInstruction(Opcode.add, PrimitiveType.Word16, PrimitiveType.Word16, new RegisterOperand(Registers.bx), new ImmediateOperand(Constant.Word16(0x10))),
										   new IntelInstruction(Opcode.mov, PrimitiveType.Word16, PrimitiveType.Word16, new RegisterOperand(Registers.si), new RegisterOperand(Registers.bx)),
										   new IntelInstruction(Opcode.add, PrimitiveType.Word16, PrimitiveType.Word16, new RegisterOperand(Registers.cx), new ImmediateOperand(Constant.Word16(1)))
									   };
			FlagM [] deadOut = dcff.DeadOutFlags(instrs);
			Assert.AreEqual(FlagM.SF|FlagM.CF|FlagM.ZF|FlagM.OF, deadOut[0], "Item 0");
			Assert.AreEqual(FlagM.SF|FlagM.CF|FlagM.ZF|FlagM.OF, deadOut[1], "Item 1");
			Assert.AreEqual(0, (int) deadOut[2], "Item 2");
		}
Example #4
0
		public void Setup()
		{
            prog = new Program();
            prog.Image = new LoadedImage(Address.Ptr32(0x10000), new byte[4]);
            var procAddress = Address.Ptr32(0x10000000);
            instr = new IntelInstruction(Opcode.nop, PrimitiveType.Word32, PrimitiveType.Word32)
            {
                Address = procAddress,
            };
            proc = Procedure.Create(procAddress, arch.CreateFrame());
			state = (X86State) arch.CreateProcessorState();
			orw = new OperandRewriter32(arch, proc.Frame, new FakeRewriterHost(prog));
		}
Example #5
0
 public Expression Transform(IntelInstruction instr, MachineOperand op, PrimitiveType opWidth, X86State state)
 {
     var reg = op as RegisterOperand;
     if (reg != null)
         return AluRegister(reg);
     var mem = op as MemoryOperand;
     if (mem != null)
         return CreateMemoryAccess(instr, mem, opWidth, state);
     var imm = op as ImmediateOperand;
     if (imm != null)
         return CreateConstant(imm, opWidth);
     var fpu = op as FpuOperand;
     if (fpu != null)
         return FpuRegister(fpu.StNumber, state);
     var addr = op as AddressOperand;
     if (addr != null)
         return addr.Address;
     throw new NotImplementedException(string.Format("Operand {0}", op));
 }
		public void Setup()
		{
			arch = new IntelArchitecture(ProcessorMode.Real);
            var image = new LoadedImage(Address.Ptr32(0x10000), new byte[4]);
			var prog = new Program(
                image,
                image.CreateImageMap(),
                arch,
                null);
			var procAddress = Address.Ptr32(0x10000000);
            instr = new IntelInstruction(Opcode.nop, PrimitiveType.Word16, PrimitiveType.Word16)
            {
                Address = procAddress,
            };

            proc = Procedure.Create(procAddress, arch.CreateFrame());
			orw = new OperandRewriter16(arch, proc.Frame, new FakeRewriterHost(prog));
            state = (X86State)arch.CreateProcessorState();
        }
		public void EmitStringInstruction(IntelInstruction instr, CodeEmitterOld emitter)
		{
            this.emitter = emitter;

			bool incSi = false;
			bool incDi = false;
			this.instrCur = instr;
			switch (instrCur.code)
			{
				default:
					throw new ApplicationException("NYI");
				case Opcode.cmps:
				case Opcode.cmpsb:
					emitter.Assign(
						orw.FlagGroup(IntelInstruction.DefCc(Opcode.cmp)),
						new ConditionOf(
						new BinaryExpression(Operator.Sub, instrCur.dataWidth, MemSi(), MemDi())));
					incSi = true;
					incDi = true;
					break;
				case Opcode.lods:
				case Opcode.lodsb:
					emitter.Assign(RegAl, MemSi());
					incSi = true;
					break;
				case Opcode.movs:
				case Opcode.movsb:
				{
					Identifier tmp = frame.CreateTemporary(instrCur.dataWidth);
					emitter.Assign(tmp, MemSi());
					emitter.Store(MemDi(), tmp);
					incSi = true;
					incDi = true;
					break;
				}
				case Opcode.ins:
				case Opcode.insb:
				{
					Identifier regDX = orw.AluRegister(Registers.edx, instrCur.addrWidth);
					emitter.Store(MemDi(), emitter.PseudoProc("__in", instrCur.dataWidth, regDX));
					incDi = true;
					break;
				}
				case Opcode.outs:
				case Opcode.outsb:
				{
					Identifier regDX = orw.AluRegister(Registers.edx, instrCur.addrWidth);
					emitter.SideEffect("__out" + RegAl.DataType.Prefix, regDX, RegAl);
					incSi = true;
					break;
				}
				case Opcode.scas:
				case Opcode.scasb:
					emitter.Assign(
						orw.FlagGroup(IntelInstruction.DefCc(Opcode.cmp)),
						new ConditionOf(
						new BinaryExpression(Operator.Sub, 
						instrCur.dataWidth,
						RegAl, 
						MemDi())));
					incDi = true;
					break;
				case Opcode.stos:
				case Opcode.stosb:
                    emitter.Store(MemDi(), RegAl);
					incDi = true;
					break;
			}

			if (incSi)
			{
				emitter.Assign(RegSi,
					new BinaryExpression(Operator.Add, 
					instrCur.addrWidth,
					RegSi, 
					new Constant(instrCur.addrWidth, instrCur.dataWidth.Size)));
			}

			if (incDi)
			{
				emitter.Assign(RegDi,
					new BinaryExpression(Operator.Add, 
					instrCur.addrWidth,
					RegDi, 
					new Constant(instrCur.addrWidth, instrCur.dataWidth.Size)));
			}
		}
Example #8
0
 public void Execute(IntelInstruction instr)
 {
     switch (instr.code)
     {
     default:
         throw new NotImplementedException(string.Format("Instruction emulation for {0} not implemented yet.", instr));
     case Opcode.adc: Adc(instr.op1, instr.op2); return;
     case Opcode.add: Add(instr.op1, instr.op2); return;
     case Opcode.and: And(instr.op1, instr.op2); return;
     case Opcode.call: Call(instr.op1); return;
     case Opcode.cmp: Cmp(instr.op1, instr.op2); return;
     case Opcode.dec: Dec(instr.op1); return;
     case Opcode.hlt: running = false; return;
     case Opcode.inc: Inc(instr.op1); return;
     case Opcode.ja: if ((Flags & (Cmask | Zmask)) == 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return;
     case Opcode.jbe: if ((Flags & (Cmask | Zmask)) != 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return;
     case Opcode.jc: if ((Flags & Cmask) != 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return;
     case Opcode.jmp: Jump(instr.op1); return;
     case Opcode.jnc: if ((Flags & Cmask) == 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return;
     case Opcode.jnz: if ((Flags & Zmask) == 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return;
     case Opcode.jz: if ((Flags & Zmask) != 0) InstructionPointer = ((AddressOperand)instr.op1).Address; return;
     case Opcode.lea: Write(instr.op1, GetEffectiveAddress((MemoryOperand)instr.op2)); break;
     case Opcode.loop: Loop(instr.op1); break;
     case Opcode.mov: Write(instr.op1, Read(instr.op2)); break;
     case Opcode.or: Or(instr.op1, instr.op2); return;
     case Opcode.pop: Write(instr.op1, Pop()); return;
     case Opcode.popa: Popa(); return;
     case Opcode.push: Push(Read(instr.op1)); return;
     case Opcode.pusha: Pusha(); return;
     case Opcode.repne: Repne(); return;
     case Opcode.rol: Rol(instr.op1, instr.op2); return;
     case Opcode.scasb: Scasb(); return;
     case Opcode.shl: Shl(instr.op1, instr.op2); return;
     case Opcode.shr: Shr(instr.op1, instr.op2); return;
     case Opcode.sub: Sub(instr.op1, instr.op2); return;
     case Opcode.xor: Xor(instr.op1, instr.op2); return;
     case Opcode.xchg: Xchg(instr.op1, instr.op2); return;
     }
 }
Example #9
0
        public Expression CreateMemoryAccess(IntelInstruction instr, MemoryOperand mem, DataType dt, X86State state)
        {
            var exp = ImportedProcedureName(instr.Address, mem.Width, mem);
            if (exp != null)
                return new ProcedureConstant(arch.PointerType, exp);

            Expression expr = EffectiveAddressExpression(instr, mem, state);
            if (IsSegmentedAccessRequired ||
                (mem.DefaultSegment != Registers.ds && mem.DefaultSegment != Registers.ss))
            {
                Expression seg = ReplaceCodeSegment(mem.DefaultSegment, state);
                if (seg == null)
                    seg = AluRegister(mem.DefaultSegment);
                return new SegmentedAccess(MemoryIdentifier.GlobalMemory, seg, expr, dt);
            }
            else
            {
                return new MemoryAccess(MemoryIdentifier.GlobalMemory, expr, dt);
            }
        }
Example #10
0
        /// <summary>
        /// Memory accesses are translated into expressions.
        /// </summary>
        /// <param name="mem"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        public Expression EffectiveAddressExpression(IntelInstruction instr, MemoryOperand mem, X86State state)
        {
            Expression eIndex = null;
            Expression eBase = null;
            Expression expr = null;
            PrimitiveType type = PrimitiveType.CreateWord(mem.Width.Size);
            bool ripRelative = false;

            if (mem.Base != RegisterStorage.None)
            {
                if (mem.Base == Registers.rip)
                {
                    ripRelative = true;
                }
                else
                {
                    eBase = AluRegister(mem.Base);
                    if (expr != null)
                    {
                        expr = new BinaryExpression(Operator.IAdd, eBase.DataType, eBase, expr);
                    }
                    else
                    {
                        expr = eBase;
                    }
                }
            }

            if (mem.Offset.IsValid)
            {
                if (ripRelative)
                {
                    expr = instr.Address + (instr.Length + mem.Offset.ToInt64());
                }
                else if (expr != null)
                {
                    BinaryOperator op = Operator.IAdd;
                    long l = mem.Offset.ToInt64();
                    if (l < 0 && l > -0x800)
                    {
                        l = -l;
                        op = Operator.ISub;
                    }

                    DataType dt = (eBase != null) ? eBase.DataType : eIndex.DataType;
                    Constant cOffset = Constant.Create(dt, l);
                    expr = new BinaryExpression(op, dt, expr, cOffset);
                }
                else
                {
                    expr = mem.Offset;
                }
            }

            if (mem.Index != RegisterStorage.None)
            {
                eIndex = AluRegister(mem.Index);
                if (mem.Scale != 0 && mem.Scale != 1)
                {
                    eIndex = new BinaryExpression(
                        Operator.IMul, eIndex.DataType, eIndex, Constant.Create(mem.Width, mem.Scale));
                }
                expr = new BinaryExpression(Operator.IAdd, expr.DataType, expr, eIndex);
            }
            return expr;
        }
Example #11
0
 public Expression CreateMemoryAccess(IntelInstruction instr, MemoryOperand memoryOperand, X86State state)
 {
     return CreateMemoryAccess(instr, memoryOperand, memoryOperand.Width, state);
 }
Example #12
0
		private IntelInstruction CreatePush(IntelRegister reg)
		{
            IntelInstruction inst = new IntelInstruction(
                Opcode.push,
                reg.DataType,
                reg.DataType,
                new RegisterOperand(reg));
			return inst;
		}
Example #13
0
		private IntelInstruction CreateMov(IntelRegister regDst, IntelRegister regSrc)
		{
            IntelInstruction inst = new IntelInstruction(
                Opcode.mov,
                PrimitiveType.Word16,
                PrimitiveType.Word16,
                new RegisterOperand(regDst),
                new RegisterOperand(regSrc));
			return inst;
		}
Example #14
0
 /// <summary>
 /// A jump to 0xFFFF:0x0000 in real mode is a reboot.
 /// </summary>
 /// <param name="instrCur"></param>
 /// <returns></returns>
 private bool IsRealModeReboot(IntelInstruction instrCur)
 {
     var addrOp = instrCur.op1 as X86AddressOperand;
     bool isRealModeReboot = addrOp != null && addrOp.Address.ToLinear() == 0xFFFF0;
     return isRealModeReboot;
 }