Rizin
unix-like reverse engineering framework and cli tools
elf_dynamic.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2021 08A <08A@riseup.net>
2 // SPDX-FileCopyrightText: 2021 RizinOrg <info@rizin.re>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include "elf_dynamic.h"
6 
7 static bool get_dt_info(RzBinElfDtDynamic *ptr, ut64 key, ut64 *info) {
8  bool found = false;
9  ut64 tmp = ht_uu_find(ptr->info, key, &found);
10 
11  if (!found) {
12  return false;
13  }
14 
15  if (info) {
16  *info = tmp;
17  }
18 
19  return true;
20 }
21 
23  return Elf_(rz_bin_elf_read_sword_sxword)(bin, &offset, &entry->d_tag) &&
24  Elf_(rz_bin_elf_read_addr)(bin, &offset, &entry->d_un.d_ptr);
25 }
26 
27 static bool get_dynamic_entry(ELFOBJ *bin, ut64 offset, Elf_(Dyn) * entry) {
29  RZ_LOG_WARN("Failed to read DT_DYNAMIC entry at 0x%" PFMT64x ".\n", offset);
30  return false;
31  }
32 
33  return true;
34 }
35 
37  if (key == DT_NEEDED) {
38  return !!rz_vector_push(&ptr->dt_needed, &info);
39  } else {
40  return ht_uu_insert(ptr->info, key, info);
41  }
42 }
43 
45  for (ut64 entry_offset = offset; entry_offset < offset + size; entry_offset += sizeof(Elf_(Dyn))) {
46  Elf_(Dyn) entry;
47  if (!get_dynamic_entry(bin, entry_offset, &entry)) {
48  return false;
49  }
50 
51  if (entry.d_tag == DT_NULL) {
52  break;
53  }
54 
55  if (get_dt_info(ptr, entry.d_tag, NULL)) {
56  RZ_LOG_WARN("DT_DYNAMIC entry (0x%" PFMT64x ") at 0x%" PFMT64x " was already handled.\n", (ut64)entry.d_tag, offset);
57  }
58 
59  if (!add_dt_dynamic_entry(ptr, entry.d_tag, entry.d_un.d_val)) {
60  return false;
61  }
62  }
63 
64  return true;
65 }
66 
69  if (!segment) {
70  RZ_LOG_WARN("No PT_DYNAMIC segment in the ELF binary.\n")
71  return false;
72  }
73 
74  if (!segment->is_valid) {
75  RZ_LOG_WARN("The PT_DYNAMIC segment is invalid.\n");
76  return false;
77  }
78 
79  ut64 offset = Elf_(rz_bin_elf_v2p)(bin, segment->data.p_vaddr);
80  if (offset == UT64_MAX) {
81  RZ_LOG_INFO("Failed to convert PT_DYNAMIC segment p_vaddr to a physical offset.\n")
82  return false;
83  }
84 
85  return fill_dt_dynamic(bin, ptr, offset, segment->data.p_filesz);
86 }
87 
90 
92  return NULL;
93  }
94 
95  return &bin->dt_dynamic->dt_needed;
96 }
97 
100  if (!result) {
101  return NULL;
102  }
103 
104  result->info = ht_uu_new0();
105  if (!result->info) {
107  return NULL;
108  }
109 
110  rz_vector_init(&result->dt_needed, sizeof(ut64), NULL, NULL);
111 
112  if (!init_dt_dynamic(bin, result)) {
114  return NULL;
115  }
116 
117  return result;
118 }
119 
121  rz_return_val_if_fail(bin, false);
122 
124  return false;
125  }
126 
127  return get_dt_info(bin->dt_dynamic, key, info);
128 }
129 
131  rz_return_val_if_fail(bin, false);
132  return bin->dt_dynamic;
133 }
134 
136  if (!ptr) {
137  return;
138  }
139 
140  ht_uu_free(ptr->info);
141  rz_vector_fini(&ptr->dt_needed);
142  free(ptr);
143 }
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
#define NULL
Definition: cris-opc.c:27
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
Definition: sflib.h:118
ut64 Elf_() rz_bin_elf_v2p(RZ_NONNULL ELFOBJ *bin, ut64 vaddr)
Convert a virtual address to the physical address.
Definition: elf.c:429
RzBinElfSegment
Definition: elf.h:131
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
#define ELFOBJ
Definition: elf.h:24
bool Elf_() rz_bin_elf_read_sword_sxword(RZ_NONNULL ELFOBJ *bin, RZ_NONNULL RZ_INOUT ut64 *offset, RZ_NONNULL RZ_OUT Elf_(Sword) *result)
Definition: elf_misc.c:131
RZ_BORROW RzBinElfSegment *Elf_() rz_bin_elf_get_segment_with_type(RZ_NONNULL ELFOBJ *bin, Elf_(Word) type)
Definition: elf_segments.c:120
static bool get_dt_info(RzBinElfDtDynamic *ptr, ut64 key, ut64 *info)
Definition: elf_dynamic.c:7
static bool init_dt_dynamic(ELFOBJ *bin, RzBinElfDtDynamic *ptr)
Definition: elf_dynamic.c:67
bool Elf_() rz_bin_elf_has_dt_dynamic(RZ_NONNULL ELFOBJ *bin)
Definition: elf_dynamic.c:130
static bool get_dynamic_entry(ELFOBJ *bin, ut64 offset, Elf_(Dyn) *entry)
Definition: elf_dynamic.c:27
void Elf_() rz_bin_elf_dt_dynamic_free(RzBinElfDtDynamic *ptr)
Definition: elf_dynamic.c:135
RZ_OWN RzBinElfDtDynamic *Elf_() rz_bin_elf_dt_dynamic_new(RZ_NONNULL ELFOBJ *bin)
Definition: elf_dynamic.c:98
bool Elf_() rz_bin_elf_get_dt_info(RZ_NONNULL ELFOBJ *bin, ut64 key, RZ_OUT ut64 *info)
Definition: elf_dynamic.c:120
static bool fill_dt_dynamic(ELFOBJ *bin, RzBinElfDtDynamic *ptr, ut64 offset, ut64 size)
Definition: elf_dynamic.c:44
RZ_BORROW RzVector *Elf_() rz_bin_elf_get_dt_needed(RZ_NONNULL ELFOBJ *bin)
Definition: elf_dynamic.c:88
static bool add_dt_dynamic_entry(RzBinElfDtDynamic *ptr, ut64 key, ut64 info)
Definition: elf_dynamic.c:36
static bool get_dynamic_entry_aux(ELFOBJ *bin, ut64 offset, Elf_(Dyn) *entry)
Definition: elf_dynamic.c:22
#define Elf_(name)
Definition: elf_specs.h:32
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API const KEY_TYPE bool * found
Definition: ht_inc.h:130
voidpf void uLong size
Definition: ioapi.h:138
voidpf uLong offset
Definition: ioapi.h:144
#define PT_DYNAMIC
Definition: common.h:304
#define DT_NEEDED
Definition: common.h:538
#define DT_NULL
Definition: common.h:537
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
#define RZ_LOG_INFO(fmtstr,...)
Definition: rz_log.h:54
#define RZ_LOG_WARN(fmtstr,...)
Definition: rz_log.h:56
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_OUT
Definition: rz_types.h:51
#define RZ_NONNULL
Definition: rz_types.h:64
#define PFMT64x
Definition: rz_types.h:393
#define RZ_BORROW
Definition: rz_types.h:63
#define UT64_MAX
Definition: rz_types_base.h:86
RZ_API void * rz_vector_push(RzVector *vec, void *x)
Definition: vector.c:197
RZ_API void rz_vector_fini(RzVector *vec)
Definition: vector.c:61
RZ_API void rz_vector_init(RzVector *vec, size_t elem_size, RzVectorFree free, void *free_user)
Definition: vector.c:33
Definition: malloc.c:26
Definition: zipcmp.c:77
ut64(WINAPI *w32_GetEnabledXStateFeatures)()