7
#include <boost/numeric/conversion/cast.hpp>
9
#include "kdlib/dbgengine.h"
11
#include "win/dbgmgr.h"
12
#include "win/exceptions.h"
14
using boost::numeric_cast;
18
///////////////////////////////////////////////////////////////////////////////
20
MEMOFFSET_64 addr64( MEMOFFSET_64 offset )
25
hres = g_dbgMgr->control->GetActualProcessorType( &processorMode );
28
if (sizeof(void*) == 4 && *((ULONG*)&offset + 1) == 0)
29
return (ULONG64)(LONG)offset;
33
switch( processorMode )
35
case IMAGE_FILE_MACHINE_I386:
36
case IMAGE_FILE_MACHINE_ARMNT:
37
if ( *( (ULONG*)&offset + 1 ) == 0 )
38
return (ULONG64)(LONG)offset;
40
case IMAGE_FILE_MACHINE_AMD64:
41
case IMAGE_FILE_MACHINE_ARM64:
45
throw DbgException( "Unknown processor type" );
52
///////////////////////////////////////////////////////////////////////////////
54
void readMemory( MEMOFFSET_64 offset, void* buffer, size_t length, bool phyAddr, unsigned long *readed )
56
offset = addr64(offset);
58
unsigned long readedLocal = 0;
64
if ( phyAddr == false )
66
offset = addr64( offset );
68
hres = g_dbgMgr->dataspace->ReadVirtual( offset, buffer, numeric_cast<ULONG>(length), readed ? readed : &readedLocal );
72
hres = g_dbgMgr->dataspace->ReadPhysical( offset, buffer, numeric_cast<ULONG>(length), readed ? readed : &readedLocal );
76
throw MemoryException( offset, phyAddr );
78
if (!readed && (readedLocal < length))
80
// read less than requested, but "readed" has nowhere to return
81
throw MemoryException( offset + readedLocal, phyAddr );
85
///////////////////////////////////////////////////////////////////////////////
87
void writeMemory( MEMOFFSET_64 offset, const void* buffer, size_t length, bool phyAddr = false, unsigned long *written = 0 )
89
offset = addr64(offset);
96
if ( phyAddr == false )
98
offset = addr64( offset );
100
hres = g_dbgMgr->dataspace->WriteVirtual( offset, const_cast<PVOID>(buffer), numeric_cast<ULONG>(length), written );
104
hres = g_dbgMgr->dataspace->WritePhysical( offset, const_cast<PVOID>(buffer), numeric_cast<ULONG>(length), written );
107
if ( FAILED( hres ) )
108
throw MemoryException( offset, phyAddr );
111
///////////////////////////////////////////////////////////////////////////////
113
bool readMemoryUnsafe( MEMOFFSET_64 offset, void* buffer, size_t length, bool phyAddr, unsigned long *readed )
115
offset = addr64(offset);
118
if ( phyAddr == false )
120
offset = addr64( offset );
122
// workitem/10473 workaround
124
hres = g_dbgMgr->dataspace->GetNextDifferentlyValidOffsetVirtual( offset, &nextAddress );
126
DBG_UNREFERENCED_LOCAL_VARIABLE(nextAddress);
128
hres = g_dbgMgr->dataspace->ReadVirtual( offset, buffer, numeric_cast<ULONG>(length), readed );
132
hres = g_dbgMgr->dataspace->ReadPhysical( offset, buffer, numeric_cast<ULONG>(length), readed );
138
///////////////////////////////////////////////////////////////////////////////
140
bool isVaValid( MEMOFFSET_64 offset )
142
offset = addr64(offset);
148
g_dbgMgr->dataspace->GetOffsetInformation(
149
DEBUG_DATA_SPACE_VIRTUAL,
150
DEBUG_OFFSINFO_VIRTUAL_SOURCE,
153
sizeof( offsetInfo ),
156
if ( FAILED( hres ) )
157
throw DbgEngException( L"IDebugDataSpace4::GetOffsetInformation", hres );
159
return offsetInfo != DEBUG_VSOURCE_INVALID;
162
///////////////////////////////////////////////////////////////////////////////
164
bool isVaRegionValid(MEMOFFSET_64 addr, size_t length)
169
ULONG64 validBase = 0;
172
if (length > 0xFFFFFFFF)
175
hres = g_dbgMgr->dataspace->GetValidRegionVirtual(addr, numeric_cast<ULONG>(length), &validBase, &validSize);
177
return hres == S_OK && validBase == addr && validSize == length;
180
///////////////////////////////////////////////////////////////////////////////
182
std::string loadCStr( MEMOFFSET_64 offset )
184
const size_t maxLength = 0x10000;
186
offset = addr64( offset );
191
g_dbgMgr->dataspace->ReadMultiByteStringVirtual(
198
if ( FAILED( hres ) )
199
throw MemoryException( offset );
201
std::vector<char> buffer(strLength);
204
g_dbgMgr->dataspace->ReadMultiByteStringVirtual(
211
if ( FAILED( hres ) )
212
throw MemoryException( offset );
214
return std::string( &buffer[0], buffer.size() - 1);
217
///////////////////////////////////////////////////////////////////////////////
219
std::wstring loadWStr( MEMOFFSET_64 offset )
221
const size_t maxLength = 0x10000;
223
offset = addr64( offset );
228
g_dbgMgr->dataspace->ReadUnicodeStringVirtualWide(
235
if ( FAILED( hres ) )
236
throw MemoryException( offset );
238
std::vector<wchar_t> buffer(strBytes/sizeof(wchar_t));
241
g_dbgMgr->dataspace->ReadUnicodeStringVirtualWide(
245
static_cast<ULONG>(buffer.size()),
248
if ( FAILED( hres ) )
249
throw MemoryException( offset );
251
return std::wstring( &buffer[0], buffer.size() - 1);
254
///////////////////////////////////////////////////////////////////////////////
256
void writeCStr( MEMOFFSET_64 offset, const std::string& str)
258
writeMemory( offset, str.c_str(), str.size() + 1 );
261
///////////////////////////////////////////////////////////////////////////////
263
void writeWStr( MEMOFFSET_64 offset, const std::wstring& str)
265
writeMemory( offset, str.c_str(), sizeof(wchar_t)*( str.size() + 1 ) );
268
///////////////////////////////////////////////////////////////////////////////
270
MEMOFFSET_64 searchMemory( MEMOFFSET_64 beginOffset, unsigned long length, const std::vector<char>& pattern )
272
if ( pattern.empty() )
273
throw DbgException( "searchMemeory: pattern parameter can not have 0 length" );
275
beginOffset = addr64(beginOffset);
278
HRESULT hres = g_dbgMgr->dataspace->SearchVirtual( beginOffset, length, (PVOID)&pattern[0], (ULONG)pattern.size(), 1, &foundOffset );
280
if ( FAILED( hres ) )
286
///////////////////////////////////////////////////////////////////////////////
288
MEMOFFSET_64 findMemoryRegion( MEMOFFSET_64 beginOffset, MEMOFFSET_64& regionOffset, unsigned long long ®ionLength )
293
if (isKernelDebugging())
294
throw DbgException("findMemoryRegion does not work in the kernel mode");
296
beginOffset = addr64(beginOffset);
300
MEMORY_BASIC_INFORMATION64 meminfo = {};
302
hres = g_dbgMgr->dataspace->QueryVirtual(beginOffset, &meminfo);
305
throw MemoryException(regionOffset);
307
if (meminfo.State == MEM_COMMIT)
309
regionOffset = addr64(meminfo.BaseAddress);
310
regionLength = meminfo.RegionSize;
315
beginOffset = meminfo.BaseAddress + meminfo.RegionSize;
320
///////////////////////////////////////////////////////////////////////////////
322
kdlib::MemoryProtect getVaProtect( kdlib::MEMOFFSET_64 offset )
324
offset = addr64(offset);
327
MEMORY_BASIC_INFORMATION64 meminfo = {};
329
hres = g_dbgMgr->dataspace->QueryVirtual( offset, &meminfo );
332
throw MemoryException( offset );
334
return static_cast<MemoryProtect>(meminfo.Protect);
337
///////////////////////////////////////////////////////////////////////////////
339
kdlib::MemoryState getVaState(kdlib::MEMOFFSET_64 offset)
341
offset = addr64(offset);
344
MEMORY_BASIC_INFORMATION64 meminfo = {};
346
hres = g_dbgMgr->dataspace->QueryVirtual(offset, &meminfo);
349
throw MemoryException(offset);
351
return static_cast<MemoryState>(meminfo.State);
354
///////////////////////////////////////////////////////////////////////////////
356
kdlib::MemoryType getVaType(kdlib::MEMOFFSET_64 offset)
358
offset = addr64(offset);
361
MEMORY_BASIC_INFORMATION64 meminfo = {};
363
hres = g_dbgMgr->dataspace->QueryVirtual(offset, &meminfo);
366
throw MemoryException(offset);
368
return static_cast<MemoryType>(meminfo.Type);
371
///////////////////////////////////////////////////////////////////////////////