Rizin
unix-like reverse engineering framework and cli tools
elf_notes.c File Reference
#include "elf.h"

Go to the source code of this file.

Macros

#define ROUND_UP_4(x)   ((x) + (4 - 1)) / 4 * 4
 
#define X86   0
 
#define X86_64   1
 
#define ARM   2
 
#define AARCH64   3
 
#define ARCH_LEN   4
 

Functions

static bool parse_note_prstatus (ELFOBJ *bin, RzVector *notes, Elf_(Nhdr) *note_segment_header, ut64 offset)
 
static bool get_note_file_aux (ELFOBJ *bin, RzBinElfNoteFile *file, ut64 *offset)
 
static bool get_note_file (ELFOBJ *bin, RzBinElfNoteFile *file, ut64 *offset)
 
static bool set_note_file (ELFOBJ *bin, RzBinElfNoteFile *file, ut64 *offset, char *name)
 
static bool parse_note_file (ELFOBJ *bin, RzVector *notes, Elf_(Nhdr) *note_segment_header, ut64 offset)
 
static bool set_note (ELFOBJ *bin, RzVector *notes, Elf_(Nhdr) *note_segment_header, ut64 offset)
 
static bool read_note_segment_header (ELFOBJ *bin, ut64 *offset, Elf_(Nhdr) *note_segment_header)
 
static bool set_note_segment (ELFOBJ *bin, RzVector *notes, RzBinElfSegment *segment)
 
static void note_prstatus_free (RzBinElfNotePrStatus *ptr)
 
static void note_file_free (RzBinElfNoteFile *ptr)
 
static void note_free (void *e, RZ_UNUSED void *user)
 
static void note_segment_free (void *e, RZ_UNUSED void *user)
 
RZ_BORROW RzBinElfPrStatusLayout *Elf_() rz_bin_elf_get_prstatus_layout (RZ_NONNULL ELFOBJ *bin)
 
RZ_OWN RzVector *Elf_() rz_bin_elf_notes_new (RZ_NONNULL ELFOBJ *bin)
 
bool Elf_() rz_bin_elf_has_notes (RZ_NONNULL ELFOBJ *bin)
 

Variables

static RzBinElfPrStatusLayout prstatus_layouts [ARCH_LEN]
 

Macro Definition Documentation

◆ AARCH64

#define AARCH64   3

Definition at line 14 of file elf_notes.c.

◆ ARCH_LEN

#define ARCH_LEN   4

Definition at line 15 of file elf_notes.c.

◆ ARM

#define ARM   2

Definition at line 13 of file elf_notes.c.

◆ ROUND_UP_4

#define ROUND_UP_4 (   x)    ((x) + (4 - 1)) / 4 * 4

Definition at line 9 of file elf_notes.c.

◆ X86

#define X86   0

Definition at line 11 of file elf_notes.c.

◆ X86_64

#define X86_64   1

Definition at line 12 of file elf_notes.c.

Function Documentation

◆ get_note_file()

static bool get_note_file ( ELFOBJ bin,
RzBinElfNoteFile file,
ut64 offset 
)
static

Definition at line 58 of file elf_notes.c.

58  {
59  ut64 tmp = *offset;
60  if (!get_note_file_aux(bin, file, offset)) {
61  RZ_LOG_WARN("Failed to read NT_FILE at 0x%" PFMT64x ".\n", tmp);
62  }
63 
64  return true;
65 }
static bool get_note_file_aux(ELFOBJ *bin, RzBinElfNoteFile *file, ut64 *offset)
Definition: elf_notes.c:52
voidpf uLong offset
Definition: ioapi.h:144
#define RZ_LOG_WARN(fmtstr,...)
Definition: rz_log.h:56
#define PFMT64x
Definition: rz_types.h:393
Definition: malloc.c:26
Definition: gzappend.c:170
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References get_note_file_aux(), PFMT64x, RZ_LOG_WARN, autogen_x86imm::tmp, and ut64().

Referenced by set_note_file().

◆ get_note_file_aux()

static bool get_note_file_aux ( ELFOBJ bin,
RzBinElfNoteFile file,
ut64 offset 
)
static

Definition at line 52 of file elf_notes.c.

52  {
53  return Elf_(rz_bin_elf_read_addr)(bin, offset, &file->start_vaddr) &&
54  Elf_(rz_bin_elf_read_addr)(bin, offset, &file->end_vaddr) &&
55  Elf_(rz_bin_elf_read_off)(bin, offset, &file->file_off);
56 }
bool Elf_() rz_bin_elf_read_addr(RZ_NONNULL ELFOBJ *bin, RZ_NONNULL RZ_INOUT ut64 *offset, RZ_NONNULL RZ_OUT Elf_(Addr) *result)
Definition: elf_misc.c:82
bool Elf_() rz_bin_elf_read_off(RZ_NONNULL ELFOBJ *bin, RZ_NONNULL RZ_INOUT ut64 *offset, RZ_NONNULL RZ_OUT Elf_(Off) *result)
Definition: elf_misc.c:91
#define Elf_(name)
Definition: elf_specs.h:32

References Elf_, rz_bin_elf_read_addr(), and rz_bin_elf_read_off().

Referenced by get_note_file().

◆ note_file_free()

static void note_file_free ( RzBinElfNoteFile ptr)
static

Definition at line 179 of file elf_notes.c.

179  {
180  free(ptr->file);
181 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130

References free().

Referenced by note_free().

◆ note_free()

static void note_free ( void *  e,
RZ_UNUSED void *  user 
)
static

Definition at line 183 of file elf_notes.c.

183  {
184  RzBinElfNote *ptr = e;
185 
186  switch (ptr->type) {
187  case NT_FILE:
188  note_file_free(&ptr->file);
189  break;
190  case NT_PRSTATUS:
191  note_prstatus_free(&ptr->prstatus);
192  break;
193  }
194 }
#define e(frag)
RzBinElfNote
Definition: elf.h:182
static void note_prstatus_free(RzBinElfNotePrStatus *ptr)
Definition: elf_notes.c:175
static void note_file_free(RzBinElfNoteFile *ptr)
Definition: elf_notes.c:179
#define NT_FILE
Definition: glibc_elf.h:752
#define NT_PRSTATUS
Definition: common.h:393

References e, note_file_free(), note_prstatus_free(), NT_FILE, NT_PRSTATUS, and RzBinElfNote.

Referenced by rz_bin_elf_notes_new().

◆ note_prstatus_free()

static void note_prstatus_free ( RzBinElfNotePrStatus ptr)
static

Definition at line 175 of file elf_notes.c.

175  {
176  free(ptr->regstate);
177 }

References free(), and rz_bin_elf_note_prstatus_t::regstate.

Referenced by note_free().

◆ note_segment_free()

static void note_segment_free ( void *  e,
RZ_UNUSED void *  user 
)
static

Definition at line 196 of file elf_notes.c.

196  {
197  RzVector *ptr = e;
198  rz_vector_fini(ptr);
199 }
RZ_API void rz_vector_fini(RzVector *vec)
Definition: vector.c:61

References e, and rz_vector_fini().

Referenced by rz_bin_elf_notes_new().

◆ parse_note_file()

static bool parse_note_file ( ELFOBJ bin,
RzVector notes,
Elf_(Nhdr) *  note_segment_header,
ut64  offset 
)
static

Definition at line 76 of file elf_notes.c.

76  {
77  Elf_(Addr) n_maps;
78  if (!Elf_(rz_bin_elf_read_addr)(bin, &offset, &n_maps)) {
79  return false;
80  }
81 
82  offset += sizeof(Elf_(Addr)); // skip page size always 1
83 
84  Elf_(Addr) strings_offset; // offset after the addr-array
85  if (!Elf_(rz_bin_elf_mul_addr)(&strings_offset, n_maps, sizeof(Elf_(Addr)) * 3)) {
86  return false;
87  }
88 
89  ut64 entry_offset = offset;
90  for (Elf_(Addr) i = 0; i < n_maps; i++) {
91  if (strings_offset >= note_segment_header->n_descsz) {
92  return false;
93  }
94 
95  char *name = rz_buf_get_nstring(bin->b, offset + strings_offset, note_segment_header->n_descsz);
96  if (!name) {
97  return false;
98  }
99 
100  RzBinElfNote *note = rz_vector_push(notes, NULL);
101  if (!note) {
102  free(name);
103  return false;
104  }
105 
106  note->type = NT_FILE;
107 
108  if (!set_note_file(bin, &note->file, &entry_offset, name)) {
109  return false;
110  }
111 
112  strings_offset += strlen(name) + 1;
113  }
114 
115  return true;
116 }
lzma_index ** i
Definition: index.h:629
#define NULL
Definition: cris-opc.c:27
bool Elf_() rz_bin_elf_mul_addr(Elf_(Addr) *result, Elf_(Addr) addr, Elf_(Addr) value)
Definition: elf_misc.c:154
static bool set_note_file(ELFOBJ *bin, RzBinElfNoteFile *file, ut64 *offset, char *name)
Definition: elf_notes.c:67
RZ_API RZ_OWN char * rz_buf_get_nstring(RZ_NONNULL RzBuffer *b, ut64 addr, size_t size)
Get a string with a max length from the buffer.
Definition: buf.c:585
RZ_API void * rz_vector_push(RzVector *vec, void *x)
Definition: vector.c:197
Definition: z80asm.h:102

References Elf_, free(), i, NT_FILE, NULL, rz_bin_elf_mul_addr(), rz_bin_elf_read_addr(), rz_buf_get_nstring(), rz_vector_push(), RzBinElfNote, set_note_file(), and ut64().

Referenced by set_note().

◆ parse_note_prstatus()

static bool parse_note_prstatus ( ELFOBJ bin,
RzVector notes,
Elf_(Nhdr) *  note_segment_header,
ut64  offset 
)
static

Definition at line 24 of file elf_notes.c.

24  {
26  if (!layout) {
27  RZ_LOG_WARN("Fetching registers from core file not supported for this architecture.\n");
28  return false;
29  }
30 
31  RzBinElfNote *note = rz_vector_push(notes, NULL);
32  if (!note) {
33  return false;
34  }
35 
36  note->type = NT_PRSTATUS;
37 
38  note->prstatus.regstate_size = layout->regsize;
39  note->prstatus.regstate = RZ_NEWS(ut8, layout->regsize);
40  if (!note->prstatus.regstate) {
41  return false;
42  }
43 
44  if (rz_buf_read_at(bin->b, offset + layout->regdelta, note->prstatus.regstate, note->prstatus.regstate_size) != layout->regsize) {
45  RZ_LOG_WARN("Failed to read register state from CORE file\n");
46  return false;
47  }
48 
49  return true;
50 }
RZ_BORROW RzBinElfPrStatusLayout *Elf_() rz_bin_elf_get_prstatus_layout(RZ_NONNULL ELFOBJ *bin)
Definition: elf_notes.c:201
uint8_t ut8
Definition: lh5801.h:11
RZ_API st64 rz_buf_read_at(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL RZ_OUT ut8 *buf, ut64 len)
Read len bytes of the buffer at the specified address.
Definition: buf.c:1136
#define RZ_NEWS(x, y)
Definition: rz_types.h:283
Information about the binary layout in a NT_PRSTATUS note for core files of a certain architecture an...
Definition: elf.h:82
ut64 regsize
Definition: elf.h:83
ut64 regdelta
Definition: elf.h:94

References Elf_, NT_PRSTATUS, NULL, prstatus_layout_t::regdelta, prstatus_layout_t::regsize, rz_bin_elf_get_prstatus_layout(), rz_buf_read_at(), RZ_LOG_WARN, RZ_NEWS, rz_vector_push(), and RzBinElfNote.

Referenced by set_note().

◆ read_note_segment_header()

static bool read_note_segment_header ( ELFOBJ bin,
ut64 offset,
Elf_(Nhdr) *  note_segment_header 
)
static

Definition at line 137 of file elf_notes.c.

137  {
138  if (!Elf_(rz_bin_elf_read_word)(bin, offset, &note_segment_header->n_namesz)) {
139  return false;
140  }
141 
142  if (!Elf_(rz_bin_elf_read_word)(bin, offset, &note_segment_header->n_descsz)) {
143  return false;
144  }
145 
146  if (!Elf_(rz_bin_elf_read_word)(bin, offset, &note_segment_header->n_type)) {
147  return false;
148  }
149 
150  return true;
151 }
bool Elf_() rz_bin_elf_read_word(RZ_NONNULL ELFOBJ *bin, RZ_NONNULL RZ_INOUT ut64 *offset, RZ_NONNULL RZ_OUT Elf_(Word) *result)
Definition: elf_misc.c:62

References Elf_, and rz_bin_elf_read_word().

Referenced by set_note_segment().

◆ rz_bin_elf_get_prstatus_layout()

RZ_BORROW RzBinElfPrStatusLayout* Elf_() rz_bin_elf_get_prstatus_layout ( RZ_NONNULL ELFOBJ bin)

Definition at line 201 of file elf_notes.c.

201  {
203 
204  switch (bin->ehdr.e_machine) {
205  case EM_AARCH64:
206  return prstatus_layouts + AARCH64;
207  case EM_ARM:
208  return prstatus_layouts + ARM;
209  case EM_386:
210  return prstatus_layouts + X86;
211  case EM_X86_64:
212  return prstatus_layouts + X86_64;
213  }
214 
215  return NULL;
216 }
#define X86_64
Definition: elf_notes.c:12
#define X86
Definition: elf_notes.c:11
static RzBinElfPrStatusLayout prstatus_layouts[ARCH_LEN]
Definition: elf_notes.c:17
#define ARM
Definition: elf_notes.c:13
#define AARCH64
Definition: elf_notes.c:14
#define EM_AARCH64
Definition: elf_specs.h:161
#define EM_X86_64
Definition: common.h:151
#define EM_386
Definition: common.h:105
#define EM_ARM
Definition: common.h:129
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108

References AARCH64, ARM, EM_386, EM_AARCH64, EM_ARM, EM_X86_64, NULL, prstatus_layouts, rz_return_val_if_fail, X86, and X86_64.

Referenced by parse_note_prstatus(), and rz_bin_elf_get_sp_val().

◆ rz_bin_elf_has_notes()

bool Elf_() rz_bin_elf_has_notes ( RZ_NONNULL ELFOBJ bin)

Definition at line 255 of file elf_notes.c.

255  {
256  rz_return_val_if_fail(bin, false);
257  return bin->notes;
258 }

References rz_return_val_if_fail.

◆ rz_bin_elf_notes_new()

RZ_OWN RzVector* Elf_() rz_bin_elf_notes_new ( RZ_NONNULL ELFOBJ bin)

Definition at line 218 of file elf_notes.c.

218  {
219  rz_return_val_if_fail(bin, false);
220 
222  if (!result) {
223  return NULL;
224  }
225 
226  RzBinElfSegment *segment;
227  rz_bin_elf_foreach_segments(bin, segment) {
228  if (!segment->is_valid || segment->data.p_type != PT_NOTE) {
229  continue;
230  }
231 
232  RzVector *notes = rz_vector_push(result, NULL);
233  if (!notes) {
234  rz_vector_free(result);
235  return NULL;
236  }
237 
238  rz_vector_init(notes, sizeof(RzBinElfNote), note_free, NULL);
239 
240  if (!set_note_segment(bin, notes, segment)) {
241  rz_vector_fini(notes);
242  rz_vector_free(result);
243  return NULL;
244  }
245  }
246 
247  if (!rz_vector_len(result)) {
248  rz_vector_free(result);
249  return NULL;
250  }
251 
252  return result;
253 }
#define rz_bin_elf_foreach_segments(bin, segment)
Definition: elf.h:26
RzBinElfSegment
Definition: elf.h:131
static void note_free(void *e, RZ_UNUSED void *user)
Definition: elf_notes.c:183
static bool set_note_segment(ELFOBJ *bin, RzVector *notes, RzBinElfSegment *segment)
Definition: elf_notes.c:153
static void note_segment_free(void *e, RZ_UNUSED void *user)
Definition: elf_notes.c:196
#define PT_NOTE
Definition: common.h:306
RZ_API void rz_vector_free(RzVector *vec)
Definition: vector.c:75
RZ_API RzVector * rz_vector_new(size_t elem_size, RzVectorFree free, void *free_user)
Definition: vector.c:42
static size_t rz_vector_len(const RzVector *vec)
Definition: rz_vector.h:82
RZ_API void rz_vector_init(RzVector *vec, size_t elem_size, RzVectorFree free, void *free_user)
Definition: vector.c:33

References note_free(), note_segment_free(), NULL, PT_NOTE, rz_bin_elf_foreach_segments, rz_return_val_if_fail, rz_vector_fini(), rz_vector_free(), rz_vector_init(), rz_vector_len(), rz_vector_new(), rz_vector_push(), RzBinElfNote, RzBinElfSegment, and set_note_segment().

Referenced by init().

◆ set_note()

static bool set_note ( ELFOBJ bin,
RzVector notes,
Elf_(Nhdr) *  note_segment_header,
ut64  offset 
)
static

Definition at line 118 of file elf_notes.c.

118  {
119  switch (note_segment_header->n_type) {
120  case NT_FILE:
121  if (!parse_note_file(bin, notes, note_segment_header, offset)) {
122  RZ_LOG_WARN("Failed to parse NT_FILE.\n");
123  return false;
124  }
125  break;
126  case NT_PRSTATUS:
127  if (!parse_note_prstatus(bin, notes, note_segment_header, offset)) {
128  RZ_LOG_WARN("Failed to parse NT_PRSTATUS.\n");
129  return false;
130  }
131  break;
132  }
133 
134  return true;
135 }
static bool parse_note_prstatus(ELFOBJ *bin, RzVector *notes, Elf_(Nhdr) *note_segment_header, ut64 offset)
Definition: elf_notes.c:24
static bool parse_note_file(ELFOBJ *bin, RzVector *notes, Elf_(Nhdr) *note_segment_header, ut64 offset)
Definition: elf_notes.c:76

References NT_FILE, NT_PRSTATUS, parse_note_file(), parse_note_prstatus(), and RZ_LOG_WARN.

Referenced by set_note_segment().

◆ set_note_file()

static bool set_note_file ( ELFOBJ bin,
RzBinElfNoteFile file,
ut64 offset,
char *  name 
)
static

Definition at line 67 of file elf_notes.c.

67  {
68  if (!get_note_file(bin, file, offset)) {
69  return false;
70  }
71 
72  file->file = name;
73  return true;
74 }
static bool get_note_file(ELFOBJ *bin, RzBinElfNoteFile *file, ut64 *offset)
Definition: elf_notes.c:58
const char * name
Definition: op.c:541

References get_note_file(), and name.

Referenced by parse_note_file().

◆ set_note_segment()

static bool set_note_segment ( ELFOBJ bin,
RzVector notes,
RzBinElfSegment segment 
)
static

Definition at line 153 of file elf_notes.c.

153  {
154  ut64 offset = segment->data.p_offset;
155 
156  while (offset < segment->data.p_filesz) {
157  Elf_(Nhdr) note_segment_header;
158 
159  if (!read_note_segment_header(bin, &offset, &note_segment_header)) {
160  return false;
161  }
162 
163  offset += ROUND_UP_4(note_segment_header.n_namesz); // skip name
164 
165  if (!set_note(bin, notes, &note_segment_header, offset)) {
166  return false;
167  }
168 
169  offset += ROUND_UP_4(note_segment_header.n_descsz); // skip name
170  }
171 
172  return true;
173 }
#define ROUND_UP_4(x)
Definition: elf_notes.c:9
static bool read_note_segment_header(ELFOBJ *bin, ut64 *offset, Elf_(Nhdr) *note_segment_header)
Definition: elf_notes.c:137
static bool set_note(ELFOBJ *bin, RzVector *notes, Elf_(Nhdr) *note_segment_header, ut64 offset)
Definition: elf_notes.c:118

References Elf_, read_note_segment_header(), ROUND_UP_4, set_note(), and ut64().

Referenced by rz_bin_elf_notes_new().

Variable Documentation

◆ prstatus_layouts

RzBinElfPrStatusLayout prstatus_layouts[ARCH_LEN]
static
Initial value:
= {
[X86] = { 160, 0x48, 32, 0x3c },
[X86_64] = { 216, 0x70, 64, 0x98 },
[ARM] = { 72, 0x48, 32, 0x34 },
[AARCH64] = { 272, 0x70, 64, 0xf8 }
}

Definition at line 17 of file elf_notes.c.

Referenced by rz_bin_elf_get_prstatus_layout().