private static MachineState emulateStackEffectFor(byte[] code, MachineState state) { switch (opcode.GetStackEffectFor(code)) { case StackEffect.Pop: { var destinationRegister = opcode.GetDestinationRegisterFor(code); state.Registers[destinationRegister] = state.Registers[RegisterName.ESP].PointsTo[0]; state = state.DoOperation(RegisterName.ESP, OperatorEffect.Sub, new AbstractValue(1)); break; } case StackEffect.Push: { state = state.DoOperation(RegisterName.ESP, OperatorEffect.Add, new AbstractValue(1)); AbstractValue sourceValue; if (opcode.HasSourceRegister(code)) { var sourceRegister = opcode.GetSourceRegisterFor(code); sourceValue = state.Registers[sourceRegister]; } else if (opcode.HasImmediate(code)) { sourceValue = new AbstractValue(opcode.GetImmediateFor(code)); } else { throw new InvalidOperationException( String.Format( "tried to push something that wasn't a register or an immediate @ 0x{0:x8}", state.InstructionPointer)); } state.Registers[RegisterName.ESP].PointsTo[0] = sourceValue; // TODO(matt_hargett): next step in correct stack emulation,, but breaks PushESPPopESP test // state = state.PushOntoStack(sourceValue); break; } default: { throw new InvalidOpcodeException(code); } } return(state); }
public void BigComplicatedMuthafuqqa() { const byte VALUE = 0xcd; state = state.DoOperation(RegisterName.ESP, OperatorEffect.Add, new AbstractValue(0x40)); state.InstructionPointer = 0x804839b; state = X86Emulator.Run(reportItems, state, new byte[] { 0x55 }); state = X86Emulator.Run(reportItems, state, new byte[] { 0x89, 0xe5 }); PrintStackAndBlock(); state = X86Emulator.Run(reportItems, state, new byte[] { 0x83, 0xec, 0x08 }); state = X86Emulator.Run(reportItems, state, new byte[] { 0x83, 0xe4, 0xf0 }); state = X86Emulator.Run(reportItems, state, new byte[] { 0xb8, 0x00, 0x00, 0x00, 0x00 }); state = X86Emulator.Run(reportItems, state, new byte[] { 0x83, 0xc0, 0x0f }); state = X86Emulator.Run(reportItems, state, new byte[] { 0x83, 0xc0, 0x0f }); state = X86Emulator.Run(reportItems, state, new byte[] { 0xc1, 0xe8, 0x04 }); state = X86Emulator.Run(reportItems, state, new byte[] { 0xc1, 0xe0, 0x04 }); state = X86Emulator.Run(reportItems, state, new byte[] { 0x29, 0xc4 }); state = X86Emulator.Run(reportItems, state, new byte[] { 0xc7, 0x04, 0x24, VALUE, 0, 0, 0 }); Assert.AreEqual(VALUE, state.TopOfStack.Value); state = X86Emulator.Run(reportItems, state, new byte[] { 0xe8, 0x10, 0, 0, 0 }); PrintStackAndBlock(); state = X86Emulator.Run(reportItems, state, new byte[] { 0x55 }); PrintStackAndBlock(); state = X86Emulator.Run(reportItems, state, new byte[] { 0x89, 0xe5 }); PrintStackAndBlock(); state = X86Emulator.Run(reportItems, state, new byte[] { 0x83, 0xec, 0x18 }); PrintStackAndBlock(); state = X86Emulator.Run(reportItems, state, new byte[] { 0x8b, 0x45, 0x08 }); PrintStackAndBlock(); Assert.AreEqual(VALUE, state.Registers[RegisterName.EAX].Value); }
public void SetUp() { state = new MachineState(new RegisterCollection()); reportItems = new ReportCollection(); var buffer = new AbstractBuffer(AbstractValue.GetNewBuffer(0x200)); var pointer = new AbstractValue(buffer); state.Registers[RegisterName.ESP] = pointer; state = state.DoOperation(RegisterName.EBP, OperatorEffect.Assignment, RegisterName.ESP); }
public void PushTwiceThenManuallyAdjustStackThenAssignToEbp() { var buffer = AbstractValue.GetNewBuffer(0x20); esp = new AbstractValue(buffer); state = state.PushOntoStack(one); state = state.PushOntoStack(two); state = state.DoOperation(RegisterName.ESP, OperatorEffect.Sub, new AbstractValue(0x4)); Assert.AreEqual(one, state.TopOfStack); }
public void PushPopThenAssignToTop() { var buffer = AbstractValue.GetNewBuffer(0x20); esp = new AbstractValue(buffer); state = state.PushOntoStack(one); // TODO(matt_hargett): extract into state.PopOffStack() state = state.DoOperation(RegisterName.ESP, OperatorEffect.Sub, new AbstractValue(0x4)); state = state.DoOperation(RegisterName.ESP, 0, OperatorEffect.Assignment, two); Assert.AreEqual(two, state.TopOfStack); }
public void PointerSub() { var buffer = AbstractValue.GetNewBuffer(0x10); buffer[0] = one; eax = new AbstractValue(buffer); ebx = new AbstractValue(0x4); state = state.DoOperation(RegisterName.EAX, OperatorEffect.Add, RegisterName.EBX); Assert.IsNotNull(eax.PointsTo); state = state.DoOperation(RegisterName.EAX, OperatorEffect.Sub, RegisterName.EBX); Assert.AreEqual(one, eax.PointsTo[0]); }
public void Jnz() { const byte offset = 6; eax = two; ebx = one; state = state.DoOperation(RegisterName.EAX, OperatorEffect.Cmp, RegisterName.EAX); state = state.DoOperation(OperatorEffect.Jnz, new AbstractValue(offset)); Assert.AreEqual(0, state.InstructionPointer); state = state.DoOperation(RegisterName.EAX, OperatorEffect.Cmp, RegisterName.EBX); state = state.DoOperation(OperatorEffect.Jnz, new AbstractValue(offset)); Assert.AreEqual(offset, state.InstructionPointer); }
public void PointerAnd() { var buffer = AbstractValue.GetNewBuffer(0x10); buffer[4] = one; eax = new AbstractValue(buffer); state = state.DoOperation(RegisterName.EAX, OperatorEffect.Add, new AbstractValue(0x4)); Assert.AreEqual(one, eax.PointsTo[0]); var andValue = new AbstractValue(0xfffffff0); var newState = state.DoOperation(RegisterName.EAX, OperatorEffect.And, andValue); Assert.AreNotSame(newState, state); Assert.AreNotEqual(newState, state); state = newState; Assert.AreEqual(one, eax.PointsTo[4]); }
private static MachineState emulateStackEffectFor(byte[] code, MachineState state) { switch (opcode.GetStackEffectFor(code)) { case StackEffect.Pop: { var destinationRegister = opcode.GetDestinationRegisterFor(code); state.Registers[destinationRegister] = state.Registers[RegisterName.ESP].PointsTo[0]; state = state.DoOperation(RegisterName.ESP, OperatorEffect.Sub, new AbstractValue(1)); break; } case StackEffect.Push: { state = state.DoOperation(RegisterName.ESP, OperatorEffect.Add, new AbstractValue(1)); AbstractValue sourceValue; if (opcode.HasSourceRegister(code)) { var sourceRegister = opcode.GetSourceRegisterFor(code); sourceValue = state.Registers[sourceRegister]; } else if (opcode.HasImmediate(code)) { sourceValue = new AbstractValue(opcode.GetImmediateFor(code)); } else { throw new InvalidOperationException( String.Format( "tried to push something that wasn't a register or an immediate @ 0x{0:x8}", state.InstructionPointer)); } state.Registers[RegisterName.ESP].PointsTo[0] = sourceValue; // TODO(matt_hargett): next step in correct stack emulation,, but breaks PushESPPopESP test // state = state.PushOntoStack(sourceValue); break; } default: { throw new InvalidOpcodeException(code); } } return state; }
public void Add() { eax = one; ebx = two; state = state.DoOperation(RegisterName.EAX, OperatorEffect.Add, RegisterName.EBX); Assert.AreEqual(3, eax.Value); Assert.IsTrue(eax.IsTainted); }