/* * 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"); }
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)); }
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))); } }
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; } }
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); } }
/// <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; }
public Expression CreateMemoryAccess(IntelInstruction instr, MemoryOperand memoryOperand, X86State state) { return CreateMemoryAccess(instr, memoryOperand, memoryOperand.Width, state); }
private IntelInstruction CreatePush(IntelRegister reg) { IntelInstruction inst = new IntelInstruction( Opcode.push, reg.DataType, reg.DataType, new RegisterOperand(reg)); return inst; }
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; }
/// <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; }