Rizin
unix-like reverse engineering framework and cli tools
mz.h File Reference
#include <rz_types.h>
#include <rz_list.h>
#include <rz_util.h>
#include <rz_bin.h>
#include "mz_specs.h"

Go to the source code of this file.

Classes

struct  rz_bin_mz_segment_t
 
struct  rz_bin_mz_reloc_t
 
struct  rz_bin_mz_obj_t
 

Functions

RzBinAddrrz_bin_mz_get_entrypoint (const struct rz_bin_mz_obj_t *bin)
 
RzListrz_bin_mz_get_segments (const struct rz_bin_mz_obj_t *bin)
 
struct rz_bin_mz_reloc_trz_bin_mz_get_relocs (const struct rz_bin_mz_obj_t *bin)
 
void * rz_bin_mz_free (struct rz_bin_mz_obj_t *bin)
 
struct rz_bin_mz_obj_trz_bin_mz_new (const char *file)
 
struct rz_bin_mz_obj_trz_bin_mz_new_buf (RzBuffer *buf)
 
RzBinAddrrz_bin_mz_get_main_vaddr (struct rz_bin_mz_obj_t *bin)
 

Function Documentation

◆ rz_bin_mz_free()

void* rz_bin_mz_free ( struct rz_bin_mz_obj_t bin)

Definition at line 188 of file mz.c.

188  {
189  if (!bin) {
190  return NULL;
191  }
192  free((void *)bin->dos_header);
193  free((void *)bin->dos_extended_header);
194  free((void *)bin->relocation_entries);
195  rz_buf_free(bin->b);
196  bin->b = NULL;
197  free(bin);
198  return NULL;
199 }
#define NULL
Definition: cris-opc.c:27
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API void rz_buf_free(RzBuffer *b)
Free all internal data hold by the buffer and the buffer.
Definition: buf.c:1253
Definition: malloc.c:26

References free(), NULL, and rz_buf_free().

Referenced by destroy(), rz_bin_mz_new(), and rz_bin_mz_new_buf().

◆ rz_bin_mz_get_entrypoint()

RzBinAddr* rz_bin_mz_get_entrypoint ( const struct rz_bin_mz_obj_t bin)

Definition at line 16 of file mz.c.

16  {
17  const MZ_image_dos_header *mz;
18  ut64 la;
19  RzBinAddr *entrypoint;
20 
21  if (!bin || !bin->dos_header) {
22  return NULL;
23  }
24 
25  mz = bin->dos_header;
26  la = rz_bin_mz_va_to_la(mz->cs, mz->ip);
27  la &= 0xfffff;
28  if (la >= bin->load_module_size) {
29  RZ_LOG_ERROR("The entry point is outside the load module size\n");
30  return NULL;
31  }
32  entrypoint = RZ_NEW0(RzBinAddr);
33  if (entrypoint) {
34  entrypoint->vaddr = la;
35  entrypoint->paddr = rz_bin_mz_la_to_pa(bin, la);
36  }
37 
38  return entrypoint;
39 }
static ut64 rz_bin_mz_la_to_pa(const struct rz_bin_mz_obj_t *bin, ut64 la)
Definition: mz.c:12
static ut64 rz_bin_mz_va_to_la(const ut16 segment, const ut16 offset)
Definition: mz.c:8
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
#define RZ_NEW0(x)
Definition: rz_types.h:284
ut64 vaddr
Definition: rz_bin.h:186
ut64 paddr
Definition: rz_bin.h:187
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References MZ_image_dos_header::cs, MZ_image_dos_header::ip, NULL, rz_bin_addr_t::paddr, rz_bin_mz_la_to_pa(), rz_bin_mz_va_to_la(), RZ_LOG_ERROR, RZ_NEW0, ut64(), and rz_bin_addr_t::vaddr.

Referenced by entries(), and rz_bin_mz_get_main_vaddr().

◆ rz_bin_mz_get_main_vaddr()

RzBinAddr* rz_bin_mz_get_main_vaddr ( struct rz_bin_mz_obj_t bin)

Definition at line 330 of file mz.c.

330  {
331  int n;
332  ut8 b[512];
333  if (!bin || !bin->b) {
334  return NULL;
335  }
337  if (!entry) {
338  return NULL;
339  }
340  ZERO_FILL(b);
341  if (rz_buf_read_at(bin->b, entry->paddr, b, sizeof(b)) < 0) {
342  RZ_LOG_ERROR("Cannot read entry at 0x%16" PFMT64x "\n", (ut64)entry->paddr);
343  free(entry);
344  return NULL;
345  }
346  // MSVC
347  if (b[0] == 0xb4 && b[1] == 0x30) {
348  // ff 36 XX XX push XXXX
349  // ff 36 XX XX push argv
350  // ff 36 XX XX push argc
351  // 9a XX XX XX XX lcall _main
352  // 50 push ax
353  for (n = 0; n < sizeof(b) - 18; n++) {
354  if (b[n] == 0xff && b[n + 4] == 0xff && b[n + 8] == 0xff && b[n + 12] == 0x9a && b[n + 17] == 0x50) {
355  const ut16 call_addr = rz_read_ble16(b + n + 13, 0);
356  const ut16 call_seg = rz_read_ble16(b + n + 15, 0);
357  entry->vaddr = rz_bin_mz_va_to_la(call_seg, call_addr);
358  entry->paddr = rz_bin_mz_la_to_pa(bin, entry->vaddr);
359  return entry;
360  }
361  }
362  }
363 
364  RZ_FREE(entry);
365  return NULL;
366 }
uint16_t ut16
uint8_t ut8
Definition: lh5801.h:11
int n
Definition: mipsasm.c:19
RzBinAddr * rz_bin_mz_get_entrypoint(const struct rz_bin_mz_obj_t *bin)
Definition: mz.c:16
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
static ut16 rz_read_ble16(const void *src, bool big_endian)
Definition: rz_endian.h:493
#define ZERO_FILL(x)
Definition: rz_types.h:281
#define RZ_FREE(x)
Definition: rz_types.h:369
#define PFMT64x
Definition: rz_types.h:393
#define b(i)
Definition: sha256.c:42
Definition: zipcmp.c:77

References b, free(), n, NULL, PFMT64x, rz_bin_mz_get_entrypoint(), rz_bin_mz_la_to_pa(), rz_bin_mz_va_to_la(), rz_buf_read_at(), RZ_FREE, RZ_LOG_ERROR, rz_read_ble16(), ut64(), and ZERO_FILL.

Referenced by binsym().

◆ rz_bin_mz_get_relocs()

struct rz_bin_mz_reloc_t* rz_bin_mz_get_relocs ( const struct rz_bin_mz_obj_t bin)

Definition at line 163 of file mz.c.

163  {
164  int i, j;
165  const int num_relocs = bin->dos_header->num_relocs;
166  const MZ_image_relocation_entry *const rel_entry = bin->relocation_entries;
167 
168  struct rz_bin_mz_reloc_t *relocs = calloc(num_relocs + 1, sizeof(*relocs));
169  if (!relocs) {
170  RZ_LOG_ERROR("Cannot allocate struct rz_bin_mz_reloc_t\n");
171  return NULL;
172  }
173  for (i = 0, j = 0; i < num_relocs; i++) {
174  relocs[j].vaddr = rz_bin_mz_va_to_la(rel_entry[i].segment,
175  rel_entry[i].offset);
176  relocs[j].paddr = rz_bin_mz_la_to_pa(bin, relocs[j].vaddr);
177 
178  /* Add only relocations which resides inside dos executable */
179  if (relocs[j].vaddr < bin->load_module_size) {
180  j++;
181  }
182  }
183  relocs[j].last = 1;
184 
185  return relocs;
186 }
lzma_index ** i
Definition: index.h:629
RzList * relocs(RzBinFile *bf)
Definition: bin_ne.c:114
voidpf uLong offset
Definition: ioapi.h:144
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
Definition: mz_specs.h:21
ut64 vaddr
Definition: mz.h:22

References calloc(), i, NULL, relocs(), rz_bin_mz_la_to_pa(), rz_bin_mz_va_to_la(), RZ_LOG_ERROR, and rz_bin_mz_reloc_t::vaddr.

Referenced by relocs().

◆ rz_bin_mz_get_segments()

RzList* rz_bin_mz_get_segments ( const struct rz_bin_mz_obj_t bin)

Definition at line 62 of file mz.c.

62  {
63  RzList *seg_list;
67  int i, num_relocs, section_number;
68  ut16 ss;
69 
70  if (!bin || !bin->dos_header) {
71  return NULL;
72  }
73 
75  if (!seg_list) {
76  return NULL;
77  }
78 
79  /* Add address of first segment to make sure that it is present
80  * even if there are no relocations or there isn't first segment in
81  * the relocations. */
83  if (!section) {
84  goto err_out;
85  }
87 
88  relocs = bin->relocation_entries;
89  num_relocs = bin->dos_header->num_relocs;
90  for (i = 0; i < num_relocs; i++) {
92  ut64 laddr, paddr, section_laddr;
93  ut16 curr_seg;
94 
95  laddr = rz_bin_mz_va_to_la(relocs[i].segment, relocs[i].offset);
96  if ((laddr + 2) >= bin->load_module_size) {
97  continue;
98  }
99 
100  paddr = rz_bin_mz_la_to_pa(bin, laddr);
101  if (rz_buf_size(bin->b) < paddr + 2) {
102  continue;
103  }
104 
105  if (!rz_buf_read_le16_at(bin->b, paddr, &curr_seg)) {
106  continue;
107  }
108 
109  section_laddr = rz_bin_mz_va_to_la(curr_seg, 0);
110  if (section_laddr > bin->load_module_size) {
111  continue;
112  }
113 
114  c.vaddr = section_laddr;
115  if (rz_list_find(seg_list, &c, cmp_sections)) {
116  continue;
117  }
118 
119  section = rz_bin_mz_init_section(bin, section_laddr);
120  if (!section) {
121  goto err_out;
122  }
124  }
125 
126  /* Add address of stack segment if it's inside the load module. */
127  ss = bin->dos_header->ss;
128  if (rz_bin_mz_va_to_la(ss, 0) < bin->load_module_size) {
130  if (!section) {
131  goto err_out;
132  }
134  }
135 
136  /* Fixup sizes and addresses, set name, permissions and set add flag */
137  section_number = 0;
138  rz_list_foreach (seg_list, iter, section) {
139  section->name = rz_str_newf("seg_%03d", section_number);
140  if (section_number) {
141  RzBinSection *p_section = iter->p->data;
142  p_section->size = section->vaddr - p_section->vaddr;
143  p_section->vsize = p_section->size;
144  }
145  section->vsize = section->size;
146  section->paddr = rz_bin_mz_la_to_pa(bin, section->vaddr);
147  section->perm = rz_str_rwx("rwx");
148  section_number++;
149  }
150  section = rz_list_get_top(seg_list);
151  section->size = bin->load_module_size - section->vaddr;
152  section->vsize = section->size;
153 
154  return seg_list;
155 
156 err_out:
157  RZ_LOG_ERROR("Failed to get segment list\n");
158  rz_list_free(seg_list);
159 
160  return NULL;
161 }
RZ_API void rz_bin_section_free(RzBinSection *bs)
Definition: bin.c:1116
RZ_API RZ_BORROW RzListIter * rz_list_find(RZ_NONNULL const RzList *list, const void *p, RZ_NONNULL RzListComparator cmp)
Returns RzListIter element which matches via the RzListComparator.
Definition: list.c:620
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_BORROW void * rz_list_get_top(RZ_NONNULL const RzList *list)
Returns the last element of the list.
Definition: list.c:457
RZ_API RZ_BORROW RzListIter * rz_list_add_sorted(RZ_NONNULL RzList *list, void *data, RZ_NONNULL RzListComparator cmp)
Adds an element to a sorted list via the RzListComparator.
Definition: list.c:518
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
static RzBinSection * rz_bin_mz_init_section(const struct rz_bin_mz_obj_t *bin, ut64 laddr)
Definition: mz.c:50
static int cmp_sections(const void *a, const void *b)
Definition: mz.c:41
#define rz_buf_read_le16_at(b, addr, result)
Definition: rz_buf.h:270
RZ_API ut64 rz_buf_size(RZ_NONNULL RzBuffer *b)
Return the size of the buffer.
Definition: buf.c:1225
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API int rz_str_rwx(const char *str)
Definition: str.c:318
#define c(i)
Definition: sha256.c:43
uint32_t size

References c, cmp_sections(), i, NULL, relocs(), rz_bin_mz_init_section(), rz_bin_mz_la_to_pa(), rz_bin_mz_va_to_la(), rz_bin_section_free(), rz_buf_read_le16_at, rz_buf_size(), rz_list_add_sorted(), rz_list_find(), rz_list_free(), rz_list_get_top(), rz_list_newf(), RZ_LOG_ERROR, rz_str_newf(), rz_str_rwx(), section::size, rz_bin_section_t::size, ut64(), rz_bin_section_t::vaddr, and rz_bin_section_t::vsize.

Referenced by sections().

◆ rz_bin_mz_new()

struct rz_bin_mz_obj_t* rz_bin_mz_new ( const char *  file)

Definition at line 293 of file mz.c.

293  {
294  struct rz_bin_mz_obj_t *bin = RZ_NEW0(struct rz_bin_mz_obj_t);
295  if (!bin) {
296  return NULL;
297  }
298  bin->file = file;
299  size_t binsz;
300  ut8 *buf = (ut8 *)rz_file_slurp(file, &binsz);
301  bin->size = binsz;
302  if (!buf) {
303  return rz_bin_mz_free(bin);
304  }
305  bin->b = rz_buf_new_with_bytes(NULL, 0);
306  if (!rz_buf_set_bytes(bin->b, buf, bin->size)) {
307  free((void *)buf);
308  return rz_bin_mz_free(bin);
309  }
310  free((void *)buf);
311  if (!rz_bin_mz_init(bin)) {
312  return rz_bin_mz_free(bin);
313  }
314  return bin;
315 }
voidpf void * buf
Definition: ioapi.h:138
static bool rz_bin_mz_init(struct rz_bin_mz_obj_t *bin)
Definition: mz.c:281
void * rz_bin_mz_free(struct rz_bin_mz_obj_t *bin)
Definition: mz.c:188
RZ_API bool rz_buf_set_bytes(RZ_NONNULL RzBuffer *b, RZ_NONNULL const ut8 *buf, ut64 len)
Replace the content of the buffer with the bytes array.
Definition: buf.c:905
RZ_API RZ_OWN RzBuffer * rz_buf_new_with_bytes(RZ_NULLABLE RZ_BORROW const ut8 *bytes, ut64 len)
Creates a new buffer with a bytes array.
Definition: buf.c:465
RZ_API RZ_OWN char * rz_file_slurp(const char *str, RZ_NULLABLE size_t *usz)
Definition: file.c:454
Definition: gzappend.c:170
static int file
Definition: z80asm.c:58

References file, free(), NULL, rz_bin_mz_free(), rz_bin_mz_init(), rz_buf_new_with_bytes(), rz_buf_set_bytes(), rz_file_slurp(), and RZ_NEW0.

◆ rz_bin_mz_new_buf()

struct rz_bin_mz_obj_t* rz_bin_mz_new_buf ( RzBuffer buf)

Definition at line 317 of file mz.c.

317  {
318  struct rz_bin_mz_obj_t *bin = RZ_NEW0(struct rz_bin_mz_obj_t);
319  if (!bin) {
320  return NULL;
321  }
323  if (!bin->b) {
324  return rz_bin_mz_free(bin);
325  }
326  bin->size = rz_buf_size(buf);
327  return rz_bin_mz_init(bin) ? bin : rz_bin_mz_free(bin);
328 }
RZ_API RZ_OWN RzBuffer * rz_buf_new_with_buf(RzBuffer *b)
Creates a new buffer from a source buffer.
Definition: buf.c:448

References NULL, rz_bin_mz_free(), rz_bin_mz_init(), rz_buf_new_with_buf(), rz_buf_size(), and RZ_NEW0.

Referenced by load().