kdlibcpp

Форк
0
/
dbgmem.cpp 
373 строки · 9.7 Кб
1
#include "stdafx.h"
2

3
#include <vector>
4

5
#include <windows.h>
6

7
#include <boost/numeric/conversion/cast.hpp>
8

9
#include "kdlib/dbgengine.h"
10

11
#include "win/dbgmgr.h"
12
#include "win/exceptions.h"
13

14
using boost::numeric_cast;
15

16
namespace  kdlib {
17

18
///////////////////////////////////////////////////////////////////////////////
19

20
MEMOFFSET_64 addr64( MEMOFFSET_64 offset )
21
{
22
    HRESULT     hres;
23

24
    ULONG   processorMode;
25
    hres = g_dbgMgr->control->GetActualProcessorType( &processorMode );
26
    if (FAILED(hres))
27
    {
28
        if (sizeof(void*) == 4 && *((ULONG*)&offset + 1) == 0)
29
            return (ULONG64)(LONG)offset;
30
        return offset;
31
    }
32

33
    switch( processorMode )
34
    {
35
    case IMAGE_FILE_MACHINE_I386:
36
    case IMAGE_FILE_MACHINE_ARMNT:
37
        if ( *( (ULONG*)&offset + 1 ) == 0 )
38
            return (ULONG64)(LONG)offset;
39

40
    case IMAGE_FILE_MACHINE_AMD64:
41
    case IMAGE_FILE_MACHINE_ARM64:
42
        break;
43

44
    default:
45
        throw DbgException( "Unknown processor type" );
46
        break;
47
    }
48

49
    return offset;
50
}
51

52
///////////////////////////////////////////////////////////////////////////////
53

54
void readMemory( MEMOFFSET_64 offset, void* buffer, size_t length, bool phyAddr, unsigned long *readed )
55
{
56
    offset = addr64(offset);
57

58
    unsigned long readedLocal = 0;
59
    if ( readed )
60
        *readed = 0;
61

62
    HRESULT hres;
63

64
    if ( phyAddr == false )
65
    {
66
        offset = addr64( offset );
67

68
        hres = g_dbgMgr->dataspace->ReadVirtual( offset, buffer, numeric_cast<ULONG>(length), readed ? readed : &readedLocal );
69
    }
70
    else
71
    {
72
        hres = g_dbgMgr->dataspace->ReadPhysical( offset, buffer,  numeric_cast<ULONG>(length), readed ? readed : &readedLocal );
73
    }
74

75
    if ( FAILED( hres ) )
76
        throw MemoryException( offset, phyAddr );
77

78
    if (!readed && (readedLocal < length))
79
    {
80
        // read less than requested, but "readed" has nowhere to return
81
        throw MemoryException( offset + readedLocal, phyAddr );
82
    }
83
}
84

85
///////////////////////////////////////////////////////////////////////////////
86

87
void writeMemory( MEMOFFSET_64 offset, const void* buffer, size_t length, bool phyAddr = false, unsigned long *written = 0 )
88
{
89
    offset = addr64(offset);
90

91
    if ( written )
92
        *written = 0;
93

94
    HRESULT hres;
95

96
    if ( phyAddr == false )
97
    {
98
        offset = addr64( offset );
99

100
        hres = g_dbgMgr->dataspace->WriteVirtual( offset, const_cast<PVOID>(buffer), numeric_cast<ULONG>(length), written );
101
    }
102
    else
103
    {
104
        hres = g_dbgMgr->dataspace->WritePhysical( offset, const_cast<PVOID>(buffer),  numeric_cast<ULONG>(length), written );
105
    }
106

107
    if ( FAILED( hres ) )
108
        throw MemoryException( offset, phyAddr );
109
}
110

111
///////////////////////////////////////////////////////////////////////////////
112

113
bool readMemoryUnsafe( MEMOFFSET_64 offset, void* buffer, size_t length, bool phyAddr, unsigned long *readed  )
114
{
115
    offset = addr64(offset);
116

117
    HRESULT hres;
118
    if ( phyAddr == false )
119
    {
120
        offset = addr64( offset );
121

122
        // workitem/10473 workaround
123
        ULONG64 nextAddress;
124
        hres = g_dbgMgr->dataspace->GetNextDifferentlyValidOffsetVirtual( offset, &nextAddress );
125

126
        DBG_UNREFERENCED_LOCAL_VARIABLE(nextAddress);
127

128
        hres = g_dbgMgr->dataspace->ReadVirtual( offset, buffer,  numeric_cast<ULONG>(length), readed );
129
    }
130
    else
131
    {
132
        hres = g_dbgMgr->dataspace->ReadPhysical( offset, buffer,  numeric_cast<ULONG>(length), readed );
133
    }
134

135
    return hres == S_OK;
136
}
137

138
///////////////////////////////////////////////////////////////////////////////
139

140
bool isVaValid( MEMOFFSET_64 offset )
141
{
142
    offset = addr64(offset);
143

144
    HRESULT     hres;
145
    ULONG       offsetInfo;
146
    
147
    hres = 
148
        g_dbgMgr->dataspace->GetOffsetInformation(
149
            DEBUG_DATA_SPACE_VIRTUAL,
150
            DEBUG_OFFSINFO_VIRTUAL_SOURCE,
151
            addr64( offset ),
152
            &offsetInfo,
153
            sizeof( offsetInfo ),
154
            NULL );
155

156
    if ( FAILED( hres ) )
157
        throw DbgEngException( L"IDebugDataSpace4::GetOffsetInformation", hres );
158

159
    return  offsetInfo != DEBUG_VSOURCE_INVALID;
160
}
161

162
///////////////////////////////////////////////////////////////////////////////
163

164
bool isVaRegionValid(MEMOFFSET_64 addr, size_t length)
165
{
166
    addr = addr64(addr);
167

168
    HRESULT  hres;
169
    ULONG64  validBase = 0;
170
    ULONG  validSize = 0;
171

172
    if (length > 0xFFFFFFFF)
173
        return false;
174

175
    hres = g_dbgMgr->dataspace->GetValidRegionVirtual(addr, numeric_cast<ULONG>(length), &validBase, &validSize);
176

177
    return hres == S_OK && validBase == addr && validSize == length;
178
}
179

180
///////////////////////////////////////////////////////////////////////////////
181

182
std::string loadCStr( MEMOFFSET_64 offset )
183
{
184
   const size_t    maxLength = 0x10000;
185

186
    offset = addr64( offset );
187

188
    ULONG   strLength = 0;
189

190
    HRESULT     hres = 
191
        g_dbgMgr->dataspace->ReadMultiByteStringVirtual(
192
            offset,
193
            maxLength,
194
            NULL,
195
            0,
196
            &strLength );
197

198
    if ( FAILED( hres ) )
199
        throw MemoryException( offset );
200

201
    std::vector<char>  buffer(strLength);
202

203
    hres = 
204
        g_dbgMgr->dataspace->ReadMultiByteStringVirtual(
205
            offset,
206
            strLength,
207
            &buffer[0],
208
            strLength,
209
            NULL );
210

211
    if ( FAILED( hres ) )
212
        throw MemoryException( offset );
213
                           
214
    return std::string( &buffer[0], buffer.size() - 1);
215
}
216

217
///////////////////////////////////////////////////////////////////////////////
218

219
std::wstring loadWStr( MEMOFFSET_64 offset )
220
{
221
    const size_t    maxLength = 0x10000;
222
 
223
    offset = addr64( offset );
224

225
    ULONG   strBytes = 0;
226

227
    HRESULT     hres = 
228
        g_dbgMgr->dataspace->ReadUnicodeStringVirtualWide(
229
            offset,
230
            maxLength,
231
            NULL,
232
            0,
233
            &strBytes );
234

235
    if ( FAILED( hres ) )
236
        throw MemoryException( offset );
237

238
    std::vector<wchar_t>  buffer(strBytes/sizeof(wchar_t));
239
        
240
    hres = 
241
        g_dbgMgr->dataspace->ReadUnicodeStringVirtualWide(
242
            offset,
243
            strBytes,
244
            &buffer[0],
245
            static_cast<ULONG>(buffer.size()),
246
            NULL );
247
    
248
    if ( FAILED( hres ) )
249
        throw MemoryException( offset );
250

251
     return std::wstring( &buffer[0], buffer.size() - 1);
252
}
253

254
///////////////////////////////////////////////////////////////////////////////
255

256
void writeCStr( MEMOFFSET_64 offset, const std::string& str)
257
{
258
   writeMemory( offset, str.c_str(), str.size() + 1 );
259
}
260

261
///////////////////////////////////////////////////////////////////////////////
262

263
void writeWStr( MEMOFFSET_64 offset, const std::wstring& str)
264
{
265
   writeMemory( offset, str.c_str(), sizeof(wchar_t)*( str.size() + 1 ) );
266
}
267

268
///////////////////////////////////////////////////////////////////////////////
269

270
MEMOFFSET_64 searchMemory( MEMOFFSET_64 beginOffset, unsigned long length, const std::vector<char>& pattern )
271
{
272
    if ( pattern.empty() )
273
        throw DbgException( "searchMemeory: pattern parameter can not have 0 length" );
274

275
    beginOffset = addr64(beginOffset);
276

277
    ULONG64 foundOffset;
278
    HRESULT hres = g_dbgMgr->dataspace->SearchVirtual( beginOffset, length, (PVOID)&pattern[0], (ULONG)pattern.size(), 1, &foundOffset );
279

280
    if ( FAILED( hres ) )
281
        return 0LL;
282

283
    return foundOffset;
284
}
285

286
///////////////////////////////////////////////////////////////////////////////
287

288
MEMOFFSET_64 findMemoryRegion( MEMOFFSET_64 beginOffset, MEMOFFSET_64& regionOffset, unsigned long long &regionLength )
289
{
290

291
    HRESULT  hres;
292

293
    if (isKernelDebugging())
294
        throw DbgException("findMemoryRegion does not work in the kernel mode");
295

296
    beginOffset = addr64(beginOffset);
297

298
    do {
299

300
        MEMORY_BASIC_INFORMATION64  meminfo = {};
301

302
        hres = g_dbgMgr->dataspace->QueryVirtual(beginOffset, &meminfo);
303

304
        if (FAILED(hres))
305
            throw MemoryException(regionOffset);
306

307
        if (meminfo.State == MEM_COMMIT)
308
        {
309
            regionOffset = addr64(meminfo.BaseAddress);
310
            regionLength = meminfo.RegionSize;
311

312
            return regionOffset;
313
        }
314

315
        beginOffset = meminfo.BaseAddress + meminfo.RegionSize;
316

317
    } while (TRUE);
318
}
319

320
///////////////////////////////////////////////////////////////////////////////
321

322
kdlib::MemoryProtect getVaProtect( kdlib::MEMOFFSET_64 offset )
323
{
324
    offset = addr64(offset);
325

326
    HRESULT  hres;
327
    MEMORY_BASIC_INFORMATION64  meminfo = {};
328

329
    hres = g_dbgMgr->dataspace->QueryVirtual( offset, &meminfo );
330

331
    if ( FAILED(hres) )
332
       throw MemoryException( offset );
333

334
    return static_cast<MemoryProtect>(meminfo.Protect);
335
}
336

337
///////////////////////////////////////////////////////////////////////////////
338

339
kdlib::MemoryState getVaState(kdlib::MEMOFFSET_64 offset)
340
{
341
    offset = addr64(offset);
342

343
    HRESULT  hres;
344
    MEMORY_BASIC_INFORMATION64  meminfo = {};
345

346
    hres = g_dbgMgr->dataspace->QueryVirtual(offset, &meminfo);
347

348
    if (FAILED(hres))
349
        throw MemoryException(offset);
350

351
    return static_cast<MemoryState>(meminfo.State);
352
}
353

354
///////////////////////////////////////////////////////////////////////////////
355

356
kdlib::MemoryType getVaType(kdlib::MEMOFFSET_64  offset)
357
{
358
    offset = addr64(offset);
359

360
    HRESULT  hres;
361
    MEMORY_BASIC_INFORMATION64  meminfo = {};
362

363
    hres = g_dbgMgr->dataspace->QueryVirtual(offset, &meminfo);
364

365
    if (FAILED(hres))
366
        throw MemoryException(offset);
367

368
    return static_cast<MemoryType>(meminfo.Type);
369
}
370

371
///////////////////////////////////////////////////////////////////////////////
372

373
}
374

375

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.