Rizin
unix-like reverse engineering framework and cli tools
mdmp_pe.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2016-2018 Davis
2 // SPDX-FileCopyrightText: 2016-2018 Alex Kornitzer <alex.kornitzer@countercept.com>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include <rz_util.h>
6 #include <rz_list.h>
7 
8 #include "mdmp_pe.h"
9 
10 static void PE_(add_tls_callbacks)(struct PE_(rz_bin_pe_obj_t) * bin, RzList *list) {
11  char *key;
12  int count = 0;
13  PE_DWord haddr, paddr, vaddr;
14  RzBinAddr *ptr = NULL;
15 
16  do {
17  key = sdb_fmt("pe.tls_callback%d_paddr", count);
18  paddr = sdb_num_get(bin->kv, key, 0);
19  if (!paddr) {
20  break;
21  }
22 
23  key = sdb_fmt("pe.tls_callback%d_vaddr", count);
24  vaddr = sdb_num_get(bin->kv, key, 0);
25  if (!vaddr) {
26  break;
27  }
28 
29  key = sdb_fmt("pe.tls_callback%d_haddr", count);
30  haddr = sdb_num_get(bin->kv, key, 0);
31  if (!haddr) {
32  break;
33  }
34  if ((ptr = RZ_NEW0(RzBinAddr))) {
35  ptr->paddr = paddr;
36  ptr->vaddr = vaddr;
37  ptr->hpaddr = haddr;
39  rz_list_append(list, ptr);
40  }
41  count++;
42  } while (vaddr);
43 }
44 
45 RzList *PE_(rz_bin_mdmp_pe_get_entrypoint)(struct PE_(rz_bin_mdmp_pe_bin) * pe_bin) {
46  ut64 offset;
47  struct rz_bin_pe_addr_t *entry = NULL;
48  RzBinAddr *ptr = NULL;
49  RzList *ret;
50 
51  if (!(entry = PE_(rz_bin_pe_get_entrypoint)(pe_bin->bin))) {
52  return NULL;
53  }
54  if (!(ret = rz_list_new())) {
55  free(entry);
56  return NULL;
57  }
58 
59  if ((ptr = RZ_NEW0(RzBinAddr))) {
60  offset = entry->vaddr;
61  if (offset > pe_bin->vaddr) {
62  offset -= pe_bin->vaddr;
63  }
64  ptr->paddr = offset + pe_bin->paddr;
65  ptr->vaddr = offset + pe_bin->vaddr;
66  ptr->hpaddr = pe_bin->paddr + entry->haddr;
68 
69  rz_list_append(ret, ptr);
70  }
71 
73  (pe_bin->bin, ret);
74 
75  free(entry);
76 
77  return ret;
78 }
79 
80 static void filter_import(ut8 *n) {
81  int I;
82  for (I = 0; n[I]; I++) {
83  if (n[I] < 30 || n[I] >= 0x7f) {
84  n[I] = 0;
85  break;
86  }
87  }
88 }
89 
90 RzList *PE_(rz_bin_mdmp_pe_get_imports)(struct PE_(rz_bin_mdmp_pe_bin) * pe_bin) {
91  int i;
92  ut64 offset;
94  RzBinImport *ptr = NULL;
95  RzBinReloc *rel;
96  RzList *ret, *relocs;
97 
98  imports = PE_(rz_bin_pe_get_imports)(pe_bin->bin);
99  ret = rz_list_new();
101 
102  if (!imports || !ret || !relocs) {
103  free(imports);
104  free(ret);
105  free(relocs);
106  return NULL;
107  }
108 
109  pe_bin->bin->relocs = relocs;
110  for (i = 0; !imports[i].last; i++) {
111  if (!(ptr = RZ_NEW0(RzBinImport))) {
112  break;
113  }
115  ptr->name = strdup((const char *)imports[i].name);
116  ptr->libname = *imports[i].libname ? strdup((const char *)imports[i].libname) : NULL;
117  ptr->bind = "NONE";
118  ptr->type = RZ_BIN_TYPE_FUNC_STR;
119  ptr->ordinal = imports[i].ordinal;
120  rz_list_append(ret, ptr);
121 
122  if (!(rel = RZ_NEW0(RzBinReloc))) {
123  break;
124  }
125 #ifdef RZ_BIN_PE64
126  rel->type = RZ_BIN_RELOC_64;
127 #else
128  rel->type = RZ_BIN_RELOC_32;
129 #endif
130  offset = imports[i].vaddr;
131  if (offset > pe_bin->vaddr) {
132  offset -= pe_bin->vaddr;
133  }
134  rel->additive = 0;
135  rel->import = ptr;
136  rel->addend = 0;
137  rel->vaddr = offset + pe_bin->vaddr;
138  rel->paddr = imports[i].paddr + pe_bin->paddr;
139  rz_list_append(relocs, rel);
140  }
141  free(imports);
142 
143  return ret;
144 }
145 
146 RzList *PE_(rz_bin_mdmp_pe_get_sections)(struct PE_(rz_bin_mdmp_pe_bin) * pe_bin) {
147  /* TODO: Vet code, taken verbatim(ish) from bin_pe.c */
148  int i;
149  ut64 ba = pe_bin->vaddr; // baddr (arch);
151  RzBinSection *ptr;
152  RzList *ret;
153 
154  if (!(ret = rz_list_new())) {
155  return NULL;
156  }
157  if (!pe_bin->bin || !(sections = pe_bin->bin->sections)) {
158  rz_list_free(ret);
159  return NULL;
160  }
162  (pe_bin->bin, &sections);
163  for (i = 0; !sections[i].last; i++) {
164  if (!(ptr = RZ_NEW0(RzBinSection))) {
165  break;
166  }
167  if (sections[i].name[0]) {
168  ptr->name = strdup((char *)sections[i].name);
169  } else {
170  ptr->name = strdup("");
171  }
172  ptr->size = sections[i].size;
173  if (ptr->size > pe_bin->bin->size) {
174  if (sections[i].vsize < pe_bin->bin->size) {
175  ptr->size = sections[i].vsize;
176  } else {
177  // hack give it page size
178  ptr->size = 4096;
179  }
180  }
181  ptr->vsize = sections[i].vsize;
182  if (!ptr->vsize && ptr->size) {
183  ptr->vsize = ptr->size;
184  }
185  ptr->paddr = sections[i].paddr + pe_bin->paddr;
186  ptr->vaddr = sections[i].vaddr + ba;
187  ptr->perm = 0;
189  ptr->perm |= RZ_PERM_X;
190  }
192  ptr->perm |= RZ_PERM_W;
193  }
195  ptr->perm |= RZ_PERM_R;
196  }
198  ptr->perm |= RZ_PERM_SHAR;
199  }
200  if ((ptr->perm & RZ_PERM_R) && !(ptr->perm & RZ_PERM_X) && ptr->size > 0) {
201  if (!strncmp(ptr->name, ".rsrc", 5) ||
202  !strncmp(ptr->name, ".data", 5) ||
203  !strncmp(ptr->name, ".rdata", 6)) {
204  ptr->is_data = true;
205  }
206  }
207  rz_list_append(ret, ptr);
208  }
209  return ret;
210 }
211 
212 RzList *PE_(rz_bin_mdmp_pe_get_symbols)(RzBin *rbin, struct PE_(rz_bin_mdmp_pe_bin) * pe_bin) {
213  int i;
214  ut64 offset;
215  struct rz_bin_pe_export_t *symbols = NULL;
216  struct rz_bin_pe_import_t *imports = NULL;
217  RzBinSymbol *ptr = NULL;
218  RzList *ret;
219 
220  if (!(ret = rz_list_new())) {
221  return NULL;
222  }
223 
224  /* TODO: Load symbol table from pdb file */
225  if ((symbols = PE_(rz_bin_pe_get_exports)(pe_bin->bin))) {
226  for (i = 0; !symbols[i].last; i++) {
227  if (!(ptr = RZ_NEW0(RzBinSymbol))) {
228  break;
229  }
230  offset = symbols[i].vaddr;
231  if (offset > pe_bin->vaddr) {
232  offset -= pe_bin->vaddr;
233  }
234  ptr->name = strdup((char *)symbols[i].name);
235  ptr->libname = *symbols[i].libname ? strdup((char *)symbols[i].libname) : NULL;
236  ptr->forwarder = rz_str_constpool_get(&rbin->constpool, (char *)symbols[i].forwarder);
238  ptr->type = RZ_BIN_TYPE_FUNC_STR;
239  ptr->size = 0;
240  ptr->vaddr = offset + pe_bin->vaddr;
241  ptr->paddr = symbols[i].paddr + pe_bin->paddr;
242  ptr->ordinal = symbols[i].ordinal;
243 
244  rz_list_append(ret, ptr);
245  }
246  free(symbols);
247  }
248  /* Calling imports is unstable at the moment, I think this is an issue in pe.c */
249  if ((imports = PE_(rz_bin_pe_get_imports)(pe_bin->bin))) {
250  for (i = 0; !imports[i].last; i++) {
251  if (!(ptr = RZ_NEW0(RzBinSymbol))) {
252  break;
253  }
254  offset = imports[i].vaddr;
255  if (offset > pe_bin->vaddr) {
256  offset -= pe_bin->vaddr;
257  }
258  ptr->name = strdup((const char *)imports[i].name);
259  ptr->libname = *imports[i].libname ? strdup((const char *)imports[i].libname) : NULL;
260  ptr->is_imported = true;
261  ptr->bind = "NONE";
262  ptr->type = RZ_BIN_TYPE_FUNC_STR;
263  ptr->size = 0;
264  ptr->vaddr = offset + pe_bin->vaddr;
265  ptr->paddr = imports[i].paddr + pe_bin->paddr;
266  ptr->ordinal = imports[i].ordinal;
267 
268  rz_list_append(ret, ptr);
269  }
270  free(imports);
271  }
272 
273  return ret;
274 }
lzma_index ** i
Definition: index.h:629
#define I(x)
Definition: arc.h:164
RzList * symbols(RzBinFile *bf)
Definition: bin_ne.c:102
RzList * imports(RzBinFile *bf)
Definition: bin_ne.c:106
RzList * sections(RzBinFile *bf)
Definition: bin_ne.c:110
RzList * relocs(RzBinFile *bf)
Definition: bin_ne.c:114
#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 count
Definition: sflib.h:98
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
RZ_API char * sdb_fmt(const char *fmt,...)
Definition: fmt.c:26
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf uLong offset
Definition: ioapi.h:144
uint8_t ut8
Definition: lh5801.h:11
static void list(RzEgg *egg)
Definition: rz-gg.c:52
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
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")
static void PE_() add_tls_callbacks(struct PE_(rz_bin_pe_obj_t) *bin, RzList *list)
Definition: mdmp_pe.c:10
RzList *PE_() rz_bin_mdmp_pe_get_symbols(RzBin *rbin, struct PE_(rz_bin_mdmp_pe_bin) *pe_bin)
Definition: mdmp_pe.c:212
static void filter_import(ut8 *n)
Definition: mdmp_pe.c:80
RzList *PE_() rz_bin_mdmp_pe_get_imports(struct PE_(rz_bin_mdmp_pe_bin) *pe_bin)
Definition: mdmp_pe.c:90
RzList *PE_() rz_bin_mdmp_pe_get_sections(struct PE_(rz_bin_mdmp_pe_bin) *pe_bin)
Definition: mdmp_pe.c:146
RzList *PE_() rz_bin_mdmp_pe_get_entrypoint(struct PE_(rz_bin_mdmp_pe_bin) *pe_bin)
Definition: mdmp_pe.c:45
int n
Definition: mipsasm.c:19
RZ_API ut64 sdb_num_get(Sdb *s, const char *key, ut32 *cas)
Definition: num.c:13
struct rz_bin_pe_export_t *PE_() rz_bin_pe_get_exports(RzBinPEObj *bin)
Definition: pe_exports.c:162
#define RZ_BIN_PE_SCN_IS_WRITABLE(x)
Definition: pe.h:20
void PE_() rz_bin_pe_check_sections(RzBinPEObj *bin, struct rz_bin_pe_section_t **sects)
Definition: pe_section.c:10
#define RZ_BIN_PE_SCN_IS_SHAREABLE(x)
Definition: pe.h:17
struct rz_bin_pe_addr_t *PE_() rz_bin_pe_get_entrypoint(RzBinPEObj *bin)
Definition: pe_info.c:509
#define RZ_BIN_PE_SCN_IS_EXECUTABLE(x)
Definition: pe.h:18
#define RZ_BIN_PE_SCN_IS_READABLE(x)
Definition: pe.h:19
struct rz_bin_pe_import_t *PE_() rz_bin_pe_get_imports(RzBinPEObj *bin)
Definition: pe_imports.c:198
#define PE_(name)
Definition: pe_specs.h:23
#define PE_DWord
Definition: pe_specs.h:27
@ RZ_BIN_RELOC_32
Definition: rz_bin.h:176
@ RZ_BIN_RELOC_64
Definition: rz_bin.h:177
#define RZ_BIN_ENTRY_TYPE_TLS
Definition: rz_bin.h:37
#define RZ_BIN_ENTRY_TYPE_PROGRAM
Definition: rz_bin.h:33
#define RZ_BIN_BIND_GLOBAL_STR
Definition: rz_bin.h:107
#define RZ_BIN_TYPE_FUNC_STR
Definition: rz_bin.h:119
RZ_API const char * rz_str_constpool_get(RzStrConstPool *pool, const char *str)
Definition: str_constpool.c:19
#define RZ_PERM_R
Definition: rz_types.h:93
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_PERM_W
Definition: rz_types.h:94
#define RZ_PERM_X
Definition: rz_types.h:95
#define RZ_PERM_SHAR
Definition: rz_types.h:100
Definition: malloc.c:26
Definition: zipcmp.c:77
Definition: z80asm.h:102
ut64 vaddr
Definition: rz_bin.h:186
ut64 paddr
Definition: rz_bin.h:187
ut64 hpaddr
Definition: rz_bin.h:189
char * libname
Definition: rz_bin.h:702
const char * type
Definition: rz_bin.h:704
const char * bind
Definition: rz_bin.h:703
ut32 ordinal
Definition: rz_bin.h:707
char * name
Definition: rz_bin.h:701
ut8 libname[PE_NAME_LENGTH+1]
Definition: pe.h:76
ut64 paddr
the paddr where the value should be patched into
Definition: rz_bin.h:717
RzBinRelocType type
Definition: rz_bin.h:712
ut64 vaddr
the vaddr where the value should be patched into
Definition: rz_bin.h:716
RzBinImport * import
Definition: rz_bin.h:714
bool additive
Definition: rz_bin.h:720
st64 addend
Definition: rz_bin.h:715
char * name
Definition: rz_bin.h:619
const char * bind
Definition: rz_bin.h:681
bool is_imported
Definition: rz_bin.h:684
const char * type
Definition: rz_bin.h:682
char * name
Definition: rz_bin.h:675
ut32 ordinal
Definition: rz_bin.h:692
const char * forwarder
Definition: rz_bin.h:680
char * libname
Definition: rz_bin.h:677
ut64(WINAPI *w32_GetEnabledXStateFeatures)()