Rizin
unix-like reverse engineering framework and cli tools
bin_mz.c File Reference
#include <rz_types.h>
#include <rz_bin.h>
#include <rz_lib.h>
#include "mz/mz.h"

Go to the source code of this file.

Macros

#define HM(x)   (int)((int)(x[0] << 8) | (int)(x[1]))
 

Functions

static Sdbget_sdb (RzBinFile *bf)
 
static bool knownHeaderBuffer (RzBuffer *b, ut16 offset)
 
static bool checkEntrypointBuffer (RzBuffer *b)
 
static bool check_buffer (RzBuffer *b)
 
static bool load (RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb)
 
static void destroy (RzBinFile *bf)
 
static RzBinAddrbinsym (RzBinFile *bf, RzBinSpecialSymbol type)
 
static RzListentries (RzBinFile *bf)
 
static RzListsections (RzBinFile *bf)
 
static RzBinInfoinfo (RzBinFile *bf)
 
static void header (RzBinFile *bf)
 
static RzListrelocs (RzBinFile *bf)
 

Variables

RzBinPlugin rz_bin_plugin_mz
 
RZ_API RzLibStruct rizin_plugin
 

Macro Definition Documentation

◆ HM

#define HM (   x)    (int)((int)(x[0] << 8) | (int)(x[1]))

Definition at line 10 of file bin_mz.c.

Function Documentation

◆ binsym()

static RzBinAddr* binsym ( RzBinFile bf,
RzBinSpecialSymbol  type 
)
static

Definition at line 138 of file bin_mz.c.

138  {
139  RzBinAddr *mzaddr = NULL;
140  if (bf && bf->o && bf->o->bin_obj) {
141  switch (type) {
143  mzaddr = rz_bin_mz_get_main_vaddr(bf->o->bin_obj);
144  break;
145  default:
146  break;
147  }
148  }
149  return mzaddr;
150 }
#define NULL
Definition: cris-opc.c:27
int type
Definition: mipsasm.c:17
RzBinAddr * rz_bin_mz_get_main_vaddr(struct rz_bin_mz_obj_t *bin)
Definition: mz.c:330
@ RZ_BIN_SPECIAL_SYMBOL_MAIN
Definition: rz_bin.h:139
RzBinObject * o
Definition: rz_bin.h:305
void * bin_obj
Definition: rz_bin.h:293

References rz_bin_object_t::bin_obj, NULL, rz_bin_file_t::o, rz_bin_mz_get_main_vaddr(), RZ_BIN_SPECIAL_SYMBOL_MAIN, and type.

◆ check_buffer()

static bool check_buffer ( RzBuffer b)
static

Definition at line 89 of file bin_mz.c.

89  {
90  rz_return_val_if_fail(b, false);
91  ut64 b_size = rz_buf_size(b);
92  if (b_size <= 0x3d) {
93  return false;
94  }
95 
96  // Check for MZ magic.
97  ut8 h[2];
98  if (rz_buf_read_at(b, 0, h, 2) != 2) {
99  return false;
100  }
101  if (memcmp(h, "MZ", 2)) {
102  return false;
103  }
104 
105  // See if there is a new exe header.
106  ut16 new_exe_header_offset;
107  if (!rz_buf_read_le16_at(b, 0x3c, &new_exe_header_offset)) {
108  return false;
109  }
110 
111  if (b_size > new_exe_header_offset + 2) {
112  if (knownHeaderBuffer(b, new_exe_header_offset)) {
113  return false;
114  }
115  }
116 
117  // Raw plain MZ executable (watcom)
118  if (!checkEntrypointBuffer(b)) {
119  return false;
120  }
121  return true;
122 }
static bool knownHeaderBuffer(RzBuffer *b, ut16 offset)
Definition: bin_mz.c:23
static bool checkEntrypointBuffer(RzBuffer *b)
Definition: bin_mz.c:45
uint16_t ut16
uint8_t ut8
Definition: lh5801.h:11
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
#define rz_buf_read_le16_at(b, addr, result)
Definition: rz_buf.h:270
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
RZ_API ut64 rz_buf_size(RZ_NONNULL RzBuffer *b)
Return the size of the buffer.
Definition: buf.c:1225
#define b(i)
Definition: sha256.c:42
#define h(i)
Definition: sha256.c:48
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References b, checkEntrypointBuffer(), h, knownHeaderBuffer(), rz_buf_read_at(), rz_buf_read_le16_at, rz_buf_size(), rz_return_val_if_fail, and ut64().

◆ checkEntrypointBuffer()

static bool checkEntrypointBuffer ( RzBuffer b)
static

Definition at line 45 of file bin_mz.c.

45  {
46  ut16 cs;
47  if (!rz_buf_read_le16_at(b, 0x16, &cs)) {
48  return false;
49  }
50 
51  ut16 ip;
52  if (!rz_buf_read_le16_at(b, 0x14, &ip)) {
53  return false;
54  }
55 
56  ut16 tmp;
57  if (!rz_buf_read_le16_at(b, 0x08, &tmp)) {
58  return false;
59  }
60 
61  ut32 pa = ((tmp + cs) << 4) + ip;
62 
63  /* A minimal MZ header is 0x1B bytes. Header length is measured in
64  * 16-byte paragraphs so the minimum header must occupy 2 paragraphs.
65  * This means that the entrypoint should be at least 0x20 unless someone
66  * cleverly fit a few instructions inside the header.
67  */
68  pa &= 0xffff;
70  if (pa >= 0x20 && pa + 1 < length) {
71  ut16 pe;
72  if (!rz_buf_read_le16_at(b, 0x3c, &pe)) {
73  return false;
74  }
75 
76  if (pe + 2 < length && length > 0x104) {
77  ut8 h[2];
78  if (rz_buf_read_at(b, pe, h, 2) == 2) {
79  if (!memcmp(h, "PE", 2)) {
80  return false;
81  }
82  }
83  }
84  return true;
85  }
86  return false;
87 }
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 static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
Definition: sflib.h:133
uint32_t ut32
#define ip

References b, test_evm::cs, h, ip, length, rz_buf_read_at(), rz_buf_read_le16_at, rz_buf_size(), autogen_x86imm::tmp, and ut64().

Referenced by check_buffer().

◆ destroy()

static void destroy ( RzBinFile bf)
static

Definition at line 134 of file bin_mz.c.

134  {
135  rz_bin_mz_free((struct rz_bin_mz_obj_t *)bf->o->bin_obj);
136 }
void * rz_bin_mz_free(struct rz_bin_mz_obj_t *bin)
Definition: mz.c:188

References rz_bin_object_t::bin_obj, rz_bin_file_t::o, and rz_bin_mz_free().

◆ entries()

static RzList* entries ( RzBinFile bf)
static

Definition at line 152 of file bin_mz.c.

152  {
153  RzBinAddr *ptr = NULL;
154  RzList *res = NULL;
155  if (!(res = rz_list_newf(free))) {
156  return NULL;
157  }
158  ptr = rz_bin_mz_get_entrypoint(bf->o->bin_obj);
159  if (ptr) {
160  rz_list_append(res, ptr);
161  }
162  return res;
163 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
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 RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RzBinAddr * rz_bin_mz_get_entrypoint(const struct rz_bin_mz_obj_t *bin)
Definition: mz.c:16

References rz_bin_object_t::bin_obj, free(), NULL, rz_bin_file_t::o, rz_bin_mz_get_entrypoint(), rz_list_append(), and rz_list_newf().

◆ get_sdb()

static Sdb* get_sdb ( RzBinFile bf)
static

Definition at line 12 of file bin_mz.c.

12  {
13  const struct rz_bin_mz_obj_t *bin;
14  if (bf && bf->o && bf->o->bin_obj) {
15  bin = (struct rz_bin_mz_obj_t *)bf->o->bin_obj;
16  if (bin && bin->kv) {
17  return bin->kv;
18  }
19  }
20  return NULL;
21 }
Definition: malloc.c:26
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4

References rz_bin_object_t::bin_obj, if(), NULL, and rz_bin_file_t::o.

◆ header()

static void header ( RzBinFile bf)
static

Definition at line 194 of file bin_mz.c.

194  {
195  const struct rz_bin_mz_obj_t *mz = (struct rz_bin_mz_obj_t *)bf->o->bin_obj;
196  eprintf("[0000:0000] Signature %c%c\n",
197  mz->dos_header->signature & 0xFF,
198  mz->dos_header->signature >> 8);
199  eprintf("[0000:0002] BytesInLastBlock 0x%04x\n",
201  eprintf("[0000:0004] BlocksInFile 0x%04x\n",
203  eprintf("[0000:0006] NumRelocs 0x%04x\n",
204  mz->dos_header->num_relocs);
205  eprintf("[0000:0008] HeaderParagraphs 0x%04x\n",
207  eprintf("[0000:000a] MinExtraParagraphs 0x%04x\n",
209  eprintf("[0000:000c] MaxExtraParagraphs 0x%04x\n",
211  eprintf("[0000:000e] InitialSs 0x%04x\n",
212  mz->dos_header->ss);
213  eprintf("[0000:0010] InitialSp 0x%04x\n",
214  mz->dos_header->sp);
215  eprintf("[0000:0012] Checksum 0x%04x\n",
216  mz->dos_header->checksum);
217  eprintf("[0000:0014] InitialIp 0x%04x\n",
218  mz->dos_header->ip);
219  eprintf("[0000:0016] InitialCs 0x%04x\n",
220  mz->dos_header->cs);
221  eprintf("[0000:0018] RelocTableOffset 0x%04x\n",
223  eprintf("[0000:001a] OverlayNumber 0x%04x\n",
225 }
#define eprintf(x, y...)
Definition: rlcc.c:7
ut16 min_extra_paragraphs
Definition: mz_specs.h:10
ut16 bytes_in_last_block
Definition: mz_specs.h:6
ut16 reloc_table_offset
Definition: mz_specs.h:17
ut16 max_extra_paragraphs
Definition: mz_specs.h:11
ut16 header_paragraphs
Definition: mz_specs.h:9
const MZ_image_dos_header * dos_header
Definition: mz.h:27

References rz_bin_object_t::bin_obj, MZ_image_dos_header::blocks_in_file, MZ_image_dos_header::bytes_in_last_block, MZ_image_dos_header::checksum, MZ_image_dos_header::cs, rz_bin_mz_obj_t::dos_header, eprintf, MZ_image_dos_header::header_paragraphs, MZ_image_dos_header::ip, MZ_image_dos_header::max_extra_paragraphs, MZ_image_dos_header::min_extra_paragraphs, MZ_image_dos_header::num_relocs, rz_bin_file_t::o, MZ_image_dos_header::overlay_number, MZ_image_dos_header::reloc_table_offset, MZ_image_dos_header::signature, MZ_image_dos_header::sp, and MZ_image_dos_header::ss.

◆ info()

static RzBinInfo* info ( RzBinFile bf)
static

Definition at line 169 of file bin_mz.c.

169  {
170  RzBinInfo *const ret = RZ_NEW0(RzBinInfo);
171  if (!ret) {
172  return NULL;
173  }
174  ret->file = strdup(bf->file);
175  ret->bclass = strdup("MZ");
176  ret->rclass = strdup("mz");
177  ret->os = strdup("DOS");
178  ret->arch = strdup("x86");
179  ret->machine = strdup("i386");
180  ret->type = strdup("EXEC (Executable file)");
181  ret->subsystem = strdup("DOS");
182  ret->bits = 16;
183  ret->dbg_info = 0;
184  ret->big_endian = false;
185  ret->has_crypto = false;
186  ret->has_canary = false;
187  ret->has_retguard = -1;
188  ret->has_nx = false;
189  ret->has_pi = false;
190  ret->has_va = true;
191  return ret;
192 }
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_NEW0(x)
Definition: rz_types.h:284
char * file
Definition: rz_bin.h:299
int has_va
Definition: rz_bin.h:228
char * type
Definition: rz_bin.h:211
int has_crypto
Definition: rz_bin.h:233
int has_canary
Definition: rz_bin.h:230
char * os
Definition: rz_bin.h:219
char * subsystem
Definition: rz_bin.h:220
int has_pi
Definition: rz_bin.h:229
int has_nx
Definition: rz_bin.h:234
char * machine
Definition: rz_bin.h:216
char * bclass
Definition: rz_bin.h:212
char * file
Definition: rz_bin.h:210
ut64 dbg_info
Definition: rz_bin.h:240
int has_retguard
Definition: rz_bin.h:231
char * rclass
Definition: rz_bin.h:213
char * arch
Definition: rz_bin.h:214
int big_endian
Definition: rz_bin.h:235

References rz_bin_info_t::arch, rz_bin_info_t::bclass, rz_bin_info_t::big_endian, rz_bin_info_t::bits, rz_bin_info_t::dbg_info, rz_bin_info_t::file, rz_bin_file_t::file, rz_bin_info_t::has_canary, rz_bin_info_t::has_crypto, rz_bin_info_t::has_nx, rz_bin_info_t::has_pi, rz_bin_info_t::has_retguard, rz_bin_info_t::has_va, rz_bin_info_t::machine, NULL, rz_bin_info_t::os, rz_bin_info_t::rclass, RZ_NEW0, strdup(), rz_bin_info_t::subsystem, and rz_bin_info_t::type.

◆ knownHeaderBuffer()

static bool knownHeaderBuffer ( RzBuffer b,
ut16  offset 
)
static

Definition at line 23 of file bin_mz.c.

23  {
24  ut8 h[2];
25  if (rz_buf_read_at(b, offset, h, sizeof(h)) != sizeof(h)) {
26  return false;
27  }
28  if (!memcmp(h, "PE", 2)) {
29  if (offset + 0x20 < rz_buf_size(b)) {
30  if (rz_buf_read_at(b, offset + 0x18, h, sizeof(h)) != 2) {
31  return false;
32  }
33  if (!memcmp(h, "\x0b\x01", 2)) {
34  return true;
35  }
36  }
37  } else {
38  if (!memcmp(h, "NE", 2) || !memcmp(h, "LE", 2) || !memcmp(h, "LX", 2) || !memcmp(h, "PL", 2)) {
39  return true;
40  }
41  }
42  return false;
43 }
voidpf uLong offset
Definition: ioapi.h:144

References b, h, rz_buf_read_at(), and rz_buf_size().

Referenced by check_buffer().

◆ load()

static bool load ( RzBinFile bf,
RzBinObject obj,
RzBuffer buf,
Sdb sdb 
)
static

Definition at line 124 of file bin_mz.c.

124  {
125  struct rz_bin_mz_obj_t *mz_obj = rz_bin_mz_new_buf(buf);
126  if (mz_obj) {
127  sdb_ns_set(sdb, "info", mz_obj->kv);
128  obj->bin_obj = mz_obj;
129  return true;
130  }
131  return false;
132 }
voidpf void * buf
Definition: ioapi.h:138
struct rz_bin_mz_obj_t * rz_bin_mz_new_buf(RzBuffer *buf)
Definition: mz.c:317
RZ_API int sdb_ns_set(Sdb *s, const char *name, Sdb *r)
Definition: ns.c:156
Sdb * kv
Definition: mz.h:38

References rz_bin_object_t::bin_obj, rz_bin_mz_obj_t::kv, rz_bin_mz_new_buf(), and sdb_ns_set().

◆ relocs()

static RzList* relocs ( RzBinFile bf)
static

Definition at line 227 of file bin_mz.c.

227  {
228  RzList *ret = NULL;
229  RzBinReloc *rel = NULL;
230  const struct rz_bin_mz_reloc_t *relocs = NULL;
231  int i;
232 
233  if (!bf || !bf->o || !bf->o->bin_obj) {
234  return NULL;
235  }
236  if (!(ret = rz_list_newf(free))) {
237  return NULL;
238  }
239  if (!(relocs = rz_bin_mz_get_relocs(bf->o->bin_obj))) {
240  return ret;
241  }
242  for (i = 0; !relocs[i].last; i++) {
243  if (!(rel = RZ_NEW0(RzBinReloc))) {
244  free((void *)relocs);
245  rz_list_free(ret);
246  return NULL;
247  }
248  rel->type = RZ_BIN_RELOC_16;
249  rel->vaddr = relocs[i].vaddr;
250  rel->paddr = relocs[i].paddr;
251  rz_list_append(ret, rel);
252  }
253  free((void *)relocs);
254  return ret;
255 }
lzma_index ** i
Definition: index.h:629
static RzList * relocs(RzBinFile *bf)
Definition: bin_mz.c:227
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
struct rz_bin_mz_reloc_t * rz_bin_mz_get_relocs(const struct rz_bin_mz_obj_t *bin)
Definition: mz.c:163
@ RZ_BIN_RELOC_16
Definition: rz_bin.h:174
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

References rz_bin_object_t::bin_obj, free(), i, NULL, rz_bin_file_t::o, rz_bin_reloc_t::paddr, rz_bin_mz_get_relocs(), RZ_BIN_RELOC_16, rz_list_append(), rz_list_free(), rz_list_newf(), RZ_NEW0, rz_bin_reloc_t::type, and rz_bin_reloc_t::vaddr.

◆ sections()

static RzList* sections ( RzBinFile bf)
static

Definition at line 165 of file bin_mz.c.

165  {
166  return rz_bin_mz_get_segments(bf->o->bin_obj);
167 }
RzList * rz_bin_mz_get_segments(const struct rz_bin_mz_obj_t *bin)
Definition: mz.c:62

References rz_bin_object_t::bin_obj, rz_bin_file_t::o, and rz_bin_mz_get_segments().

Variable Documentation

◆ rizin_plugin

RZ_API RzLibStruct rizin_plugin
Initial value:
= {
.type = RZ_LIB_TYPE_BIN,
.data = &rz_bin_plugin_mz,
}
RzBinPlugin rz_bin_plugin_mz
Definition: bin_mz.c:257
@ RZ_LIB_TYPE_BIN
Definition: rz_lib.h:75
#define RZ_VERSION
Definition: rz_version.h:8
char * version
Definition: rz_bin.h:512

Definition at line 276 of file bin_mz.c.

◆ rz_bin_plugin_mz

RzBinPlugin rz_bin_plugin_mz
Initial value:
= {
.name = "mz",
.desc = "MZ bin plugin",
.license = "MIT",
.get_sdb = &get_sdb,
.load_buffer = &load,
.destroy = &destroy,
.check_buffer = &check_buffer,
.binsym = &binsym,
.entries = &entries,
.sections = &sections,
.info = &info,
.header = &header,
.relocs = &relocs,
.minstrlen = 4,
}
RZ_API RZ_OWN RzList * rz_bin_maps_of_file_sections(RZ_NONNULL RzBinFile *binfile)
Create a list of RzBinMap from RzBinSections queried from the given file.
Definition: bin.c:1040
static Sdb * get_sdb(RzBinFile *bf)
Definition: bin_mz.c:12
static RzBinAddr * binsym(RzBinFile *bf, RzBinSpecialSymbol type)
Definition: bin_mz.c:138
static void header(RzBinFile *bf)
Definition: bin_mz.c:194
static void destroy(RzBinFile *bf)
Definition: bin_mz.c:134
static bool check_buffer(RzBuffer *b)
Definition: bin_mz.c:89
static RzBinInfo * info(RzBinFile *bf)
Definition: bin_mz.c:169
static RzList * entries(RzBinFile *bf)
Definition: bin_mz.c:152
static bool load(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb)
Definition: bin_mz.c:124
static RzList * sections(RzBinFile *bf)
Definition: bin_mz.c:165

Definition at line 257 of file bin_mz.c.