8 #include "..\..\debug\p\native\maps\windows_maps.h"
9 #include "..\..\bin\pdb\pdb_downloader.h"
10 #include "..\..\bin\pdb\pdb.h"
52 #define PDI_MODULES 0x01
53 #define PDI_HEAPS 0x04
54 #define PDI_HEAP_TAGS 0x08
55 #define PDI_HEAP_BLOCKS 0x10
56 #define PDI_HEAP_ENTRIES_EX 0x200
61 #define CHECK_INFO(heapInfo) \
63 eprintf("It wasn't possible to get the heap information\n"); \
66 if (!heapInfo->count) { \
67 rz_cons_print("No heaps for this process\n"); \
71 #define CHECK_INFO_RETURN_NULL(heapInfo) \
73 eprintf("It wasn't possible to get the heap information\n"); \
76 if (!heapInfo->count) { \
77 rz_cons_print("No heaps for this process\n"); \
81 #define UPDATE_FLAGS(hb, flags) \
82 if (((flags)&0xf1) || ((flags)&0x0200)) { \
83 hb->dwFlags = LF32_FIXED; \
84 } else if ((flags)&0x20) { \
85 hb->dwFlags = LF32_MOVEABLE; \
86 } else if ((flags)&0x0100) { \
87 hb->dwFlags = LF32_FREE; \
89 hb->dwFlags |= ((flags) >> SHIFT) << SHIFT;
95 char *dot = strchr(
info->version,
'.');
107 switch (
flags & 0xFFFF) {
115 state =
"(MOVEABLE)";
120 heaptype =
"Segment";
138 HANDLE ntdll = LoadLibrary(TEXT(
"ntdll.dll"));
142 if (!RtlCreateQueryDebugBuffer) {
143 RtlCreateQueryDebugBuffer = (
PDEBUG_BUFFER(NTAPI *)(
DWORD, BOOLEAN))GetProcAddress(ntdll,
"RtlCreateQueryDebugBuffer");
145 if (!RtlQueryProcessDebugInformation) {
148 if (!RtlDestroyQueryDebugBuffer) {
149 RtlDestroyQueryDebugBuffer = (
NTSTATUS(NTAPI *)(
PDEBUG_BUFFER))GetProcAddress(ntdll,
"RtlDestroyQueryDebugBuffer");
151 if (!w32_NtQueryInformationProcess) {
152 w32_NtQueryInformationProcess = (
NTSTATUS(NTAPI *)(
HANDLE, PROCESSINFOCLASS,
PVOID,
ULONG,
PULONG))GetProcAddress(ntdll,
"NtQueryInformationProcess");
159 if (ReadProcessMemory(h_proc, heapBase, &
heap,
sizeof(
HEAP),
NULL)) {
160 if (
heap.SegmentSignature == 0xddeeddee) {
182 SIZE_T index = hb->
index;
199 }
while (block[index].
flags & 2);
213 SIZE_T index = hb->
index;
219 if (block[index].
flags & 2) {
230 }
while (block[index].
flags & 2);
281 if (!strcmp(
map->name,
"ntdll.dll")) {
287 eprintf(
"ntdll.dll not loaded.\n");
304 RzBinOptions opt = { 0 };
318 char *pdb_path =
rz_str_newf(
"%s\\ntdll.pdb\\%s\\ntdll.pdb",
330 eprintf(
"Failed to download ntdll.pdb file\n");
348 eprintf(
"Warning: Cannot find base address, flags will probably be misplaced\n");
376 if (!strcmp(gdata_name->
str_value,
"RtlpHpHeapGlobals")) {
379 }
else if (!strcmp(gdata_name->
str_value,
"RtlpLFHKey")) {
395 WPARAM lfhKeyLocation;
407 if (!ReadProcessMemory(h_proc, (
PVOID)lfhKeyLocation, lfhKey,
sizeof(WPARAM),
NULL)) {
409 eprintf(
"LFH key not found.\n");
421 if (
heap->EncodeFlagMask && (*(UINT32 *)
entry &
heap->EncodeFlagMask)) {
425 *(WPARAM *)
entry ^= *(WPARAM *)&
heap->Encoding;
436 if (
heap->EncodeFlagMask) {
453 params->
ret = RtlQueryProcessDebugInformation(params->
dbg->
pid, params->
mask, params->
db);
456 RtlDestroyQueryDebugBuffer(params->
db);
463 PROCESS_BASIC_INFORMATION pib;
464 if (w32_NtQueryInformationProcess(
ph, ProcessBasicInformation, &pib,
sizeof(pib),
NULL)) {
469 ReadProcessMemory(
ph, pib.PebBaseAddress, &peb,
sizeof(PEB),
NULL);
475 processHeaps = *((
PVOID *)(((
ut8 *)&peb) + 0xF0));
476 numberOfHeaps = *((
ULONG *)(((
ut8 *)&peb) + 0xE8));
478 processHeaps = *((
PVOID *)(((
ut8 *)&peb) + 0x90));
479 numberOfHeaps = *((
ULONG *)(((
ut8 *)&peb) + 0x88));
482 ReadProcessMemory(
ph, processHeaps, &heapAddress,
sizeof(
PVOID),
NULL);
485 }
while (--numberOfHeaps);
506 RtlDestroyQueryDebugBuffer(db);
512 WaitForSingleObject(th, 5000);
514 RtlDestroyQueryDebugBuffer(db);
522 eprintf(
"RtlQueryProcessDebugInformation hanged\n");
524 }
else if (params->
ret) {
525 RtlDestroyQueryDebugBuffer(db);
536 db = RtlCreateQueryDebugBuffer(0,
FALSE);
542 RtlDestroyQueryDebugBuffer(db);
545 HANDLE h_proc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE,
dbg->
pid);
549 RtlDestroyQueryDebugBuffer(db);
558 RtlDestroyQueryDebugBuffer(db);
565 rz_list_foreach (heaps, it, heapBase) {
579 #define GROW_BLOCKS() \
580 if (allocated <= count * sizeof(HeapBlockBasicInfo)) { \
581 SIZE_T old_alloc = allocated; \
583 PVOID tmp = blocks; \
584 blocks = realloc(blocks, allocated); \
589 memset((BYTE *)blocks + old_alloc, 0, old_alloc); \
592 #define GROW_PBLOCKS() \
593 if (*allocated <= *count * sizeof(HeapBlockBasicInfo)) { \
594 SIZE_T old_alloc = *allocated; \
596 PVOID tmp = *blocks; \
597 tmp = realloc(*blocks, *allocated); \
602 memset((BYTE *)(*blocks) + old_alloc, 0, old_alloc); \
606 while ((first != next) && next) {
622 (*blocks)[*
count].address = next +
off;
636 next = (WPARAM)subsegment.
ListEntry.Flink;
645 ReadProcessMemory(h_proc, heapBase, &segheapHeader,
sizeof(
SEGMENT_HEAP), &bytesRead);
647 if (segheapHeader.
Signature != 0xddeeddee) {
652 if (!ReadProcessMemory(h_proc, (
PVOID)lfhKeyLocation, &lfhKey,
sizeof(WPARAM), &bytesRead)) {
654 eprintf(
"LFH key not found.\n");
661 for (j = 0; j < numBuckets; j++) {
700 (*blocks)[*
count].size = ((
entry.AllocatedPages >> 12) << 12);
706 ReadProcessMemory(h_proc, (
void *)(*
blocks)[*
count].address, &extra->
granularity,
sizeof(USHORT), &bytesRead);
708 curr =
entry.TreeNode.Right;
715 WPARAM RtlpHpHeapGlobal;
719 for (
i = 0;
i < 2;
i++) {
723 WPARAM currPageSegment = (WPARAM)
ctx.SegmentListHead.Flink;
728 for (WPARAM j = 2; j < 256; j++) {
733 (*blocks)[*
count].address = currPageSegment + j * 0x1000;
740 extra->
segment = currPageSegment;
748 WPARAM
start,
from = currPageSegment + j * 0x1000;
760 (*blocks)[*
count].size = sz;
774 currPageSegment = (WPARAM)pageSegment.
ListEntry.Flink;
775 }
while (currPageSegment && currPageSegment != ctxFirstEntry);
796 h_proc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE,
pid);
804 RtlDestroyQueryDebugBuffer(db);
806 eprintf(
"GetHeapBlocks: Failed to get LFH key.\n");
812 for (
i = 0;
i < heapInfo->
count;
i++) {
819 ReadProcessMemory(h_proc,
heap->Base, &heapHeader,
sizeof(
HEAP), &bytesRead);
864 if (!ReadProcessMemory(h_proc, heapHeader.
FrontEndHeap, &lfhHeader,
sizeof(
LFH_HEAP), &bytesRead)) {
880 WPARAM curSubsegment = (WPARAM)(curEntry + 2);
883 if (!ReadProcessMemory(h_proc, (
PVOID)curSubsegment, &subsegment,
sizeof(
HEAP_SUBSEGMENT), &bytesRead) || !subsegment.BlockSize || !ReadProcessMemory(h_proc, subsegment.LocalInfo, &
info,
sizeof(
HEAP_LOCAL_SEGMENT_INFO), &bytesRead) || !ReadProcessMemory(h_proc,
info.LocalData, &localData,
sizeof(
HEAP_LOCAL_DATA), &bytesRead) || !ReadProcessMemory(h_proc, localData.
CrtZone, &blockZone,
sizeof(
LFH_BLOCK_ZONE), &bytesRead)) {
887 if (!subsegment.UserBlocks || !subsegment.BlockSize) {
888 goto next_subsegment;
891 size_t sz = subsegment.BlockSize *
sizeof(
HEAP_ENTRY);
892 ReadProcessMemory(h_proc, subsegment.UserBlocks, &userdata,
sizeof(
HEAP_USERDATA_HEADER), &bytesRead);
895 WPARAM *bitmap =
calloc(bitmapsz >
sizeof(WPARAM) ? bitmapsz :
sizeof(WPARAM), 1);
899 ReadProcessMemory(h_proc, userdata.
BusyBitmap.
Buffer, bitmap, bitmapsz, &bytesRead);
913 from = (WPARAM)subsegment.UserBlocks +
off;
914 ReadProcessMemory(h_proc, (
PVOID)
from, &heapEntry, sz_entry, &bytesRead);
924 extra->
segment = curSubsegment;
937 ReadProcessMemory(h_proc, curEntry, &
entry,
sizeof(
entry), &bytesRead);
938 curEntry =
entry.Flink;
939 }
while (curEntry != firstEntry);
943 WPARAM firstSegment = (WPARAM)heapHeader.
SegmentList.Flink;
952 if (!ReadProcessMemory(h_proc, (
PVOID)
from, &heapEntry, sz_entry, &bytesRead)) {
956 if (!heapEntry.Size) {
962 SIZE_T real_sz = heapEntry.Size * sz_entry;
979 oldSegment = segment;
986 if (!
heap->Committed && !
heap->Allocated) {
999 for (
i = 0;
i < heapInfo->
count;
i++) {
1004 RtlDestroyQueryDebugBuffer(db);
1014 RZ_LOG_ERROR(
"GetSingleSegmentBlock: Allocation failed.\n");
1019 RZ_LOG_ERROR(
"GetSingleSegmentBlock: Allocation failed.\n");
1023 extra->
heap = (WPARAM)heapBase;
1024 WPARAM granularity = (WPARAM)
dbg->
bits * 2;
1025 WPARAM headerOff =
offset - granularity;
1028 WPARAM RtlpHpHeapGlobal;
1031 WPARAM pgSegOff = headerOff &
heap.SegContexts[0].SegmentMask;
1032 WPARAM segSignature;
1033 ReadProcessMemory(h_proc, (
PVOID)(pgSegOff +
sizeof(LIST_ENTRY)), &segSignature,
sizeof(WPARAM),
NULL);
1034 WPARAM
test = RtlpHpHeapGlobal ^ pgSegOff ^ segSignature ^ ((WPARAM)heapBase +
offsetof(
SEGMENT_HEAP, SegContexts));
1035 if (
test == 0xa2e64eada2e64ead) {
1038 WPARAM pgRangeDescOff = ((headerOff - pgSegOff) >>
heap.SegContexts[0].UnitShift) << 5;
1044 WPARAM subsegmentOffset = pgSegOff + pageIndex * 0x1000;
1051 header.Sizes.HeaderBits ^= RtlpHpHeapGlobal ^ headerOff;
1056 extra->
segment = subsegmentOffset;
1071 extra->
segment = subsegmentOffset;
1077 if ((
offset & 0xFFFF) < 0x100) {
1078 if (!
heap.LargeAllocMetadata.Root) {
1082 WPARAM curr = (WPARAM)
heap.LargeAllocMetadata.Root;
1088 WPARAM VirtualAddess =
entry.VirtualAddess -
entry.UnusedBytes;
1089 if ((
offset & ~0xFFFFULL) > VirtualAddess) {
1090 curr = (WPARAM)node.
Right;
1091 }
else if ((
offset & ~0xFFFFULL) < VirtualAddess) {
1092 curr = (WPARAM)node.
Left;
1121 HANDLE h_proc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE,
dbg->
pid);
1139 for (
i = 0;
i < heapInfo->
count;
i++) {
1152 WPARAM entryOffset =
offset -
heap.Granularity;
1153 if (!ReadProcessMemory(h_proc,
heap.Base, &
h,
sizeof(
HEAP),
NULL) ||
1164 if (
entry.UnusedBytes == 0x4) {
1179 if (
entry.UnusedBytes & 0x80) {
1181 WPARAM userBlocksOffset;
1183 *(((WPARAM *)&tmpEntry) + 1) ^= PtrToInt(
h.BaseAddress) ^ (entryOffset >> 0x4) ^ (
DWORD)NtLFHKey;
1184 userBlocksOffset = entryOffset - (USHORT)((*(((WPARAM *)&tmpEntry) + 1)) >> 0xC);
1186 *((WPARAM *)&tmpEntry) ^= PtrToInt(
h.BaseAddress) ^ ((
DWORD)(entryOffset) >> 0x4) ^ (
DWORD)NtLFHKey;
1187 userBlocksOffset = entryOffset - (USHORT)(*((WPARAM *)&tmpEntry) >> 0xC);
1211 RtlDestroyQueryDebugBuffer(db);
1212 CloseHandle(h_proc);
1216 CloseHandle(h_proc);
1219 RtlDestroyQueryDebugBuffer(db);
1246 eprintf(
"Couldn't get heap info.\n");
1260 for (
i = 0;
i < heapInfo->
count;
i++) {
1285 RtlDestroyQueryDebugBuffer(db);
1297 eprintf(
"Couldn't get heap info.\n");
1307 for (
i = 0;
i < heapInfo->
count;
i++) {
1333 eprintf(
"Flag couldn't be set for block at 0x%" PFMT64x, address);
1338 pj_kN(pj,
"header_address", address);
1340 pj_kN(pj,
"unused", unusedBytes);
1367 RtlDestroyQueryDebugBuffer(db);
1390 ut64 headerAddr =
off - granularity;
1396 pj_kN(pj,
"header_address", headerAddr);
1423 eprintf(
"Couldn't get heap info.\n");
1430 for (
int i = 0;
i < heapInfo->
count;
i++) {
1447 RtlDestroyQueryDebugBuffer(db);
1450 heap_block->headerAddress = address;
1452 heap_block->size = block->
dwSize;
1453 strcpy(heap_block->type,
type);
1454 heap_block->unusedBytes = unusedBytes;
1455 heap_block->granularity = granularity;
1466 RtlDestroyQueryDebugBuffer(db);
1479 eprintf(
"Couldn't get heap info.\n");
1487 for (
int i = 0;
i < heapInfo->
count;
i++) {
1493 RtlDestroyQueryDebugBuffer(db);
1509 RtlDestroyQueryDebugBuffer(db);
RZ_API bool rz_bin_file_set_cur_binfile(RzBin *bin, RzBinFile *bf)
RZ_API bool rz_bin_file_delete(RzBin *bin, RzBinFile *bf)
RZ_DEPRECATE RZ_API RZ_BORROW RzBinInfo * rz_bin_get_info(RzBin *bin)
RZ_API RzBinFile * rz_bin_open_io(RzBin *bin, RzBinOptions *opt)
RZ_API RzBinFile * rz_bin_cur(RzBin *bin)
static ut64 baddr(RzBinFile *bf)
RzBinInfo * info(RzBinFile *bf)
RZ_API ut64 rz_config_get_i(RzConfig *cfg, RZ_NONNULL const char *name)
RZ_API RZ_BORROW const char * rz_config_get(RzConfig *cfg, RZ_NONNULL const char *name)
RZ_API void rz_cons_println(const char *str)
RZ_API char * rz_core_bin_pdb_gvars_as_string(RZ_NONNULL const RzPdb *pdb, const ut64 img_base, PJ *pj, const RzOutputMode mode)
Return the PDB global vars string.
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void start
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len key
size_t map(int syms, int left, int len)
RZ_API RzFlagItem * rz_flag_set(RzFlag *f, const char *name, ut64 off, ut32 size)
RZ_API void Ht_() free(HtName_(Ht) *ht)
RZ_API const KEY_TYPE bool * found
#define offsetof(type, member)
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
RZ_API RZ_BORROW RzListIter * rz_list_push(RZ_NONNULL RzList *list, void *item)
Alias for rz_list_append.
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
void * realloc(void *ptr, size_t size)
void * malloc(size_t size)
void * calloc(size_t number, size_t size)
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc pid
#define header(is_bt, len_min, ret_op)
RZ_API RZ_OWN RzPdb * rz_bin_pdb_parse_from_file(RZ_NONNULL const char *filename)
Parse PDB file given the path.
RZ_API void rz_bin_pdb_free(RzPdb *pdb)
Free PDB instance.
RZ_API int rz_bin_pdb_download(RZ_NONNULL RzBin *bin, RZ_NULLABLE PJ *pj, int isradjson, RZ_NONNULL SPDBOptions *options)
Download PDB file for currently opened RzBin file.
#define rz_return_if_fail(expr)
#define rz_return_val_if_fail(expr, val)
RZ_API bool rz_file_exists(const char *str)
RZ_API ut64 rz_io_fd_size(RzIO *io, int fd)
RZ_API int rz_io_fd_open(RzIO *io, const char *uri, int flags, int mode)
RZ_API bool rz_io_fd_close(RzIO *io, int fd)
RZ_API const RzJson * rz_json_get(const RzJson *json, const char *key)
RZ_API RzJson * rz_json_parse(char *text)
#define RZ_LOG_ERROR(fmtstr,...)
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
RZ_API PJ * pj_k(PJ *j, const char *k)
RZ_API PJ * pj_end(PJ *j)
RZ_API const char * pj_string(PJ *pj)
RZ_API void pj_free(PJ *j)
RZ_API PJ * pj_ks(PJ *j, const char *k, const char *v)
RZ_API PJ * pj_kN(PJ *j, const char *k, st64 n)
RZ_API bool rz_stack_is_empty(RzStack *s)
RZ_API void * rz_stack_pop(RzStack *s)
RZ_API bool rz_stack_push(RzStack *s, void *el)
RZ_API RzStack * rz_stack_new(ut32 n)
RZ_API void rz_stack_free(RzStack *s)
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API void rz_sys_info_free(RSysInfo *si)
RZ_API RSysInfo * rz_sys_info(void)
RZ_API void rz_table_add_column(RzTable *t, RzTableColumnType *type, const char *name, int maxWidth)
RZ_API void rz_table_add_rowf(RzTable *t, const char *fmt,...)
RZ_API void rz_table_free(RzTable *t)
RZ_API char * rz_table_tostring(RzTable *t)
RZ_API RzTable * rz_table_new(void)
RZ_API RzTableColumnType * rz_table_type(const char *name)
RzOutputMode
Enum to describe the way data are printed.
@ RZ_OUTPUT_MODE_STANDARD
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr from
static struct sockaddr static addrlen static backlog const void static flags void flags
const char * symbol_server
const char * symbol_store_path
WPARAM TotalMemoryCommitted
HEAP_LFH_SUBSEGMENT_OWNER State
PHEAP_LFH_AFFINITY_SLOT * AffinitySlots
PHEAP_LFH_BUCKET Buckets[129]
LIST_ENTRY FullSubsegmentList
LIST_ENTRY AvailableSubsegmentList
HEAP_LFH_SUBSEGMENT_ENCODED_OFFSETS BlockOffsets
HEAP_PAGE_RANGE_DESCRIPTOR DescArray[256]
LIST_ENTRY SegmentListEntry
PHEAP_ENTRY LastValidEntry
UINT16 FirstAllocationOffset
LIST_ENTRY VirtualAllocdBlocks
PHeapBlockExtraInfo extraInfo
LIST_ENTRY SubSegmentZones
WPARAM LargeReservedPages
HEAP_SEG_CONTEXT SegContexts[2]
HEAP_LFH_CONTEXT LfhContext
RTL_RB_TREE LargeAllocMetadata
ut64 baseaddr
where the linker maps the binary in memory
XX curplugin == o->plugin.
RzBinObjectLoadOptions opts
RZ_DEPRECATE RzBinFile * cur
never use this in new code! Get a file from the binfiles list or track it yourself.
struct rz_json_t::@304::@307 children
struct rz_json_t::@304::@306 num
if(dbg->bits==RZ_SYS_BITS_64)
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static size_t RtlpHpHeapGlobalsOffset
static char * get_type(WPARAM flags)
static bool GetNextHeapBlock(PDEBUG_HEAP_INFORMATION heapInfo, PHeapBlock hb)
RZ_IPI void rz_heap_list_w32(RzCore *core, RzOutputMode mode)
#define CHECK_INFO(heapInfo)
static bool has_heap_globals(void)
static bool __lfh_segment_loop(HANDLE h_proc, PHeapBlockBasicInfo *blocks, SIZE_T *allocated, WPARAM lfhKey, WPARAM *count, WPARAM first, WPARAM next)
static bool is_segment_heap(HANDLE h_proc, PVOID heapBase)
static DWORD WINAPI __th_QueryDebugBuffer(void *param)
static bool DecodeHeapEntry(RzDebug *dbg, PHEAP heap, PHEAP_ENTRY entry)
static void w32_list_heaps_blocks(RzCore *core, RzOutputMode mode, bool flag)
RZ_IPI void rz_heap_debug_block_win(RzCore *core, const char *addr, RzOutputMode mode, bool flag)
static RzList * GetListOfHeaps(RzDebug *dbg, HANDLE ph)
static RzTable * __new_heapblock_tbl(void)
RZ_IPI RzList * rz_heap_list(RzCore *core)
static bool GetFirstHeapBlock(PDEBUG_HEAP_INFORMATION heapInfo, PHeapBlock hb)
static bool GetHeapGlobalsOffset(RzDebug *dbg, HANDLE h_proc)
struct _th_query_params th_query_params
static bool __is_windows_ten(void)
static PDEBUG_BUFFER GetHeapBlocks(DWORD pid, RzDebug *dbg)
static bool GetLFHKey(RzDebug *dbg, HANDLE h_proc, bool segment, WPARAM *lfhKey)
#define CHECK_INFO_RETURN_NULL(heapInfo)
static bool initialize_windows_ntdll_query_api_functions(void)
static bool DecodeLFHEntry(RzDebug *dbg, PHEAP heap, PHEAP_ENTRY entry, PHEAP_USERDATA_HEADER userBlocks, WPARAM key, WPARAM addr)
static size_t RtlpLFHKeyOffset
static PHeapBlock GetSingleBlock(RzDebug *dbg, ut64 offset)
RZ_IPI RzList * rz_heap_blocks_list(RzCore *core)
#define UPDATE_FLAGS(hb, flags)
static PDEBUG_BUFFER InitHeapInfo(RzDebug *dbg, DWORD mask)
static PHeapBlock GetSingleSegmentBlock(RzDebug *dbg, HANDLE h_proc, PSEGMENT_HEAP heapBase, WPARAM offset)
static void free_extra_info(PDEBUG_HEAP_INFORMATION heap)
static bool GetSegmentHeapBlocks(RzDebug *dbg, HANDLE h_proc, PVOID heapBase, PHeapBlockBasicInfo *blocks, WPARAM *count, SIZE_T *allocated)
struct _HEAP_ENTRY * PHEAP_ENTRY
struct _DEBUG_BUFFER * PDEBUG_BUFFER
struct _HeapBlockExtraInfo * PHeapBlockExtraInfo
struct _HEAP_SEG_CONTEXT HEAP_SEG_CONTEXT
struct _RTL_BALANCED_NODE RTL_BALANCED_NODE
struct _HEAP_VIRTUAL_ALLOC_ENTRY HEAP_VIRTUAL_ALLOC_ENTRY
@ PAGE_RANGE_FLAGS_LFH_SUBSEGMENT
@ PAGE_RANGE_FLAGS_ALLOCATED
struct _HeapBlockBasicInfo * PHeapBlockBasicInfo
#define SEGMENT_HEAP_BLOCK
struct _HEAP_VS_CHUNK_HEADER HEAP_VS_CHUNK_HEADER
struct _RTL_BALANCED_NODE * PRTL_BALANCED_NODE
struct _HeapBlockBasicInfo HeapBlockBasicInfo
struct _HEAP_SUBSEGMENT HEAP_SUBSEGMENT
struct _HEAP_ENTRY HEAP_ENTRY
struct _HEAP_VS_SUBSEGMENT HEAP_VS_SUBSEGMENT
struct _HEAP_PAGE_SEGMENT HEAP_PAGE_SEGMENT
struct _HEAP_PAGE_RANGE_DESCRIPTOR HEAP_PAGE_RANGE_DESCRIPTOR
RZ_API RzList * rz_w32_dbg_modules(RzDebug *dbg)
static const z80_opcode fd[]