[0.2.x] refactored : memory management API

git-svn-id: https://pykd.svn.codeplex.com/svn@78411 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2012-07-31 15:53:49 +00:00 committed by Mikhail I. Izmestev
parent 9cbbbb7ea6
commit 82df396b22
6 changed files with 443 additions and 18 deletions

View File

@ -9,6 +9,9 @@ void terminateProcess( ULONG processId = -1);
void debugGo();
// system properties
ULONG ptrSize();
//manage debug module
ULONG64 findModuleBase( const std::string &moduleName );
ULONG64 findModuleBase( ULONG64 offset );

View File

@ -5,6 +5,131 @@ namespace pykd {
/////////////////////////////////////////////////////////////////////////////////////
bool compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr = FALSE )
{
bool result = false;
addr1 = addr64( addr1 );
addr2 = addr64( addr2 );
std::vector<char> m1(length);
std::vector<char> m2(length);
readMemory( addr1, &m1[0], length, phyAddr );
readMemory( addr2, &m2[0], length, phyAddr );
return std::equal( m1.begin(), m1.end(), m2.begin() );
}
/////////////////////////////////////////////////////////////////////////////////////
ULONG64 ptrByte( ULONG64 offset )
{
unsigned char val = 0;
readMemory( offset, &val, sizeof(val), false );
return val;
}
/////////////////////////////////////////////////////////////////////////////////////
ULONG64 ptrWord( ULONG64 offset )
{
unsigned short val = 0;
readMemory( offset, &val, sizeof(val), false );
return val;
}
/////////////////////////////////////////////////////////////////////////////////////
ULONG64 ptrDWord( ULONG64 offset )
{
unsigned long val = 0;
readMemory( offset, &val, sizeof(val), false );
return val;
}
/////////////////////////////////////////////////////////////////////////////////////
ULONG64 ptrQWord( ULONG64 offset )
{
unsigned __int64 val = 0;
readMemory( offset, &val, sizeof(val), false );
return val;
}
/////////////////////////////////////////////////////////////////////////////////////
ULONG64 ptrMWord( ULONG64 offset )
{
return ptrSize() == 8 ? ptrQWord( offset ) : ptrDWord(offset );
}
ULONG64 ptrPtr( ULONG64 offset )
{
return ptrMWord( offset );
}
/////////////////////////////////////////////////////////////////////////////////////
LONG64 ptrSignByte( ULONG64 offset )
{
char val = 0;
readMemory( offset, &val, sizeof(val), false );
return val;
}
/////////////////////////////////////////////////////////////////////////////////////
LONG64 ptrSignWord( ULONG64 offset )
{
short val = 0;
readMemory( offset, &val, sizeof(val), false );
return val;
}
/////////////////////////////////////////////////////////////////////////////////////
LONG64 ptrSignDWord( ULONG64 offset )
{
long val = 0;
readMemory( offset, &val, sizeof(val), false );
return val;
}
/////////////////////////////////////////////////////////////////////////////////////
LONG64 ptrSignQWord( ULONG64 offset )
{
__int64 val = 0;
readMemory( offset, &val, sizeof(val), false );
return val;
}
/////////////////////////////////////////////////////////////////////////////////////
LONG64 ptrSignMWord( ULONG64 offset )
{
return ptrSize() == 8 ? ptrSignQWord( offset ) : ptrSignDWord(offset);
}
/////////////////////////////////////////////////////////////////////////////////////
template<typename T>
struct PyListType
{
@ -92,6 +217,134 @@ python::list loadSignQWords( ULONG64 offset, ULONG count, bool phyAddr )
/////////////////////////////////////////////////////////////////////////////////////
std::string loadChars( ULONG64 offset, ULONG number, bool phyAddr )
{
std::vector<char> buffer(number);
ULONG bufferSize = (ULONG)( sizeof(std::vector<char>::value_type)*buffer.size() );
if (number)
readMemory( offset, &buffer[0], bufferSize, phyAddr );
return std::string( buffer.begin(), buffer.end() );
}
/////////////////////////////////////////////////////////////////////////////////////
std::wstring loadWChars( ULONG64 offset, ULONG number, bool phyAddr )
{
std::vector<wchar_t> buffer(number);
ULONG bufferSize = (ULONG)( sizeof(std::vector<wchar_t>::value_type)*buffer.size() );
if (number)
readMemory( offset, &buffer[0], bufferSize, phyAddr );
return std::wstring( buffer.begin(), buffer.end() );
}
/////////////////////////////////////////////////////////////////////////////////////
python::list loadPtrList( ULONG64 offset )
{
offset = addr64( offset );
ULONG64 entryAddress = 0;
python::list lst;
for( entryAddress = ptrPtr( offset ); entryAddress != offset && entryAddress != 0; entryAddress = ptrPtr( entryAddress ) )
lst.append( entryAddress );
return lst;
}
/////////////////////////////////////////////////////////////////////////////////////
python::list loadPtrArray( ULONG64 offset, ULONG number )
{
offset = addr64( offset );
python::list lst;
for ( ULONG i = 0; i < number; ++i )
lst.append( ptrPtr( offset + i*ptrSize() ) );
return lst;
}
/////////////////////////////////////////////////////////////////////////////////////
std::wstring loadUnicodeStr( ULONG64 offset )
{
USHORT length;
USHORT maximumLength;
ULONG64 buffer = 0;
ULONG ptrsize = ptrSize();
offset = addr64( offset );
readMemory( offset, &length, sizeof( length ) );
if ( length == 0 )
return L"";
offset += sizeof( length );
readMemory( offset, &maximumLength, sizeof( maximumLength ) );
offset += sizeof( maximumLength );
offset += offset % ptrsize ? ( ptrsize - offset % ptrsize ) : 0 ; // âûðàâíèâàíèå
buffer = addr64( ptrPtr( offset ) );
offset += ptrsize;
std::vector<wchar_t> str(length / 2);
readMemory( buffer, &str[0], length );
return std::wstring (&str[0], length/2);
}
/////////////////////////////////////////////////////////////////////////////////////
std::string loadAnsiStr( ULONG64 offset )
{
USHORT length;
USHORT maximumLength;
ULONG64 buffer = 0;
ULONG ptrsize = ptrSize();
offset = addr64( offset );
readMemory( offset, &length, sizeof( length ) );
if ( length == 0 )
return "";
offset += sizeof( length );
readMemory( offset, &maximumLength, sizeof( maximumLength ) );
offset += sizeof( maximumLength );
offset += offset % ptrsize ? ( ptrsize - offset % ptrsize ) : 0 ; // âûðàâíèâàíèå
buffer = addr64( ptrPtr( offset ) );
offset += ptrsize;
std::vector<char> str(length);
readMemory( buffer, &str[0], length );
return std::string (&str[0], length);
}
/////////////////////////////////////////////////////////////////////////////////////
}; // end pykd namespace

View File

@ -4,6 +4,21 @@ namespace pykd {
///////////////////////////////////////////////////////////////////////////////////
bool isVaValid( ULONG64 addr );
bool compareMemory( ULONG64 addr1, ULONG64 addr2, ULONG length, bool phyAddr = FALSE );
ULONG64 ptrByte( ULONG64 offset );
ULONG64 ptrWord( ULONG64 offset );
ULONG64 ptrDWord( ULONG64 offset );
ULONG64 ptrQWord( ULONG64 offset );
ULONG64 ptrMWord( ULONG64 offset );
LONG64 ptrSignByte( ULONG64 offset );
LONG64 ptrSignWord( ULONG64 offset );
LONG64 ptrSignDWord( ULONG64 offset );
LONG64 ptrSignQWord( ULONG64 offset );
LONG64 ptrSignMWord( ULONG64 offset );
ULONG64 ptrPtr( ULONG64 offset );
python::list loadBytes( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
python::list loadWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
python::list loadDWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
@ -13,6 +28,17 @@ python::list loadSignWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
python::list loadSignDWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
python::list loadSignQWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
python::list loadPtrList( ULONG64 offset );
python::list loadPtrArray( ULONG64 offset, ULONG number );
std::string loadChars( ULONG64 offset, ULONG number, bool phyAddr = FALSE );
std::wstring loadWChars( ULONG64 offset, ULONG number, bool phyAddr = FALSE );
std::string loadCStr( ULONG64 offset );
std::wstring loadWStr( ULONG64 offset );
std::string loadAnsiStr( ULONG64 offset );
std::wstring loadUnicodeStr( ULONG64 offset );
///////////////////////////////////////////////////////////////////////////////////

View File

@ -37,6 +37,7 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignBytes_, loadSignBytes, 2, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignWords_, loadSignWords, 2, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignDWords_, loadSignDWords, 2, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( loadSignQWords_, loadSignQWords, 2, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( compareMemory_, compareMemory, 3, 4 );
BOOST_PYTHON_MODULE( pykd )
@ -56,6 +57,34 @@ BOOST_PYTHON_MODULE( pykd )
"Go debugging" );
// Manage target memory access
python::def( "isValid", &isVaValid,
"Check if the virtual address is valid" );
python::def( "compareMemory", &compareMemory, compareMemory_( python::args( "offset1", "offset2", "length", "phyAddr" ),
"Compare two memory buffers by virtual or physical addresses" ) );
python::def( "ptrByte", &ptrByte,
"Read an unsigned 1-byte integer from the target memory" );
python::def( "ptrWord", &ptrWord,
"Read an unsigned 2-byte integer from the target memory" );
python::def( "ptrDWord", (ULONG64(*)(ULONG64))&ptrDWord,
"Read an unsigned 4-byte integer from the target memory" );
python::def( "ptrQWord", (ULONG64(*)(ULONG64))&ptrQWord,
"Read an unsigned 8-byte integer from the target memory" );
python::def( "ptrMWord", (ULONG64(*)(ULONG64))&ptrMWord,
"Read an unsigned mashine's word wide integer from the target memory" );
python::def( "ptrSignByte", &ptrSignByte,
"Read an signed 1-byte integer from the target memory" );
python::def( "ptrSignWord", &ptrSignWord,
"Read an signed 2-byte integer from the target memory" );
python::def( "ptrSignDWord", &ptrSignDWord,
"Read an signed 4-byte integer from the target memory" );
python::def( "ptrSignQWord", &ptrSignQWord,
"Read an signed 8-byte integer from the target memory" );
python::def( "ptrSignMWord", &ptrSignMWord,
"Read an signed mashine's word wide integer from the target memory" );
python::def( "ptrPtr", (ULONG64(*)(ULONG64))&ptrPtr,
"Read an pointer value from the target memory" );
python::def( "loadBytes", &loadBytes, loadBytes_( python::args( "offset", "count", "phyAddr" ),
"Read the block of the target's memory and return it as liat of unsigned bytes" ) );
python::def( "loadWords", &loadWords, loadWords_( python::args( "offset", "count", "phyAddr" ),
@ -72,22 +101,22 @@ BOOST_PYTHON_MODULE( pykd )
"Read the block of the target's memory and return it as list of signed longs" ) );
python::def( "loadSignQWords", &loadSignQWords, loadSignQWords_( python::args( "offset", "count", "phyAddr" ),
"Read the block of the target's memory and return it as list of signed long longs" ) );
//python::def( "loadChars", &loadChars, loadChars_( python::args( "address", "count", "phyAddr" ),
// "Load string from target memory" ) );
//python::def( "loadWChars", &loadWChars, loadWChars_( python::args( "address", "count", "phyAddr" ),
// "Load string from target memory" ) );
//python::def( "loadCStr", &loadCStr,
// "Load string from the target buffer containing 0-terminated ansi-string" );
//python::def( "loadWStr", &loadWStr,
// "Load string from the target buffer containing 0-terminated unicode-string" );
//python::def( "loadUnicodeString", &loadUnicodeStr,
// "Return string represention of windows UNICODE_STRING type" );
//python::def( "loadAnsiString", &loadAnsiStr,
// "Return string represention of windows ANSU_STRING type" );
//python::def( "loadPtrList", &loadPtrList,
// "Return list of pointers, each points to next" );
//python::def( "loadPtrs", &loadPtrArray,
// "Read the block of the target's memory and return it as a list of pointers" );
python::def( "loadChars", &loadChars, loadChars_( python::args( "address", "count", "phyAddr" ),
"Load string from target memory" ) );
python::def( "loadWChars", &loadWChars, loadWChars_( python::args( "address", "count", "phyAddr" ),
"Load string from target memory" ) );
python::def( "loadCStr", &loadCStr,
"Load string from the target buffer containing 0-terminated ansi-string" );
python::def( "loadWStr", &loadWStr,
"Load string from the target buffer containing 0-terminated unicode-string" );
python::def( "loadUnicodeString", &loadUnicodeStr,
"Return string represention of windows UNICODE_STRING type" );
python::def( "loadAnsiString", &loadAnsiStr,
"Return string represention of windows ANSI_STRING type" );
python::def( "loadPtrList", &loadPtrList,
"Return list of pointers, each points to next" );
python::def( "loadPtrs", &loadPtrArray,
"Read the block of the target's memory and return it as a list of pointers" );
python::class_<intBase>( "intBase", "intBase", python::no_init )

View File

@ -227,6 +227,22 @@ std::string getModuleSymbolFileName( ULONG64 baseOffset )
///////////////////////////////////////////////////////////////////////////////////
ULONG ptrSize()
{
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
HRESULT hres;
hres = g_dbgEng->control->IsPointer64Bit();
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::IsPointer64Bit failed" );
return S_OK == hres ? 8 : 4;
}
///////////////////////////////////////////////////////////////////////////////////
};

View File

@ -41,6 +41,30 @@ ULONG64 addr64( ULONG64 addr )
///////////////////////////////////////////////////////////////////////////////////
bool isVaValid( ULONG64 addr )
{
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
HRESULT hres;
ULONG offsetInfo;
hres =
g_dbgEng->dataspace->GetOffsetInformation(
DEBUG_DATA_SPACE_VIRTUAL,
DEBUG_OFFSINFO_VIRTUAL_SOURCE,
addr64NoSafe( addr ),
&offsetInfo,
sizeof( offsetInfo ),
NULL );
if ( FAILED( hres ) )
throw DbgException( "IDebugDataSpace4::GetOffsetInformation failed" );
return offsetInfo != DEBUG_VSOURCE_INVALID;
}
///////////////////////////////////////////////////////////////////////////////////
void readMemory( ULONG64 offset, PVOID buffer, ULONG length, bool phyAddr )
{
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
@ -53,8 +77,7 @@ void readMemory( ULONG64 offset, PVOID buffer, ULONG length, bool phyAddr )
// workitem/10473 workaround
ULONG64 nextAddress;
hres =
g_dbgEng->dataspace->GetNextDifferentlyValidOffsetVirtual( offset, &nextAddress );
hres = g_dbgEng->dataspace->GetNextDifferentlyValidOffsetVirtual( offset, &nextAddress );
DBG_UNREFERENCED_LOCAL_VARIABLE(nextAddress);
@ -71,4 +94,79 @@ void readMemory( ULONG64 offset, PVOID buffer, ULONG length, bool phyAddr )
///////////////////////////////////////////////////////////////////////////////////
std::string loadCStr( ULONG64 offset )
{
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
const size_t maxLength = 0x10000;
offset = addr64NoSafe( offset );
ULONG strLength = 0;
HRESULT hres =
g_dbgEng->dataspace->ReadMultiByteStringVirtual(
offset,
maxLength,
NULL,
0,
&strLength );
if ( FAILED( hres ) )
throw MemoryException( offset );
std::vector<char> buffer(strLength);
hres =
g_dbgEng->dataspace->ReadMultiByteStringVirtual(
offset,
strLength,
&buffer[0],
strLength,
NULL );
if ( FAILED( hres ) )
throw MemoryException( offset );
return std::string( &buffer[0] );
}
///////////////////////////////////////////////////////////////////////////////////
std::wstring loadWStr( ULONG64 offset )
{
PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate );
const size_t maxLength = 0x10000;
offset = addr64NoSafe( offset );
ULONG strLength = 0;
HRESULT hres =
g_dbgEng->dataspace->ReadUnicodeStringVirtualWide(
offset,
maxLength,
NULL,
0,
&strLength );
std::vector<wchar_t> buffer(strLength);
hres =
g_dbgEng->dataspace->ReadUnicodeStringVirtualWide(
offset,
strLength,
&buffer[0],
strLength,
NULL );
if ( FAILED( hres ) )
throw MemoryException( offset );
return std::wstring( &buffer[0] );
}
///////////////////////////////////////////////////////////////////////////////////
}; //namespace pykd