Rizin
unix-like reverse engineering framework and cli tools
relocs_patch.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2021 Florian Märkl <info@florianmaerkl.de>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_bin.h>
5 #include <ht_uu.h>
6 
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 }
24 
29 } /* RzBinRelocTargetBuilder */;
30 
35 RZ_API RzBinRelocTargetBuilder *rz_bin_reloc_target_builder_new(ut64 target_size, ut64 target_base) {
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 }
50 
51 RZ_API void rz_bin_reloc_target_builder_free(RzBinRelocTargetBuilder *builder) {
52  if (!builder) {
53  return;
54  }
55  ht_uu_free(builder->targets_by_sym);
56  free(builder);
57 }
58 
69 RZ_API ut64 rz_bin_reloc_target_builder_get_target(RzBinRelocTargetBuilder *builder, ut64 sym) {
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 }
80 
87  RZ_NULLABLE RzBuffer *buf_patched, ut64 buf_patched_offset,
88  ut64 target_vfile_base, ut64 target_vfile_size,
89  RZ_NONNULL const char *vfile_name_patched, RZ_NONNULL const char *vfile_name_reloc_targets) {
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 }
static RzList * maps(RzBinFile *bf)
Definition: bin_bf.c:116
#define RZ_API
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
int max
Definition: enough.c:225
size_t map(int syms, int left, int len)
Definition: enough.c:237
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
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")
RZ_API ut64 rz_bin_reloc_target_builder_get_target(RzBinRelocTargetBuilder *builder, ut64 sym)
obtain the address of the target for a given symbol
Definition: relocs_patch.c:69
RZ_API void rz_bin_reloc_target_builder_free(RzBinRelocTargetBuilder *builder)
Definition: relocs_patch.c:51
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.
Definition: relocs_patch.c:86
RZ_API RzBinRelocTargetBuilder * rz_bin_reloc_target_builder_new(ut64 target_size, ut64 target_base)
Definition: relocs_patch.c:35
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: relocs_patch.c:8
#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
static ut64 rz_num_align_delta(ut64 v, ut64 alignment)
Padding to align v to the next alignment-boundary.
Definition: rz_num.h:116
#define RZ_PERM_R
Definition: rz_types.h:93
#define RZ_NULLABLE
Definition: rz_types.h:65
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_NONNULL
Definition: rz_types.h:64
#define RZ_NEW(x)
Definition: rz_types.h:285
Description of a single memory mapping into virtual memory from a binary.
Definition: rz_bin.h:602
HtUU * targets_by_sym
to create only a single target per symbol, if there are more relocs for a single symbol
Definition: relocs_patch.c:27
ut64 target_size
size per target
Definition: relocs_patch.c:26
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58