ReactOS 0.4.16-dev-340-g0540c21
dbgbuffer.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS system libraries
3 * LICENSE: GPL-2.0 (https://spdx.org/licenses/GPL-2.0)
4 * PURPOSE: RTL_DEBUG_INFORMATION implementation
5 * COPYRIGHT: Copyright James Tabor
6 * Copyright 2020 Mark Jansen (mark.jansen@reactos.org)
7 */
8
9/* INCLUDES *****************************************************************/
10
11#include <rtl.h>
12
13#define NDEBUG
14#include <debug.h>
15
16/* FUNCTIONS *****************************************************************/
17
22{
23 ULONG Remaining = Buffer->CommitSize - Buffer->OffsetFree;
26
27 if (Size > MAXLONG)
28 return NULL;
29
30 if (Remaining < Size)
31 {
32 PVOID Buf;
34
35 Buf = (PVOID)((ULONG_PTR)Buffer->ViewBaseClient + Buffer->CommitSize);
36 CommitSize = Size - Remaining;
37
38 /* this is not going to end well.. */
39 if (CommitSize > MAXLONG)
40 return NULL;
41
43 if (!NT_SUCCESS(Status))
44 return NULL;
45
46 Buffer->CommitSize += CommitSize;
47 Remaining = Buffer->CommitSize - Buffer->OffsetFree;
48 /* Sanity check */
49 ASSERT(Remaining >= Size);
50 if (Remaining < Size)
51 return NULL;
52 }
53
54 Result = (PBYTE)Buffer->ViewBaseClient + Buffer->OffsetFree;
55 Buffer->OffsetFree += Size;
56
57 return Result;
58}
59
60
61/*
62 * @unimplemented
63 */
67 _In_ BOOLEAN EventPair)
68{
72 SIZE_T CommitSize = sizeof(*Buf);
73
74 /* Reserve the memory */
76 if (!NT_SUCCESS(Status))
77 return NULL;
78
79 /* Commit the first data, CommitSize is updated with the actual committed data */
81 if (!NT_SUCCESS(Status))
82 {
84 return NULL;
85 }
86
87 /* Fill out the minimum data required */
88 Buf->ViewBaseClient = Buf;
91 Buf->OffsetFree = sizeof(*Buf);
92
93 return Buf;
94}
95
96/*
97 * @unimplemented
98 */
100NTAPI
102{
104 SIZE_T ViewSize = 0;
105
106 if (NULL != Buf)
107 {
109 (PVOID*)&Buf,
110 &ViewSize,
112 }
113 if (!NT_SUCCESS(Status))
114 {
115 DPRINT1("RtlDQDB: Failed to free VM!\n");
116 }
117 return Status;
118}
119
120/*
121 * Based on lib/epsapi/enum/modules.c by KJK::Hyperion.
122 */
124NTAPI
129{
131 PPEB_LDR_DATA ppldLdrData;
132 LDR_DATA_TABLE_ENTRY lmModule;
133 PLIST_ENTRY pleListHead;
134 PLIST_ENTRY pleCurEntry;
135
138 ULONG UsedSize = sizeof(ULONG);
140 PCHAR p;
141
142 DPRINT("RtlpQueryRemoteProcessModules Start\n");
143
144 /* query the process basic information (includes the PEB address) */
147 &pbiInfo,
149 NULL);
150
151 if (!NT_SUCCESS(Status))
152 {
153 /* failure */
154 DPRINT("NtQueryInformationProcess 1 0x%lx\n", Status);
155 return Status;
156 }
157
158 if (Modules == NULL || Size == 0)
159 {
161 }
162 else
163 {
164 Modules->NumberOfModules = 0;
165 ModulePtr = &Modules->Modules[0];
167 }
168
169 /* get the address of the PE Loader data */
171 &(pbiInfo.PebBaseAddress->Ldr),
172 &ppldLdrData,
173 sizeof(ppldLdrData),
174 NULL);
175
176 if (!NT_SUCCESS(Status))
177 {
178 /* failure */
179 DPRINT("NtReadVirtualMemory 1 0x%lx\n", Status);
180 return Status;
181 }
182
183
184 /* head of the module list: the last element in the list will point to this */
185 pleListHead = &ppldLdrData->InLoadOrderModuleList;
186
187 /* get the address of the first element in the list */
189 &(ppldLdrData->InLoadOrderModuleList.Flink),
190 &pleCurEntry,
191 sizeof(pleCurEntry),
192 NULL);
193
194 if (!NT_SUCCESS(Status))
195 {
196 /* failure */
197 DPRINT("NtReadVirtualMemory 2 0x%lx\n", Status);
198 return Status;
199 }
200
201 while(pleCurEntry != pleListHead)
202 {
203 UNICODE_STRING Unicode;
204 WCHAR Buffer[256 * sizeof(WCHAR)];
205
206 /* read the current module */
208 CONTAINING_RECORD(pleCurEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks),
209 &lmModule,
210 sizeof(LDR_DATA_TABLE_ENTRY),
211 NULL);
212
213 if (!NT_SUCCESS(Status))
214 {
215 /* failure */
216 DPRINT( "NtReadVirtualMemory 3 0x%lx\n", Status);
217 return Status;
218 }
219
220 /* Import module name from remote Process user space. */
221 Unicode.Length = lmModule.FullDllName.Length;
222 Unicode.MaximumLength = lmModule.FullDllName.MaximumLength;
223 Unicode.Buffer = Buffer;
224
226 lmModule.FullDllName.Buffer,
227 Unicode.Buffer,
228 Unicode.Length,
229 NULL);
230
231 if (!NT_SUCCESS(Status))
232 {
233 /* failure */
234 DPRINT( "NtReadVirtualMemory 3 0x%lx\n", Status);
235 return Status;
236 }
237
238 DPRINT(" Module %wZ\n", &Unicode);
239
240 if (UsedSize > Size)
241 {
243 }
244 else if (Modules != NULL)
245 {
246 ModulePtr->Section = 0;
247 ModulePtr->MappedBase = NULL; // FIXME: ??
248 ModulePtr->ImageBase = lmModule.DllBase;
249 ModulePtr->ImageSize = lmModule.SizeOfImage;
250 ModulePtr->Flags = lmModule.Flags;
251 ModulePtr->LoadOrderIndex = 0; // FIXME: ??
252 ModulePtr->InitOrderIndex = 0; // FIXME: ??
253 ModulePtr->LoadCount = lmModule.LoadCount;
254
255 AnsiString.Length = 0;
256 AnsiString.MaximumLength = 256;
257 AnsiString.Buffer = ModulePtr->FullPathName;
259 &Unicode,
260 FALSE);
261
262 p = strrchr(ModulePtr->FullPathName, '\\');
263 if (p != NULL)
264 ModulePtr->OffsetToFileName = (USHORT)(p - ModulePtr->FullPathName + 1);
265 else
266 ModulePtr->OffsetToFileName = 0;
267
268 ModulePtr++;
269 Modules->NumberOfModules++;
270 }
271 UsedSize += sizeof(RTL_PROCESS_MODULE_INFORMATION);
272
273 /* address of the next module in the list */
274 pleCurEntry = lmModule.InLoadOrderLinks.Flink;
275 }
276
277 if (ReturnedSize != 0)
278 *ReturnedSize = UsedSize;
279
280 DPRINT("RtlpQueryRemoteProcessModules End\n");
281
282 /* success */
283 return (STATUS_SUCCESS);
284}
285
286/*
287 * @unimplemented
288 */
290NTAPI
292 IN ULONG DebugInfoMask,
294{
296 ULONG Pid = (ULONG)(ULONG_PTR) NtCurrentTeb()->ClientId.UniqueProcess;
297
298 Buf->Flags = DebugInfoMask;
299 Buf->OffsetFree = sizeof(RTL_DEBUG_INFORMATION);
300
301 DPRINT("QueryProcessDebugInformation Start\n");
302
303 /*
304 Currently ROS can not read-only from kenrel space, and doesn't
305 check for boundaries inside kernel space that are page protected
306 from every one but the kernel. aka page 0 - 2
307 */
308 if (ProcessId <= 1)
309 {
311 }
312 else
313 if (Pid == ProcessId)
314 {
315 if (DebugInfoMask & RTL_DEBUG_QUERY_MODULES)
316 {
318 ULONG ReturnSize = 0;
319
320 /* I like this better than the do & while loop. */
322 0,
323 &ReturnSize);
324
325 Mp = RtlpDebugBufferCommit(Buf, ReturnSize);
326 if (!Mp)
327 {
328 DPRINT1("RtlQueryProcessDebugInformation: Unable to commit %u\n", ReturnSize);
329 }
330
332 ReturnSize,
333 &ReturnSize);
334 if (!NT_SUCCESS(Status))
335 {
336 return Status;
337 }
338
339 Buf->Modules = Mp;
340 }
341
342 if (DebugInfoMask & RTL_DEBUG_QUERY_HEAPS)
343 {
345 ULONG HSize;
346
347 Hp = (PRTL_PROCESS_HEAPS)((PUCHAR)Buf + Buf->OffsetFree);
348 HSize = sizeof(RTL_PROCESS_HEAPS);
349 if (DebugInfoMask & RTL_DEBUG_QUERY_HEAP_TAGS)
350 {
351 // TODO
352 }
353 if (DebugInfoMask & RTL_DEBUG_QUERY_HEAP_BLOCKS)
354 {
355 // TODO
356 }
357 Buf->Heaps = Hp;
358 Buf->OffsetFree = Buf->OffsetFree + HSize;
359
360 }
361
362 if (DebugInfoMask & RTL_DEBUG_QUERY_LOCKS)
363 {
365 ULONG LSize;
366
367 Lp = (PRTL_PROCESS_LOCKS)((PUCHAR)Buf + Buf->OffsetFree);
368 LSize = sizeof(RTL_PROCESS_LOCKS);
369 Buf->Locks = Lp;
370 Buf->OffsetFree = Buf->OffsetFree + LSize;
371 }
372
373 DPRINT("QueryProcessDebugInformation end\n");
374 DPRINT("QueryDebugInfo : 0x%lx\n", Buf->OffsetFree);
375 }
376 else
377 {
381
382 Buf->TargetProcessHandle = NtCurrentProcess();
383
387 NULL,
388 0,
389 NULL,
390 NULL);
391
395 &ClientId );
396 if (!NT_SUCCESS(Status))
397 {
398 return Status;
399 }
400
401 if (DebugInfoMask & RTL_DEBUG_QUERY_MODULES)
402 {
404 ULONG ReturnSize = 0;
405
407 NULL,
408 0,
409 &ReturnSize);
410
411 Mp = RtlpDebugBufferCommit(Buf, ReturnSize);
412 if (!Mp)
413 {
414 DPRINT1("RtlQueryProcessDebugInformation: Unable to commit %u\n", ReturnSize);
415 }
416
418 Mp,
419 ReturnSize ,
420 &ReturnSize);
421 if (!NT_SUCCESS(Status))
422 {
423 return Status;
424 }
425
426 Buf->Modules = Mp;
427 }
428
429 if (DebugInfoMask & RTL_DEBUG_QUERY_HEAPS)
430 {
432 ULONG HSize;
433
434 Hp = (PRTL_PROCESS_HEAPS)((PUCHAR)Buf + Buf->OffsetFree);
435 HSize = sizeof(RTL_PROCESS_HEAPS);
436 if (DebugInfoMask & RTL_DEBUG_QUERY_HEAP_TAGS)
437 {
438 // TODO
439 }
440 if (DebugInfoMask & RTL_DEBUG_QUERY_HEAP_BLOCKS)
441 {
442 // TODO
443 }
444 Buf->Heaps = Hp;
445 Buf->OffsetFree = Buf->OffsetFree + HSize;
446
447 }
448
449 if (DebugInfoMask & RTL_DEBUG_QUERY_LOCKS)
450 {
452 ULONG LSize;
453
454 Lp = (PRTL_PROCESS_LOCKS)((PUCHAR)Buf + Buf->OffsetFree);
455 LSize = sizeof(RTL_PROCESS_LOCKS);
456 Buf->Locks = Lp;
457 Buf->OffsetFree = Buf->OffsetFree + LSize;
458 }
459
460 DPRINT("QueryProcessDebugInformation end\n");
461 DPRINT("QueryDebugInfo : 0x%lx\n", Buf->OffsetFree);
462 }
463
464 return Status;
465}
466
467/* EOL */
unsigned char BOOLEAN
ULONG ReturnedSize
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
NTSTATUS NTAPI RtlpQueryRemoteProcessModules(HANDLE ProcessHandle, IN PRTL_PROCESS_MODULES Modules OPTIONAL, IN ULONG Size OPTIONAL, OUT PULONG ReturnedSize)
Definition: dbgbuffer.c:125
NTSTATUS NTAPI RtlDestroyQueryDebugBuffer(_In_ PRTL_DEBUG_INFORMATION Buf)
Definition: dbgbuffer.c:101
PRTL_DEBUG_INFORMATION NTAPI RtlCreateQueryDebugBuffer(_In_ ULONG Size, _In_ BOOLEAN EventPair)
Definition: dbgbuffer.c:66
PVOID NTAPI RtlpDebugBufferCommit(_Inout_ PRTL_DEBUG_INFORMATION Buffer, _In_ SIZE_T Size)
Definition: dbgbuffer.c:20
NTSTATUS NTAPI RtlQueryProcessDebugInformation(IN ULONG ProcessId, IN ULONG DebugInfoMask, IN OUT PRTL_DEBUG_INFORMATION Buf)
Definition: dbgbuffer.c:291
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
@ AnsiString
Definition: dnslib.h:19
#define PAGE_SIZE
Definition: env_spec_w32.h:49
IN PFCB IN PFILE_OBJECT FileObject IN ULONG AllocationSize
Definition: fatprocs.h:323
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2712
Status
Definition: gdiplustypes.h:25
GLfloat GLfloat p
Definition: glext.h:8902
#define Mp
Definition: i386-dis.c:360
@ ProcessBasicInformation
Definition: winternl.h:394
#define NtCurrentTeb
NTSTATUS NTAPI LdrQueryProcessModuleInformation(_Out_writes_bytes_to_(Size, *ReturnedSize) PRTL_PROCESS_MODULES ModuleInformation, _In_ ULONG Size, _Out_opt_ PULONG ReturnedSize)
Definition: ldrapi.c:1076
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
#define ASSERT(a)
Definition: mode.c:44
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T CommitSize
Definition: mmfuncs.h:406
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:408
#define RTL_DEBUG_QUERY_LOCKS
Definition: rtltypes.h:371
#define RTL_DEBUG_QUERY_HEAPS
Definition: rtltypes.h:368
struct _RTL_PROCESS_MODULE_INFORMATION RTL_PROCESS_MODULE_INFORMATION
#define RTL_DEBUG_QUERY_MODULES
Definition: rtltypes.h:366
struct _RTL_PROCESS_LOCKS * PRTL_PROCESS_LOCKS
struct _RTL_PROCESS_HEAPS RTL_PROCESS_HEAPS
struct _RTL_DEBUG_INFORMATION RTL_DEBUG_INFORMATION
struct _RTL_PROCESS_HEAPS * PRTL_PROCESS_HEAPS
struct _RTL_PROCESS_LOCKS RTL_PROCESS_LOCKS
#define RTL_DEBUG_QUERY_HEAP_TAGS
Definition: rtltypes.h:369
#define RTL_DEBUG_QUERY_HEAP_BLOCKS
Definition: rtltypes.h:370
#define _Inout_
Definition: no_sal2.h:162
#define _In_
Definition: no_sal2.h:158
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define PROCESS_ALL_ACCESS
Definition: nt_native.h:1324
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define MEM_RESERVE
Definition: nt_native.h:1314
#define MEM_RELEASE
Definition: nt_native.h:1316
#define MEM_COMMIT
Definition: nt_native.h:1313
NTSTATUS NTAPI NtFreeVirtualMemory(IN HANDLE ProcessHandle, IN PVOID *UBaseAddress, IN PSIZE_T URegionSize, IN ULONG FreeType)
Definition: virtual.c:5230
NTSTATUS NTAPI NtReadVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, OUT PVOID Buffer, IN SIZE_T NumberOfBytesToRead, OUT PSIZE_T NumberOfBytesRead OPTIONAL)
Definition: virtual.c:2816
NTSTATUS NTAPI NtAllocateVirtualMemory(IN HANDLE ProcessHandle, IN OUT PVOID *UBaseAddress, IN ULONG_PTR ZeroBits, IN OUT PSIZE_T URegionSize, IN ULONG AllocationType, IN ULONG Protect)
Definition: virtual.c:4492
NTSTATUS NTAPI NtOpenProcess(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId)
Definition: process.c:1440
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:59
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
BYTE * PBYTE
Definition: pedump.c:66
unsigned short USHORT
Definition: pedump.c:61
_CRT_RESTORE_GCC_WARNINGS _CRT_DISABLE_GCC_WARNINGS _Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
HANDLE UniqueThread
Definition: compat.h:826
HANDLE UniqueProcess
Definition: compat.h:825
Definition: btrfs_drv.h:1876
USHORT LoadCount
Definition: ntddk_ex.h:208
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1882
ULONG SizeOfImage
Definition: ldrtypes.h:143
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:138
PVOID DllBase
Definition: btrfs_drv.h:1880
ULONG Flags
Definition: ntddk_ex.h:207
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY InLoadOrderModuleList
Definition: ldrtypes.h:120
PPEB_LDR_DATA Ldr
Definition: btrfs_drv.h:1912
RTL_HEAP_INFORMATION Heaps[1]
Definition: rtltypes.h:1135
RTL_PROCESS_LOCK_INFORMATION Locks[1]
Definition: rtltypes.h:1155
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
PVOID HANDLE
Definition: typedefs.h:73
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define MAXLONG
Definition: umtypes.h:116
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1151
__wchar_t WCHAR
Definition: xmlstorage.h:180