Expose ReadVirtualValue as ReadMemAs<T>, implement the other ReadMemAs functions using it
Add read function for simple & efficient reading of single discrete values
This commit is contained in:
Zhentar 2019-01-20 00:09:53 -06:00 коммит произвёл Dan Thompson
Родитель 5fc3493668
Коммит b830c1b852
4 изменённых файлов: 84 добавлений и 26 удалений

Просмотреть файл

@ -5048,6 +5048,26 @@ int WDebugDataSpaces::ReadVirtualDirect(
return hr;
}
generic <typename TValue>
where TValue : value class
int WDebugDataSpaces::ReadVirtualValue(
[In] UInt64 Offset,
[Out] TValue% value)
{
ULONG BytesRead;
pin_ptr<TValue> pval = &value;
int hr = m_pNative->ReadVirtual( Offset,
pval,
sizeof(TValue),
&BytesRead);
//Since we are reading a single discrete value, treat under-read as failure
if (hr == S_OK && BytesRead < sizeof(TValue))
{
return HRESULT_FROM_WIN32(ERROR_READ_FAULT);
}
return hr;
}
// Note that not all bytes may be written!
int WDebugDataSpaces::WriteVirtual(

Просмотреть файл

@ -2767,6 +2767,12 @@ namespace DbgEngWrapper
[In] ULONG BytesRequested,
[In] BYTE* buffer,
[Out] ULONG% BytesRead);
generic <typename TValue>
where TValue : value class //should be `unmanaged` but that's not a choice we have
int ReadVirtualValue(
[In] UInt64 Offset,
[Out] TValue% value);
// Note that not all bytes may be written!
int WriteVirtual(

Просмотреть файл

@ -1033,6 +1033,26 @@ namespace MS.Dbg
} );
} // end QueryTargetIs32Bit()
internal bool QueryTargetIsWow64()
{
return ExecuteOnDbgEngThread( () =>
{
CheckHr(m_debugControl.GetActualProcessorType(out IMAGE_FILE_MACHINE type ));
if( type == IMAGE_FILE_MACHINE.AMD64 || (uint)type == 0xAA64 /*ARM64*/ ) //Wow64 supported architectures
{
CheckHr(m_debugSystemObjects.GetCurrentThreadTeb( out var teb ));
var wow64offset = teb + 0x1488; //TODO: TlsSlots[1] - 1 == WOW64_TLS_CPURESERVED
//Note that we want to do a 64-bit pointer read here regardless of the current effective pointer size
_CheckMemoryReadHr( wow64offset, m_debugDataSpaces.ReadVirtualValue( wow64offset, out ulong cpureservedOffset ) );
//now we have a pointer to a WOW64_CPURESERVED struct, which is a pair of ushort values
//If we wanted to know the WoW guest architecture, we'd want to read the second one (only actually necessary
//for windows builds >= 9925, which I presume was the first time it might have been a value other than i386.
//but that's not what we are checking here.
return cpureservedOffset != 0;
}
return false;
} );
}
private RealDebugEventCallbacks m_internalEventCallbacks;
private IDebugInputCallbacksImp m_inputCallbacks;
@ -2128,6 +2148,14 @@ namespace MS.Dbg
} );
} // end ReadMem()
public T ReadMemAs< T >( ulong address ) where T : unmanaged
{
return ExecuteOnDbgEngThread( () =>
{
_CheckMemoryReadHr( address, m_debugDataSpaces.ReadVirtualValue( address, out T tempValue ) );
return tempValue;
} );
}
/// <summary>
/// Reads the specified number of bytes from the specified address in the
@ -2337,74 +2365,62 @@ namespace MS.Dbg
public short ReadMemAs_short( ulong address )
{
byte[] raw = ReadMem( address, 2, true );
return BitConverter.ToInt16( raw, 0 );
return ReadMemAs< short >( address );
} // end ReadMemAs_short()
public ushort ReadMemAs_ushort( ulong address )
{
byte[] raw = ReadMem( address, 2, true );
return BitConverter.ToUInt16( raw, 0 );
return ReadMemAs< ushort >( address );
} // end ReadMemAs_ushort()
public byte ReadMemAs_byte( ulong address )
{
byte[] raw = ReadMem( address, 1, true );
return raw[ 0 ];
return ReadMemAs< byte >( address );
} // end ReadMemAs_byte()
public sbyte ReadMemAs_sbyte( ulong address )
{
byte[] raw = ReadMem( address, 1, true );
return (sbyte) raw[ 0 ];
return ReadMemAs< sbyte >( address );
} // end ReadMemAs_sbyte()
public char ReadMemAs_WCHAR( ulong address )
{
byte[] raw = ReadMem( address, 2, true );
return BitConverter.ToChar( raw, 0 );
return ReadMemAs< char >( address );
} // end ReadMemAs_WCHAR()
public int ReadMemAs_Int32( ulong address )
{
byte[] raw = ReadMem( address, 4, true );
return BitConverter.ToInt32( raw, 0 );
return ReadMemAs< int >( address );
} // end ReadMemAs_Int32()
public uint ReadMemAs_UInt32( ulong address )
{
byte[] raw = ReadMem( address, 4, true );
return BitConverter.ToUInt32( raw, 0 );
return ReadMemAs< uint >( address );
} // end ReadMemAs_UInt32()
public long ReadMemAs_Int64( ulong address )
{
byte[] raw = ReadMem( address, 8, true );
return BitConverter.ToInt64( raw, 0 );
return ReadMemAs< long >( address );
} // end ReadMemAs_Int64()
public ulong ReadMemAs_UInt64( ulong address )
{
byte[] raw = ReadMem( address, 8, true );
return BitConverter.ToUInt64( raw, 0 );
return ReadMemAs< ulong >( address );
} // end ReadMemAs_UInt64()
public bool ReadMemAs_CPlusPlusBool( ulong address )
{
byte[] raw = ReadMem( address, 1, true );
return BitConverter.ToBoolean( raw, 0 );
return ReadMemAs< byte >( address ) != 0;
} // end ReadMemAs_CPlusPlusBool()
public float ReadMemAs_float( ulong address )
{
byte[] raw = ReadMem( address, 4, true );
return BitConverter.ToSingle( raw, 0 );
return ReadMemAs< float >( address );
} // end ReadMemAs_float()
public double ReadMemAs_double( ulong address )
{
byte[] raw = ReadMem( address, 8, true );
return BitConverter.ToDouble( raw, 0 );
return ReadMemAs< double >( address );
} // end ReadMemAs_double()
public ulong ReadMemAs_pointer( ulong address )
@ -2415,8 +2431,7 @@ namespace MS.Dbg
public Guid ReadMemAs_Guid( ulong address )
{
byte[] raw = ReadMem( address, 16, true );
return new Guid( raw );
return ReadMemAs< Guid >( address );
} // end ReadMemAs_Guid()
public T[] ReadMemAs_TArray< T >( ulong address, uint count ) where T: unmanaged

Просмотреть файл

@ -76,6 +76,23 @@ namespace MS.Dbg
}
}
private bool? m_isWoW64;
[NsLeafItem]
public bool IsWoW64
{
get
{
if( null == m_isWoW64 )
{
using( new DbgEngContextSaver( Debugger, Context ) )
{
m_isWoW64 = Debugger.QueryTargetIsWow64();
}
}
return (bool) m_isWoW64;
}
}
private string m_targetFriendlyName;