public SimState(CPUx86 x86) : base(x86) { EIP = x86.EIP.Value; EAX = x86.EAX.Value; EBX = x86.EBX.Value; ECX = x86.ECX.Value; EDX = x86.EDX.Value; ESP = x86.ESP.Value; EBP = x86.EBP.Value; ESI = x86.ESI.Value; EDI = x86.EDI.Value; CR0 = x86.CR0.Value; CR2 = x86.CR2.Value; CR3 = x86.CR3.Value; CR4 = x86.CR4.Value; XMM0 = x86.XMM0.Value.Low; XMM1 = x86.XMM1.Value.Low; XMM2 = x86.XMM2.Value.Low; XMM3 = x86.XMM3.Value.Low; XMM4 = x86.XMM4.Value.Low; XMM5 = x86.XMM5.Value.Low; XMM6 = x86.XMM6.Value.Low; XMM7 = x86.XMM7.Value.Low; Zero = x86.EFLAGS.Zero; Parity = x86.EFLAGS.Parity; Carry = x86.EFLAGS.Carry; Direction = x86.EFLAGS.Direction; Sign = x86.EFLAGS.Sign; Adjust = x86.EFLAGS.Adjust; Overflow = x86.EFLAGS.Overflow; }
protected uint LoadValue(CPUx86 cpu, SimOperand operand) { if (operand.IsImmediate) { return((uint)operand.Immediate); } if (operand.IsRegister) { return(((operand.Register) as Register32Bit).Value); } if (operand.IsLabel) { return(ResolveLabel(cpu, operand)); } if (operand.IsMemory) { uint address = GetAddress(cpu, operand); return(Read(cpu, address, operand.Size)); } throw new SimCPUException(); }
protected FloatingValue ReadFloat(CPUx86 cpu, uint address, int size) { if (size == 128) { return(new FloatingValue() { ULow = cpu.Read64(address), UHigh = cpu.Read64(address + 0x8) }); } else if (size == 64) { return(new FloatingValue() { ULow = cpu.Read64(address) }); } else if (size == 32) { var val = new FloatingValue(); var b = BitConverter.GetBytes(cpu.Read32(address)); val.LowF = BitConverter.ToSingle(b, 0); return(val); } throw new SimCPUException(); }
public SimState(CPUx86 x86) : base(x86) { EIP = x86.EIP.Value; EAX = x86.EAX.Value; EBX = x86.EBX.Value; ECX = x86.ECX.Value; EDX = x86.EDX.Value; ESP = x86.ESP.Value; EBP = x86.EBP.Value; ESI = x86.ESI.Value; EDI = x86.EDI.Value; CR0 = x86.CR0.Value; CR2 = x86.CR2.Value; CR3 = x86.CR3.Value; CR4 = x86.CR4.Value; XMM0 = x86.XMM0.Value; XMM1 = x86.XMM1.Value; XMM2 = x86.XMM2.Value; XMM3 = x86.XMM3.Value; XMM4 = x86.XMM4.Value; XMM5 = x86.XMM5.Value; XMM6 = x86.XMM6.Value; XMM7 = x86.XMM7.Value; Zero = x86.EFLAGS.Zero; Parity = x86.EFLAGS.Parity; Carry = x86.EFLAGS.Carry; Direction = x86.EFLAGS.Direction; Sign = x86.EFLAGS.Sign; Adjust = x86.EFLAGS.Adjust; Overflow = x86.EFLAGS.Overflow; }
protected void StoreFloatValue(CPUx86 cpu, SimOperand operand, double value, int size) { var val = new FloatingValue() { Low = value }; StoreFloatValue(cpu, operand, val, size); }
protected uint ResolveBranch(CPUx86 cpu, SimOperand operand) { if (operand.IsLabel) { return(ResolveLabel(cpu, operand)); } else if (operand.IsImmediate) { return((uint)(cpu.EIP.Value + (long)operand.Immediate)); } throw new InvalidProgramException(); }
protected uint ResolveLabel(CPUx86 cpu, SimOperand operand) { Debug.Assert(operand.IsLabel); uint address = (uint)cpu.GetSymbol(operand.Label).Address; if (operand.IsMemory) { return(Read(cpu, address, operand.Size)); } else { return(address); } }
protected void Write(CPUx86 cpu, uint address, uint value, int size) { if (size == 32) { cpu.Write32(address, value); } else if (size == 16) { cpu.Write16(address, (ushort)value); } else if (size == 8) { cpu.Write8(address, (byte)value); } }
protected void UpdateParity(CPUx86 cpu, uint u) { bool parity = false; for (int i = 0; i < 8; i++) { if ((u & 0x1) == 1) { parity = !parity; } u = u >> 1; } cpu.EFLAGS.Parity = parity; }
protected uint Read(CPUx86 cpu, uint address, int size) { if (size == 32) { return(cpu.Read32(address)); } else if (size == 16) { return(cpu.Read16(address)); } else if (size == 8) { return(cpu.Read8(address)); } throw new SimCPUException(); }
protected void UpdateFlags(CPUx86 cpu, int size, long s, ulong u, bool zeroFlag, bool parityParity, bool signFlag, bool carryFlag, bool overFlowFlag) { if (size == 32) { UpdateFlags32(cpu, s, u, zeroFlag, parityParity, signFlag, carryFlag, overFlowFlag); } else if (size == 16) { UpdateFlags16(cpu, s, u, zeroFlag, parityParity, signFlag, carryFlag, overFlowFlag); } else { UpdateFlags8(cpu, s, u, zeroFlag, parityParity, signFlag, carryFlag, overFlowFlag); } UpdateParity(cpu, (uint)u); }
private void AddStack(CPUx86 x86) { var stack = new List <ulong[]>(); StoreValue("Stack", stack); uint esp = x86.ESP.Value; uint index = 0; while (index < 16) { stack.Add(new ulong[2] { (ulong)x86.Read32(esp), esp }); esp = esp + 4; index++; } }
private void AddStackFrame(CPUx86 x86) { var frame = new List <ulong[]>(); StoreValue("StackFrame", frame); uint ebp = x86.EBP.Value; uint index = 0; while (ebp > x86.ESP.Value && index < 32) { frame.Add(new ulong[2] { (ulong)x86.Read32(ebp), ebp }); ebp = ebp - 4; index++; } }
protected void WriteFloat(CPUx86 cpu, uint address, FloatingValue value, int size) { if (size == 128) { cpu.Write64(address, value.ULow); cpu.Write64(address + 0x08, value.UHigh); } else if (size == 64) { cpu.Write64(address, value.ULow); } else if (size == 32) { var b = BitConverter.GetBytes(value.LowF); uint val = BitConverter.ToUInt32(b, 0); cpu.Write32(address, val); } }
protected void UpdateFlags32(CPUx86 cpu, long s, ulong u, bool zeroFlag, bool parityParity, bool signFlag, bool carryFlag, bool overFlowFlag) { if (zeroFlag) { cpu.EFLAGS.Zero = ((u & 0xFFFFFFFF) == 0); } if (overFlowFlag) { cpu.EFLAGS.Overflow = (s < int.MinValue || s > int.MaxValue); } if (carryFlag) { cpu.EFLAGS.Carry = ((u >> 32) != 0); } if (signFlag) { cpu.EFLAGS.Sign = (((u >> 31) & 0x01) != 0); } }
protected void StoreFloatValue(CPUx86 cpu, SimOperand operand, FloatingValue value, int size) { Debug.Assert(!operand.IsImmediate); if (operand.IsRegister) { var newValue = ((operand.Register) as RegisterFloatingPoint).Value; switch (size) { case 128: newValue = value; break; case 64: newValue.Low = value.Low; break; case 32: newValue.LowF = value.LowF; break; } ((operand.Register) as RegisterFloatingPoint).Value = newValue; } if (operand.IsLabel) { uint address = (uint)cpu.GetSymbol(operand.Label).Address; WriteFloat(cpu, address, value, size); } if (operand.IsMemory) { uint address = GetAddress(cpu, operand); WriteFloat(cpu, address, value, size); } }
protected FloatingValue LoadFloatValue(CPUx86 cpu, SimOperand operand, int size) { if (operand.IsRegister) { return(((operand.Register) as RegisterFloatingPoint).Value); } if (operand.IsLabel) { uint address = (uint)cpu.GetSymbol(operand.Label).Address; return(ReadFloat(cpu, address, size)); } if (operand.IsMemory) { uint address = GetAddress(cpu, operand); return(ReadFloat(cpu, address, size)); } throw new SimCPUException(); }
protected void StoreValue(CPUx86 cpu, SimOperand operand, uint value, int size) { Debug.Assert(!operand.IsImmediate); if (operand.IsRegister) { ((operand.Register) as Register32Bit).Value = value; } else if (operand.IsLabel) { uint address = (uint)cpu.GetSymbol(operand.Label).Address; Write(cpu, address, value, size); return; } else if (operand.IsMemory) { uint address = GetAddress(cpu, operand); Write(cpu, address, value, size); } }
protected uint GetAddress(CPUx86 cpu, SimOperand operand) { Debug.Assert(operand.IsMemory); int address = 0; if (operand.Index != null) { // Memory = Register + (Base * Scale) + Displacement address = (int)(((operand.Index) as GeneralPurposeRegister).Value * operand.Scale); } if (operand.Register != null) { address = address + (int)((operand.Register) as GeneralPurposeRegister).Value + operand.Displacement; } else { address = (int)operand.Immediate; } return((uint)address); }
protected uint GetAddress(CPUx86 cpu, SimOperand operand) { Debug.Assert(operand.IsMemory); int address = 0; if (operand.Index != null) { // Memory = Register + (Base * Scale) + Displacement address = (int)(((operand.Index) as GeneralPurposeRegister).Value * operand.Scale); } if (operand.Register != null) { address = address + (int)((operand.Register) as GeneralPurposeRegister).Value + operand.Displacement; } else { address = (int)operand.Immediate; } return (uint)address; }
private void AddCallStack(CPUx86 x86) { var callStack = new List <ulong>(); uint ip = x86.EIP.Value; uint ebp = x86.EBP.Value; StoreValue("CallStack", callStack); callStack.Add((ulong)ip); try { for (int i = 0; i < 20; i++) { if (ebp == 0) { return; } ip = x86.DirectRead32(ebp + 4); if (ip == 0) { return; } callStack.Add((ulong)ip); ebp = x86.DirectRead32(ebp); } } catch (SimCPUException e) { } }
protected void UpdateFlags(CPUx86 cpu, int size, long s, ulong u, bool zeroFlag, bool parityParity, bool signFlag, bool carryFlag, bool overFlowFlag) { if (size == 32) UpdateFlags32(cpu, s, u, zeroFlag, parityParity, signFlag, carryFlag, overFlowFlag); else if (size == 16) UpdateFlags16(cpu, s, u, zeroFlag, parityParity, signFlag, carryFlag, overFlowFlag); else UpdateFlags8(cpu, s, u, zeroFlag, parityParity, signFlag, carryFlag, overFlowFlag); UpdateParity(cpu, (uint)u); }
public virtual void Execute(CPUx86 cpu, SimInstruction instruction) { }
protected uint ResolveBranch(CPUx86 cpu, SimOperand operand) { if (operand.IsLabel) return ResolveLabel(cpu, operand); else if (operand.IsImmediate) return (uint)(cpu.EIP.Value + (long)operand.Immediate); throw new InvalidProgramException(); }
protected uint ResolveLabel(CPUx86 cpu, SimOperand operand) { Debug.Assert(operand.IsLabel); uint address = (uint)cpu.GetSymbol(operand.Label).Address; if (operand.IsMemory) { return Read(cpu, address, operand.Size); } else { return address; } }
protected uint Read(CPUx86 cpu, uint address, int size) { if (size == 32) return cpu.Read32(address); else if (size == 16) return cpu.Read16(address); else if (size == 8) return cpu.Read8(address); throw new SimCPUException(); }
protected FloatingValue ReadFloat(CPUx86 cpu, uint address, int size) { if (size == 128) { return new FloatingValue() { ULow = cpu.Read64(address), UHigh = cpu.Read64(address + 0x8) }; } else if (size == 64) { return new FloatingValue() { ULow = cpu.Read64(address) }; } else if (size == 32) { var val = new FloatingValue(); var b = BitConverter.GetBytes(cpu.Read32(address)); val.LowF = BitConverter.ToSingle(b, 0); return val; } throw new SimCPUException(); }
protected uint LoadValue(CPUx86 cpu, SimOperand operand) { if (operand.IsImmediate) { return (uint)operand.Immediate; } if (operand.IsRegister) { return ((operand.Register) as Register32Bit).Value; } if (operand.IsLabel) { return ResolveLabel(cpu, operand); } if (operand.IsMemory) { uint address = GetAddress(cpu, operand); return Read(cpu, address, operand.Size); } throw new SimCPUException(); }
private void AddStackFrame(CPUx86 x86) { var frame = new List<ulong[]>(); StoreValue("StackFrame", frame); uint ebp = x86.EBP.Value; uint index = 0; while (ebp > x86.ESP.Value && index < 32) { frame.Add(new ulong[2] { (ulong)x86.Read32(ebp), ebp }); ebp = ebp - 4; index++; } }
protected void Write(CPUx86 cpu, uint address, uint value, int size) { if (size == 32) cpu.Write32(address, value); else if (size == 16) cpu.Write16(address, (ushort)value); else if (size == 8) cpu.Write8(address, (byte)value); }
protected void UpdateFlags8(CPUx86 cpu, long s, ulong u, bool zeroFlag, bool parityParity, bool signFlag, bool carryFlag, bool overFlowFlag) { if (zeroFlag) cpu.EFLAGS.Zero = ((u & 0xFF) == 0); if (overFlowFlag) cpu.EFLAGS.Overflow = (s < byte.MinValue || s > byte.MaxValue); if (carryFlag) cpu.EFLAGS.Carry = ((u >> 8) != 0); if (signFlag) cpu.EFLAGS.Sign = (((u >> 7) & 0x01) != 0); }
private void AddStack(CPUx86 x86) { var stack = new List<ulong[]>(); StoreValue("Stack", stack); uint esp = x86.ESP.Value; uint index = 0; while (index < 16) { stack.Add(new ulong[2] { (ulong)x86.Read32(esp), esp }); esp = esp + 4; index++; } }
protected void StoreFloatValue(CPUx86 cpu, SimOperand operand, double value, int size) { Debug.Assert(!operand.IsImmediate); if (operand.IsRegister) { ((operand.Register) as RegisterFloatingPoint).Value = value; } if (operand.IsLabel) { uint address = (uint)cpu.GetSymbol(operand.Label).Address; WriteFloat(cpu, address, value, size); } if (operand.IsMemory) { uint address = GetAddress(cpu, operand); WriteFloat(cpu, address, value, size); } }
protected void UpdateParity(CPUx86 cpu, uint u) { bool parity = false; for (int i = 0; i < 8; i++) { if ((u & 0x1) == 1) parity = !parity; u = u >> 1; } cpu.EFLAGS.Parity = parity; }
private void AddCallStack(CPUx86 x86) { var callStack = new List<ulong>(); uint ip = x86.EIP.Value; uint ebp = x86.EBP.Value; StoreValue("CallStack", callStack); callStack.Add((ulong)ip); try { for (int i = 0; i < 20; i++) { if (ebp == 0) return; ip = x86.DirectRead32(ebp + 4); if (ip == 0) return; callStack.Add((ulong)ip); ebp = x86.DirectRead32(ebp); } } catch (SimCPUException e) { } }
protected void WriteFloat(CPUx86 cpu, uint address, double value, int size) { if (size == 64) { byte[] b = BitConverter.GetBytes(value); cpu.Write8(address + 0, b[0]); cpu.Write8(address + 1, b[1]); cpu.Write8(address + 2, b[2]); cpu.Write8(address + 3, b[3]); cpu.Write8(address + 4, b[4]); cpu.Write8(address + 5, b[5]); cpu.Write8(address + 6, b[6]); cpu.Write8(address + 7, b[7]); } else if (size == 32) { byte[] b = BitConverter.GetBytes((float)value); cpu.Write8(address + 0, b[0]); cpu.Write8(address + 1, b[1]); cpu.Write8(address + 2, b[2]); cpu.Write8(address + 3, b[3]); } }
protected FloatingValue LoadFloatValue(CPUx86 cpu, SimOperand operand, int size) { if (operand.IsRegister) { return ((operand.Register) as RegisterFloatingPoint).Value; } if (operand.IsLabel) { uint address = (uint)cpu.GetSymbol(operand.Label).Address; return ReadFloat(cpu, address, size); } if (operand.IsMemory) { uint address = GetAddress(cpu, operand); return ReadFloat(cpu, address, size); } throw new SimCPUException(); }
protected double ReadFloat(CPUx86 cpu, uint address, int size) { if (size == 64) { byte[] b = new byte[8]; b[0] = cpu.Read8(address + 0); b[1] = cpu.Read8(address + 1); b[2] = cpu.Read8(address + 2); b[3] = cpu.Read8(address + 3); b[4] = cpu.Read8(address + 4); b[5] = cpu.Read8(address + 5); b[6] = cpu.Read8(address + 6); b[7] = cpu.Read8(address + 7); return BitConverter.ToDouble(b, 0); } else if (size == 32) { byte[] b = new byte[4]; b[0] = cpu.Read8(address + 0); b[1] = cpu.Read8(address + 1); b[2] = cpu.Read8(address + 2); b[3] = cpu.Read8(address + 3); return BitConverter.ToSingle(b, 0); } throw new SimCPUException(); }