Rizin
unix-like reverse engineering framework and cli tools
rz_heap_glibc.h
Go to the documentation of this file.
1 #ifndef RZ_HEAP_GLIBC_H
2 #define RZ_HEAP_GLIBC_H
3 
4 #include <rz_core.h>
5 
6 #ifdef __cplusplus
7 extern "C" {
8 #endif
9 
10 RZ_LIB_VERSION_HEADER(rz_heap_glibc);
11 
12 #define PRINTF_A(color, fmt, ...) rz_cons_printf(color fmt Color_RESET, __VA_ARGS__)
13 #define PRINTF_YA(fmt, ...) PRINTF_A("%s", fmt, pal->offset, __VA_ARGS__)
14 #define PRINTF_GA(fmt, ...) PRINTF_A("%s", fmt, pal->args, __VA_ARGS__)
15 #define PRINTF_BA(fmt, ...) PRINTF_A("%s", fmt, pal->num, __VA_ARGS__)
16 #define PRINTF_RA(fmt, ...) PRINTF_A("%s", fmt, pal->invalid, __VA_ARGS__)
17 
18 #define PRINT_A(color, msg) rz_cons_print(color msg Color_RESET)
19 #define PRINT_YA(msg) rz_cons_printf("%s" msg Color_RESET, pal->offset)
20 #define PRINT_GA(msg) rz_cons_printf("%s" msg Color_RESET, pal->args)
21 #define PRINT_BA(msg) rz_cons_printf("%s" msg Color_RESET, pal->num)
22 #define PRINT_RA(msg) rz_cons_printf("%s" msg Color_RESET, pal->invalid)
23 
24 #define PREV_INUSE 0x1
25 #define IS_MMAPPED 0x2
26 #define NON_MAIN_ARENA 0x4
27 
28 #define NBINS 128
29 #define NSMALLBINS 64
30 #define NFASTBINS 10
31 #define BINMAPSHIFT 5
32 #define SZ core->dbg->bits
33 #define FASTBIN_IDX_TO_SIZE(i) ((SZ * 4) + (SZ * 2) * (i - 1))
34 #define BITSPERMAP (1U << BINMAPSHIFT)
35 #define BINMAPSIZE (NBINS / BITSPERMAP)
36 #define NPAD -6
37 #define TCACHE_MAX_BINS 64
38 #define TCACHE_FILL_COUNT 7
39 #define TCACHE_NEW_VERSION 230
40 
41 #define MMAP_ALIGN_32 0x14
42 #define MMAP_ALIGN_64 0x18
43 #define MMAP_OFFSET 0x8
44 
45 #define HDR_SZ_32 0x8
46 #define HDR_SZ_64 0x10
47 #define TC_HDR_SZ 0x10
48 #define TC_SZ_32 0x0
49 #define TC_SZ_64 0x10
50 
51 // Introduced with glibc 2.32
52 
53 #define largebin_index_32(size) \
54  (((((ut32)(size)) >> 6) <= 38) ? 56 + (((ut32)(size)) >> 6) : ((((ut32)(size)) >> 9) <= 20) ? 91 + (((ut32)(size)) >> 9) \
55  : ((((ut32)(size)) >> 12) <= 10) ? 110 + (((ut32)(size)) >> 12) \
56  : ((((ut32)(size)) >> 15) <= 4) ? 119 + (((ut32)(size)) >> 15) \
57  : ((((ut32)(size)) >> 18) <= 2) ? 124 + (((ut32)(size)) >> 18) \
58  : 126)
59 #define largebin_index_32_big(size) \
60  (((((ut32)(size)) >> 6) <= 45) ? 49 + (((ut32)(size)) >> 6) : ((((ut32)(size)) >> 9) <= 20) ? 91 + (((ut32)(size)) >> 9) \
61  : ((((ut32)(size)) >> 12) <= 10) ? 110 + (((ut32)(size)) >> 12) \
62  : ((((ut32)(size)) >> 15) <= 4) ? 119 + (((ut32)(size)) >> 15) \
63  : ((((ut32)(size)) >> 18) <= 2) ? 124 + (((ut32)(size)) >> 18) \
64  : 126)
65 #define largebin_index_64(size) \
66  (((((ut32)(size)) >> 6) <= 48) ? 48 + (((ut32)(size)) >> 6) : ((((ut32)(size)) >> 9) <= 20) ? 91 + (((ut32)(size)) >> 9) \
67  : ((((ut32)(size)) >> 12) <= 10) ? 110 + (((ut32)(size)) >> 12) \
68  : ((((ut32)(size)) >> 15) <= 4) ? 119 + (((ut32)(size)) >> 15) \
69  : ((((ut32)(size)) >> 18) <= 2) ? 124 + (((ut32)(size)) >> 18) \
70  : 126)
71 
72 #define largebin_index(size) \
73  (SZ == 8 ? largebin_index_64(size) : largebin_index_32(size))
74 
75 #define fastbin_index(size) \
76  (SZ == 8 ? (size >> 4) - 2 : (size >> 3) - 2)
77 /* Not works 32 bit on 64 emulation
78 #define largebin_index(size) \
79  (SZ == 8 ? largebin_index_64 (size) \
80  : MALLOC_ALIGNMENT == 16 ? largebin_index_32_big (size) \
81  : largebin_index_32 (size))
82 */
83 
84 typedef struct rz_malloc_chunk_64 {
85  ut64 prev_size; /* Size of previous chunk (if free). */
86  ut64 size; /* Size in bytes, including overhead. */
87 
88  ut64 fd; /* double links -- used only if free. */
90 
91  /* Only used for large blocks: pointer to next larger size. */
92  ut64 fd_nextsize; /* double links -- used only if free. */
95 
96 typedef struct rz_malloc_chunk_32 {
97  ut32 prev_size; /* Size of previous chunk (if free). */
98  ut32 size; /* Size in bytes, including overhead. */
99 
100  ut32 fd; /* double links -- used only if free. */
102 
103  /* Only used for large blocks: pointer to next larger size. */
104  ut32 fd_nextsize; /* double links -- used only if free. */
107 
108 /*
109 typedef RzHeapChunk64 *mfastbinptr64;
110 typedef RzHeapChunk64 *mchunkptr64;
111 
112 typedef RzHeapChunk32 *mfastbinptr32;
113 typedef RzHeapChunk32 *mchunkptr32;
114 */
115 
116 typedef struct rz_malloc_state_32 {
117  int mutex; /* serialized access */
118  int flags; /* flags */
119  ut32 fastbinsY[NFASTBINS]; /* array of fastchunks */
120  ut32 top; /* top chunk's base addr */
121  ut32 last_remainder; /* remainder top chunk's addr */
122  ut32 bins[NBINS * 2 - 2]; /* array of remainder free chunks */
123  unsigned int binmap[BINMAPSIZE]; /* bitmap of bins */
124  ut32 next; /* double linked list of chunks */
125  ut32 next_free; /* double linked list of free chunks */
126  unsigned int attached_threads; /* threads attached */
127  ut32 system_mem; /* current allocated memory of current arena */
128  ut32 max_system_mem; /* maximum system memory */
130 
131 typedef struct rz_malloc_state_64 {
132  int mutex; /* serialized access */
133  int flags; /* flags */
134  ut64 fastbinsY[NFASTBINS]; /* array of fastchunks */
135  ut64 top; /* top chunk's base addr */
136  ut64 last_remainder; /* remainder top chunk's addr */
137  ut64 bins[NBINS * 2 - 2]; /* array of remainder free chunks */
138  unsigned int binmap[BINMAPSIZE]; /* bitmap of bins */
139  ut64 next; /* double linked list of chunks */
140  ut64 next_free; /* double linked list of free chunks */
141  unsigned int attached_threads; /* threads attached */
142  ut64 system_mem; /* current allocated memory of current arena */
143  ut64 max_system_mem; /* maximum system memory */
145 
150 
155 
160 
165 
166 typedef enum { NEW,
168 
169 typedef struct {
171  union {
174  } RzHeapTcache;
175 } RTcache_64;
176 
177 typedef struct {
179  union {
182  } RzHeapTcache;
183 } RTcache_32;
184 
186  int mutex; /* serialized access */
187  int flags; /* flags */
188  int have_fast_chunks; /* have fast chunks */
189  ut32 fastbinsY[NFASTBINS + 1]; /* array of fastchunks */
190  ut32 top; /* top chunk's base addr */
191  ut32 last_remainder; /* remainder top chunk's addr */
192  ut32 bins[NBINS * 2 - 2]; /* array of remainder free chunks */
193  unsigned int binmap[BINMAPSIZE]; /* bitmap of bins */
194  ut32 next; /* double linked list of chunks */
195  ut32 next_free; /* double linked list of free chunks */
196  unsigned int attached_threads; /* threads attached */
197  ut32 system_mem; /* current allocated memory of current arena */
198  ut32 max_system_mem; /* maximum system memory */
200 
202  int mutex; /* serialized access */
203  int flags; /* flags */
204  int have_fast_chunks; /* have fast chunks */
205  ut64 fastbinsY[NFASTBINS]; /* array of fastchunks */
206  ut64 top; /* top chunk's base addr */
207  ut64 last_remainder; /* remainder top chunk's addr */
208  ut64 bins[NBINS * 2 - 2]; /* array of remainder free chunks */
209  unsigned int binmap[BINMAPSIZE]; /* bitmap of bins */
210  ut64 next; /* double linked list of chunks */
211  ut64 next_free; /* double linked list of free chunks */
212  unsigned int attached_threads; /* threads attached */
213  ut64 system_mem; /* current allocated memory of current arena */
214  ut64 max_system_mem; /* maximum system memory */
216 
217 typedef struct rz_malloc_state {
218  int mutex; /* serialized access */
219  int flags; /* flags */
220  unsigned int binmap[BINMAPSIZE]; /* bitmap of bins */
221 
222  /*tcache*/
223  int have_fast_chunks; /* have fast chunks */
224  unsigned int attached_threads; /* threads attached */
225 
226  /*64 bits members */
227  ut64 fastbinsY[NFASTBINS]; /* array of fastchunks */
228  ut64 top; /* top chunk's base addr */
229  ut64 last_remainder; /* remainder top chunk's addr */
230  ut64 bins[NBINS * 2 - 2]; /* array of remainder free chunks */
231  ut64 next; /* double linked list of chunks */
232  ut64 next_free; /* double linked list of free chunks */
233  ut64 system_mem; /* current allocated memory of current arena */
234  ut64 max_system_mem; /* maximum system memory */
236 
237 typedef struct rz_heap_info_32 {
238  ut32 ar_ptr; /* Arena for this heap. */
239  ut32 prev; /* Previous heap. */
240  ut32 size; /* Current size in bytes. */
241  ut32 mprotect_size; /* Size in bytes that has been mprotected PROT_READ|PROT_WRITE. */
242 
243  /* Make sure the following data is properly aligned, particularly
244  that sizeof (heap_info) + 2 * SZ is a multiple of
245  MALLOC_ALIGNMENT. */
246  /* char pad[NPAD * SZ & MALLOC_ALIGN_MASK]; */
248 
249 typedef struct rz_heap_info_64 {
250  ut64 ar_ptr; /* Arena for this heap. */
251  ut64 prev; /* Previous heap. */
252  ut64 size; /* Current size in bytes. */
253  ut64 mprotect_size; /* Size in bytes that has been mprotected PROT_READ|PROT_WRITE. */
254 
255  /* Make sure the following data is properly aligned, particularly
256  that sizeof (heap_info) + 2 * SZ is a multiple of
257  MALLOC_ALIGNMENT. */
258  /* char pad[NPAD * SZ & MALLOC_ALIGN_MASK]; */
260 
261 typedef enum rz_heap_bin_type {
269 
270 typedef struct rz_heap_chunk_list_item {
271  ut64 addr; /* Base addr of the chunk */
272  ut64 size; /* Size of the chunk */
273  char *status; /* Status of the chunk, allocated/free/corrupted */
275 
276 typedef struct rz_arena_list_item {
277  ut64 addr; /* Base addr of the arena */
278  char *type; /* Type of arena, main/thread */
279  MallocState *arena; /* The MallocState for the arena */
281 
282 typedef struct rz_heap_chunk_simple {
283  ut64 addr; /* Base addr of the chunk*/
284  ut64 prev_size; /* size of prev_chunk*/
285  ut64 size; /* size of chunk */
286  bool non_main_arena; /* flag for NON_MAIN_ARENA */
287  bool prev_inuse; /* flag for PREV_INUSE*/
288  bool is_mmapped; /* flag for IS_MMAPPED*/
289  ut64 fd; /* fd pointer, only if free */
290  ut64 bk; /* bk pointer, only if free */
291  ut64 fd_nextsize; /* fd nextsize pointer, only if free */
292  ut64 bk_nextsize; /* bk nextsize pointer, only if free */
294 
295 typedef struct rz_heap_bin {
300  int bin_num;
301  char *type;
302  RzList *chunks; /* list of chunks in the bins */
303  char *message; /* indicating the list is corrupted or double free*/
305 
308 
311 
314 
315 RZ_API RzList *rz_heap_chunks_list_64(RzCore *core, MallocState *main_arena, ut64 m_arena, ut64 m_state, bool top_chunk);
316 RZ_API RzList *rz_heap_chunks_list_32(RzCore *core, MallocState *main_arena, ut32 m_arena, ut32 m_state, bool top_chunk);
317 
320 
321 RZ_API bool rz_heap_update_main_arena_64(RzCore *core, ut64 m_arena, MallocState *main_arena);
322 RZ_API bool rz_heap_update_main_arena_32(RzCore *core, ut32 m_arena, MallocState *main_arena);
323 
326 
329 
332 
335 
336 RZ_API RzHeapBin *rz_heap_bin_content_64(RzCore *core, MallocState *main_arena, int bin_num, ut64 m_arena);
337 RZ_API RzHeapBin *rz_heap_bin_content_32(RzCore *core, MallocState *main_arena, int bin_num, ut32 m_arena);
338 
341 
344 
345 RZ_IPI int rz_cmd_heap_fastbins_print_64(void *data, const char *input);
346 RZ_IPI int rz_cmd_heap_fastbins_print_32(void *data, const char *input);
347 
350 
353 
354 #ifdef __cplusplus
355 }
356 #endif
357 #endif
#define RZ_IPI
Definition: analysis_wasm.c:11
#define RZ_API
uint16_t ut16
uint32_t ut32
uint8_t ut8
Definition: lh5801.h:11
struct rz_tcache_perthread_struct_32 RzHeapTcache_32
struct rz_malloc_state_tcache_64 RzHeap_MallocState_tcache_64
RZ_API bool rz_heap_write_heap_chunk_64(RzCore *core, RzHeapChunkSimple *chunk_simple)
RZ_API RzHeapChunkSimple * rz_heap_chunk_wrapper_32(RzCore *core, ut32 addr)
RZ_API bool rz_heap_write_heap_chunk_32(RzCore *core, RzHeapChunkSimple *chunk_simple)
RZ_API RzHeapBin * rz_heap_fastbin_content_32(RzCore *core, MallocState *main_arena, int bin_num)
RZ_API RzList * rz_heap_arenas_list_32(RzCore *core, ut32 m_arena, MallocState *main_arena)
RZ_IPI int rz_cmd_heap_fastbins_print_32(void *data, const char *input)
#define TCACHE_MAX_BINS
Definition: rz_heap_glibc.h:37
struct rz_malloc_state_tcache_32 RzHeap_MallocState_tcache_32
struct rz_tcache_perthread_struct_pre_230_64 RzHeapTcachePre230_64
RZ_API RzList * rz_heap_arena_list_wrapper_32(RzCore *core)
struct rz_heap_info_32 RzHeapInfo_32
RZ_API RzList * rz_heap_chunks_list_wrapper_32(RzCore *core, ut64 m_state)
struct rz_heap_chunk_list_item RzHeapChunkListItem
RZ_API void rz_heap_bin_free_32(RzHeapBin *bin)
struct rz_heap_chunk_simple RzHeapChunkSimple
struct rz_heap_bin RzHeapBin
RZ_API RzList * rz_heap_tcache_content_32(RzCore *core, ut32 arena_base)
RZ_API bool rz_heap_update_main_arena_32(RzCore *core, ut32 m_arena, MallocState *main_arena)
RZ_API RzHeapChunk_64 * rz_heap_get_chunk_at_addr_64(RzCore *core, ut64 addr)
RZ_API RzList * rz_heap_chunks_list_64(RzCore *core, MallocState *main_arena, ut64 m_arena, ut64 m_state, bool top_chunk)
RZ_API bool rz_heap_resolve_main_arena_32(RzCore *core, ut32 *m_arena)
RZ_API bool rz_heap_update_main_arena_64(RzCore *core, ut64 m_arena, MallocState *main_arena)
rz_heap_bin_type
@ RZ_HEAP_BIN_TCACHE
@ RZ_HEAP_BIN_LARGE
@ RZ_HEAP_BIN_FAST
@ RZ_HEAP_BIN_SMALL
@ RZ_HEAP_BIN_ANY
@ RZ_HEAP_BIN_UNSORTED
RZ_API RzList * rz_heap_tcache_content_64(RzCore *core, ut64 arena_base)
struct rz_malloc_state MallocState
RZ_API RzList * rz_heap_arena_list_wrapper_64(RzCore *core)
struct rz_malloc_chunk_64 RzHeapChunk_64
RZ_API MallocState * rz_heap_get_arena_64(RzCore *core, ut64 m_state)
tcache_type
@ OLD
@ NEW
#define BINMAPSIZE
Definition: rz_heap_glibc.h:35
struct rz_arena_list_item RzArenaListItem
RZ_IPI int rz_cmd_heap_fastbins_print_64(void *data, const char *input)
RZ_API RzList * rz_heap_chunks_list_32(RzCore *core, MallocState *main_arena, ut32 m_arena, ut32 m_state, bool top_chunk)
RZ_API RzList * rz_heap_arenas_list_64(RzCore *core, ut64 m_arena, MallocState *main_arena)
RZ_API RzHeapChunkSimple * rz_heap_chunk_wrapper_64(RzCore *core, ut64 addr)
RZ_API RzList * rz_heap_chunks_list_wrapper_64(RzCore *core, ut64 m_state)
struct rz_malloc_state_32 RzHeap_MallocState_32
RZ_IPI int rz_cmd_heap_bins_list_print_32(RzCore *core, const char *input)
RZ_IPI int rz_cmd_heap_bins_list_print_64(RzCore *core, const char *input)
#define NBINS
Definition: rz_heap_glibc.h:28
struct rz_malloc_chunk_32 RzHeapChunk_32
RZ_API MallocState * rz_heap_get_arena_32(RzCore *core, ut32 m_state)
struct rz_malloc_state_64 RzHeap_MallocState_64
struct rz_tcache_perthread_struct_pre_230_32 RzHeapTcachePre230_32
RZ_API RzHeapBin * rz_heap_fastbin_content_64(RzCore *core, MallocState *main_arena, int bin_num)
#define NFASTBINS
Definition: rz_heap_glibc.h:30
struct rz_heap_info_64 RzHeapInfo_64
RZ_API bool rz_heap_resolve_main_arena_64(RzCore *core, ut64 *m_arena)
RZ_API RzHeapBin * rz_heap_bin_content_32(RzCore *core, MallocState *main_arena, int bin_num, ut32 m_arena)
enum rz_heap_bin_type RzHeapBinType
RZ_LIB_VERSION_HEADER(rz_heap_glibc)
RZ_API void rz_heap_bin_free_64(RzHeapBin *bin)
struct rz_tcache_perthread_struct_64 RzHeapTcache_64
RZ_API RzHeapBin * rz_heap_bin_content_64(RzCore *core, MallocState *main_arena, int bin_num, ut64 m_arena)
RZ_API RzHeapChunk_32 * rz_heap_get_chunk_at_addr_32(RzCore *core, ut32 addr)
RzHeapTcache_32 * heap_tcache
tcache_type type
RzHeapTcachePre230_32 * heap_tcache_pre_230
RzHeapTcachePre230_64 * heap_tcache_pre_230
RzHeapTcache_64 * heap_tcache
tcache_type type
Definition: malloc.c:26
MallocState * arena
char * message
RzList * chunks
unsigned int binmap[BINMAPSIZE]
ut32 fastbinsY[NFASTBINS]
ut32 bins[NBINS *2 - 2]
unsigned int attached_threads
ut64 bins[NBINS *2 - 2]
ut64 fastbinsY[NFASTBINS]
unsigned int binmap[BINMAPSIZE]
unsigned int attached_threads
ut32 fastbinsY[NFASTBINS+1]
ut32 bins[NBINS *2 - 2]
unsigned int binmap[BINMAPSIZE]
ut64 fastbinsY[NFASTBINS]
ut64 bins[NBINS *2 - 2]
unsigned int binmap[BINMAPSIZE]
ut64 fastbinsY[NFASTBINS]
ut64 bins[NBINS *2 - 2]
unsigned int attached_threads
unsigned int binmap[BINMAPSIZE]
ut16 counts[TCACHE_MAX_BINS]
ut32 entries[TCACHE_MAX_BINS]
ut64 entries[TCACHE_MAX_BINS]
ut16 counts[TCACHE_MAX_BINS]
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58
static bool input(void *ud, zip_uint8_t *data, zip_uint64_t length)