Rizin
unix-like reverse engineering framework and cli tools
relocs_patch.c File Reference
#include <rz_bin.h>
#include <ht_uu.h>

Go to the source code of this file.

Classes

struct  rz_bin_reloc_target_builder
 

Functions

RZ_API ut64 rz_bin_relocs_patch_find_targets_map_base (RzList *maps, ut64 target_sz)
 Finm a suitable location for putting the artificial reloc targets map. More...
 
RZ_API RzBinRelocTargetBuilder * rz_bin_reloc_target_builder_new (ut64 target_size, ut64 target_base)
 
RZ_API void rz_bin_reloc_target_builder_free (RzBinRelocTargetBuilder *builder)
 
RZ_API ut64 rz_bin_reloc_target_builder_get_target (RzBinRelocTargetBuilder *builder, ut64 sym)
 obtain the address of the target for a given symbol More...
 
RZ_API void rz_bin_relocs_patch_maps (RZ_NONNULL RzList *maps, RZ_NULLABLE RzBuffer *buf_patched, ut64 buf_patched_offset, ut64 target_vfile_base, ut64 target_vfile_size, RZ_NONNULL const char *vfile_name_patched, RZ_NONNULL const char *vfile_name_reloc_targets)
 Change file-mapped maps to the patched vfile if covered by the buffer and add the reloc target map. More...
 

Function Documentation

◆ rz_bin_reloc_target_builder_free()

RZ_API void rz_bin_reloc_target_builder_free ( RzBinRelocTargetBuilder *  builder)

Definition at line 51 of file relocs_patch.c.

51  {
52  if (!builder) {
53  return;
54  }
55  ht_uu_free(builder->targets_by_sym);
56  free(builder);
57 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130

References free().

Referenced by patch_relocs().

◆ rz_bin_reloc_target_builder_get_target()

RZ_API ut64 rz_bin_reloc_target_builder_get_target ( RzBinRelocTargetBuilder *  builder,
ut64  sym 
)

obtain the address of the target for a given symbol

When patchin a reloc that points to some symbol that itself is not part of the file (e.g. an import), this function is used to obtain an address in the reloc target map that the reloc can be patched to. On the first call with a new symbol, the builder will allocate a new address, which will be returned on all following calls with the same sym value.

Parameters
symsome (uninterpreted) unique identifier for a symbol. This function will always return the same value for a single symbol.

Definition at line 69 of file relocs_patch.c.

69  {
70  bool found;
71  ut64 r = ht_uu_find(builder->targets_by_sym, sym, &found);
72  if (found) {
73  return r;
74  }
75  r = builder->next_target;
76  ht_uu_insert(builder->targets_by_sym, sym, r);
77  builder->next_target += builder->target_size;
78  return r;
79 }
#define r
Definition: crypto_rc6.c:12
RZ_API const KEY_TYPE bool * found
Definition: ht_inc.h:130
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References found, r, and ut64().

Referenced by patch_relocs().

◆ rz_bin_reloc_target_builder_new()

RZ_API RzBinRelocTargetBuilder* rz_bin_reloc_target_builder_new ( ut64  target_size,
ut64  target_base 
)
Parameters
target_sizesize of a single reloc target in the vfile
target_basebase address where the target vfile will be mapped, generated targets will start at this address.

Definition at line 35 of file relocs_patch.c.

35  {
36  RzBinRelocTargetBuilder *builder = RZ_NEW(RzBinRelocTargetBuilder);
37  if (!builder) {
38  return NULL;
39  }
40  builder->target_size = target_size;
41  builder->next_target = target_base;
42  HtUUOptions opt = { 0 };
43  builder->targets_by_sym = ht_uu_new_opt(&opt);
44  if (!builder->targets_by_sym) {
45  free(builder);
46  return NULL;
47  }
48  return builder;
49 }
#define NULL
Definition: cris-opc.c:27
#define RZ_NEW(x)
Definition: rz_types.h:285

References free(), NULL, and RZ_NEW.

Referenced by patch_relocs().

◆ rz_bin_relocs_patch_find_targets_map_base()

RZ_API ut64 rz_bin_relocs_patch_find_targets_map_base ( RzList maps,
ut64  target_sz 
)

Finm a suitable location for putting the artificial reloc targets map.

Definition at line 8 of file relocs_patch.c.

8  {
9  // find the lowest unmapped address
10  ut64 max = 0;
11  if (maps) {
12  RzListIter *it;
13  RzBinMap *map;
14  rz_list_foreach (maps, it, map) {
15  ut64 addr = map->vaddr + map->vsize;
16  if (addr > max) {
17  max = addr;
18  }
19  }
20  }
21  max += 0x8; // small additional shift to not overlap with symbols like _end
22  return max + rz_num_align_delta(max, target_sz);
23 }
static RzList * maps(RzBinFile *bf)
Definition: bin_bf.c:116
int max
Definition: enough.c:225
size_t map(int syms, int left, int len)
Definition: enough.c:237
static ut64 rz_num_align_delta(ut64 v, ut64 alignment)
Padding to align v to the next alignment-boundary.
Definition: rz_num.h:116
Description of a single memory mapping into virtual memory from a binary.
Definition: rz_bin.h:602
static int addr
Definition: z80asm.c:58

References addr, map(), maps(), max, rz_num_align_delta(), and ut64().

Referenced by reloc_targets_map_base().

◆ rz_bin_relocs_patch_maps()

RZ_API void rz_bin_relocs_patch_maps ( RZ_NONNULL RzList maps,
RZ_NULLABLE RzBuffer buf_patched,
ut64  buf_patched_offset,
ut64  target_vfile_base,
ut64  target_vfile_size,
RZ_NONNULL const char *  vfile_name_patched,
RZ_NONNULL const char *  vfile_name_reloc_targets 
)

Change file-mapped maps to the patched vfile if covered by the buffer and add the reloc target map.

Parameters
buf_patched_offsetthe offset of the data in buf_patched inside the real file. This is especially relevant for fatmach0 where the buf starts further into the fat file.

Definition at line 86 of file relocs_patch.c.

89  {
91 
92  // if relocs should be patched, use the patched vfile for everything from the file
93  if (buf_patched) {
94  RzListIter *it;
95  RzBinMap *map;
96  rz_list_foreach (maps, it, map) {
97  if (map->vfile_name) {
98  // For mach0, this skips rebased+stripped maps, preventing reloc patching there.
99  // But as far as we can tell, these two features are mutually exclusive in practice.
100  continue;
101  }
102  ut64 buf_addr = map->paddr - buf_patched_offset;
103  if (!map->psize || !rz_buf_sparse_populated_in(buf_patched, buf_addr, buf_addr + map->psize - 1)) {
104  // avoid using the patched file if there is nothing different in this range
105  continue;
106  }
107  map->vfile_name = strdup(vfile_name_patched);
108  map->paddr = buf_addr;
109  }
110  }
111 
112  if (target_vfile_size) {
113  // virtual file for reloc targets (where the relocs will point into)
115  if (!map) {
116  return;
117  }
118  map->name = strdup("reloc-targets");
119  map->paddr = 0;
120  map->psize = target_vfile_size;
121  map->vaddr = target_vfile_base;
122  map->vsize = target_vfile_size;
123  map->perm = RZ_PERM_R;
124  map->vfile_name = strdup(vfile_name_reloc_targets);
126  }
127 }
RZ_API RZ_BORROW RzListIter * rz_list_prepend(RZ_NONNULL RzList *list, void *data)
Appends at the beginning of the list a new element.
Definition: list.c:316
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
RZ_API bool rz_buf_sparse_populated_in(RzBuffer *b, ut64 from, ut64 to)
Definition: buf_sparse.c:339
#define RZ_PERM_R
Definition: rz_types.h:93
#define RZ_NEW0(x)
Definition: rz_types.h:284

References map(), maps(), rz_buf_sparse_populated_in(), rz_list_prepend(), RZ_NEW0, RZ_PERM_R, rz_return_if_fail, strdup(), and ut64().

Referenced by get_maps().