public override bool TryPeekPointer(EndianImageReader rdr, out ulong target) { if (!rdr.IsValidOffset(rdr.Offset + 4 - 1)) { target = 0; return(false); } else { target = rdr.PeekLeUInt32(0); return(true); } }
public override bool MatchCall(EndianImageReader rdr, uint opcode, out ulong target) { if (opcode == 0xE8 // CALL NEAR && rdr.IsValidOffset(rdr.Offset + 4u)) { int callOffset = rdr.PeekLeInt32(1); target = ((ulong)(long)callOffset + rdr.Address.ToLinear() + 5); return(true); } target = 0; return(false); }
public override bool MatchCall(EndianImageReader rdr, uint opcode, out uint target) { if ((opcode & 0xFC000000) == 0x0C000000 // JAL && rdr.IsValidOffset(rdr.Offset + 4u)) { var off = (opcode & 0x03FFFFFF) << 2; target = (((uint)rdr.Address.ToLinear() + 4) & 0xF0000000u) | off; return(true); } target = 0; return(false); }
public override bool MatchCall(EndianImageReader rdr, uint opcode, out uint target) { if (opcode == 0xE8 // CALL NEAR && rdr.IsValidOffset(rdr.Offset + 2u)) { int callOffset = rdr.PeekLeInt16(1); target = (uint)(callOffset + (uint)rdr.Address.ToLinear() + 3); return(true); } if (opcode == 0x9A // CALL FAR && rdr.IsValidOffset(rdr.Offset + 5u)) { ushort callOff = rdr.PeekLeUInt16(1); ushort callSeg = rdr.PeekLeUInt16(3); target = ((uint)callSeg << 4) + callOff; return(true); } target = 0; return(false); }
public override bool MatchJump(EndianImageReader rdr, uint opcode, out uint target) { if ((opcode & 0xFC000000) == 0x08000000 // J - far jump && rdr.IsValidOffset(rdr.Offset + 4u)) { var off = (opcode & 0x03FFFFFF) << 2; target = (((uint)rdr.Address.ToLinear() + 4) & 0xF0000000u) | off; return(true); } if ((opcode & 0xF0000000) == 0x10000000 // b** - far jump && rdr.IsValidOffset(rdr.Offset + 4u)) { int off = (short)opcode; off <<= 2; target = (uint)(((int)rdr.Address.ToLinear() + 4) + off); return(true); } target = 0; return(false); }
private bool RelativeBranchCall(EndianImageReader rdr, uint opcode, out uint target) { int callOffset = (sbyte)opcode; if (callOffset == -1// bsr.l && rdr.IsValidOffset(rdr.Offset + 4u)) { callOffset = rdr.PeekBeInt32(2); target = (uint)(callOffset + (long)rdr.Address.ToLinear() + 2); return(true); } if (callOffset == 0x00 // bsr.w) && rdr.IsValidOffset(rdr.Offset + 2u)) { callOffset = rdr.PeekBeInt16(2); target = (uint)(callOffset + (long)rdr.Address.ToLinear() + 2); return(true); } target = (uint)(callOffset + (long)rdr.Address.ToLinear() + 2); return(true); }
private MachineOperand DecodeModRM(PrimitiveType dataWidth, RegisterStorage segOverride, Func <int, PrimitiveType, RegisterStorage> regFn) { if (!TryEnsureModRM(out byte modRm)) { return(null); } int rm = this.currentDecodingContext.ModRegMemByte & 0x07; int mod = this.currentDecodingContext.ModRegMemByte >> 6; RegisterStorage b; RegisterStorage idx; byte scale = 1; PrimitiveType offsetWidth = null; if (addressWidth == PrimitiveType.Word16) { // 16-bit addressing modes are weird. b = s_ma16Base[rm]; idx = s_ma16Index[rm]; scale = 1; switch (mod) { case 0: if (rm == 0x06) { offsetWidth = PrimitiveType.Word16; b = RegisterStorage.None; idx = RegisterStorage.None; } else { offsetWidth = null; } break; case 1: offsetWidth = PrimitiveType.SByte; break; case 2: offsetWidth = PrimitiveType.Word16; break; case 3: return(new RegisterOperand(RegFromBitsRexB(rm, dataWidth, regFn))); } } else { idx = RegisterStorage.None; switch (mod) { case 0: if (rm == 0x05) { if (defaultAddressWidth.BitSize == 64) //$REFACTOR: should subclass this type of behaviour. { b = Registers.rip; offsetWidth = PrimitiveType.Int32; } else { offsetWidth = PrimitiveType.Ptr32; b = RegisterStorage.None; } } else { b = RegFromBitsRexB(rm, addressWidth, GpRegFromBits); offsetWidth = null; } break; case 1: b = RegFromBitsRexB(rm, addressWidth, GpRegFromBits); offsetWidth = PrimitiveType.SByte; break; case 2: b = RegFromBitsRexB(rm, addressWidth, GpRegFromBits); offsetWidth = PrimitiveType.Word32; break; case 3: return(new RegisterOperand(RegFromBitsRexB(rm, dataWidth, regFn))); default: throw new InvalidOperationException("Impossiburu."); } // Handle possible s-i-b byte. if (rm == 0x04) { // We have SIB'ness, your majesty! if (!rdr.TryReadByte(out byte sib)) { return(null); } if (((this.currentDecodingContext.ModRegMemByte & 0xC0) == 0) && ((sib & 0x7) == 5)) { offsetWidth = PrimitiveType.Word32; b = RegisterStorage.None; } else { b = RegFromBitsRexB(sib, addressWidth, GpRegFromBits); } int i = (sib >> 3) & 0x7; idx = (i == 0x04) ? RegisterStorage.None : RegFromBitsRexX(i, addressWidth, GpRegFromBits); scale = (byte)(1 << (sib >> 6)); } } // Now fetch the offset if there was any. Constant offset; if (offsetWidth != null) { if (!rdr.IsValidOffset(rdr.Offset + (uint)offsetWidth.Size - 1)) { return(null); } if (!rdr.TryReadLe(offsetWidth, out offset)) { return(null); } } else { offset = Constant.Invalid; } return(new MemoryOperand(dataWidth, offset) { Base = b, Index = idx, Scale = scale, SegOverride = segOverride, }); }