1 /* radare - LGPL - Copyright 2019 - GustavoLCR */
2
3 #include <r_bin.h>
4 #include "../format/le/le.h"
5
check_buffer(RBuffer * b)6 static bool check_buffer(RBuffer *b) {
7 ut64 length = r_buf_size (b);
8 if (length < 2) {
9 return false;
10 }
11 ut16 idx = r_buf_read_le16_at (b, 0x3c);
12 if ((ut64)idx + 26 < length) {
13 ut8 buf[2];
14 r_buf_read_at (b, 0, buf, sizeof (buf));
15 if (!memcmp (buf, "LX", 2) || !memcmp (buf, "LE", 2)) {
16 return true;
17 }
18 if (!memcmp (buf, "MZ", 2)) {
19 r_buf_read_at (b, idx, buf, sizeof (buf));
20 if (!memcmp (buf, "LX", 2) || !memcmp (buf, "LE", 2)) {
21 return true;
22 }
23 }
24 }
25 return false;
26 }
27
load_buffer(RBinFile * bf,void ** bin_obj,RBuffer * buf,ut64 loadaddr,Sdb * sdb)28 static bool load_buffer(RBinFile *bf, void **bin_obj, RBuffer *buf, ut64 loadaddr, Sdb *sdb) {
29 r_return_val_if_fail (bf && bin_obj && buf, false);
30 r_bin_le_obj_t *res = r_bin_le_new_buf (buf);
31 if (res) {
32 *bin_obj = res;
33 return true;
34 }
35 return false;
36 }
37
destroy(RBinFile * bf)38 static void destroy(RBinFile *bf) {
39 r_bin_le_free (bf->o->bin_obj);
40 }
41
header(RBinFile * bf)42 static void header(RBinFile *bf) {
43 r_return_if_fail (bf && bf->rbin && bf->o && bf->o->bin_obj);
44 RBin *rbin = bf->rbin;
45 r_bin_le_obj_t *bin = bf->o->bin_obj;
46 LE_image_header *h = bin->header;
47 PrintfCallback p = rbin->cb_printf;
48 if (!h || !p) {
49 return;
50 }
51 p ("Signature: %2s\n", h->magic);
52 p ("Byte Order: %s\n", h->border ? "Big" : "Little");
53 p ("Word Order: %s\n", h->worder ? "Big" : "Little");
54 p ("Format Level: %u\n", h->level);
55 p ("CPU: %s\n", bin->cpu);
56 p ("OS: %s\n", bin->os);
57 p ("Version: %u\n", h->ver);
58 p ("Flags: 0x%04x\n", h->mflags);
59 p ("Pages: %u\n", h->mpages);
60 p ("InitialEipObj: %u\n", h->startobj);
61 p ("InitialEip: 0x%04x\n", h->eip);
62 p ("InitialStackObj: %u\n", h->stackobj);
63 p ("InitialEsp: 0x%04x\n", h->esp);
64 p ("Page Size: 0x%04x\n", h->pagesize);
65 if (bin->is_le) {
66 p ("Last Page Size: 0x%04x\n", h->pageshift);
67 } else {
68 p ("Page Shift: 0x%04x\n", h->pageshift);
69 }
70 p ("Fixup Size: 0x%04x\n", h->fixupsize);
71 p ("Fixup Checksum: 0x%04x\n", h->fixupsum);
72 p ("Loader Size: 0x%04x\n", h->ldrsize);
73 p ("Loader Checksum: 0x%04x\n", h->ldrsum);
74 p ("Obj Table: 0x%04x\n", h->objtab);
75 p ("Obj Count: %u\n", h->objcnt);
76 p ("Obj Page Map: 0x%04x\n", h->objmap);
77 p ("Obj Iter Data Map: 0x%04x\n", h->itermap);
78 p ("Resource Table: 0x%04x\n", h->rsrctab);
79 p ("Resource Count: %u\n", h->rsrccnt);
80 p ("Resident Name Table: 0x%04x\n", h->restab);
81 p ("Entry Table: 0x%04x\n", h->enttab);
82 p ("Directives Table: 0x%04x\n", h->dirtab);
83 p ("Directives Count: %u\n", h->dircnt);
84 p ("Fixup Page Table: 0x%04x\n", h->fpagetab);
85 p ("Fixup Record Table: 0x%04x\n", h->frectab);
86 p ("Import Module Name Table: 0x%04x\n", h->impmod);
87 p ("Import Module Name Count: %u\n", h->impmodcnt);
88 p ("Import Procedure Name Table: 0x%04x\n", h->impproc);
89 p ("Per-Page Checksum Table: 0x%04x\n", h->pagesum);
90 p ("Enumerated Data Pages: 0x%04x\n", h->datapage);
91 p ("Number of preload pages: %u\n", h->preload);
92 p ("Non-resident Names Table: 0x%04x\n", h->nrestab);
93 p ("Size Non-resident Names: %u\n", h->cbnrestab);
94 p ("Checksum Non-resident Names: 0x%04x\n", h->nressum);
95 p ("Autodata Obj: %u\n", h->autodata);
96 p ("Debug Info: 0x%04x\n", h->debuginfo);
97 p ("Debug Length: 0x%04x\n", h->debuglen);
98 p ("Preload pages: %u\n", h->instpreload);
99 p ("Demand pages: %u\n", h->instdemand);
100 p ("Heap Size: 0x%04x\n", h->heapsize);
101 p ("Stack Size: 0x%04x\n", h->stacksize);
102 }
103
sections(RBinFile * bf)104 static RList *sections(RBinFile *bf) {
105 return r_bin_le_get_sections (bf->o->bin_obj);
106 }
107
entries(RBinFile * bf)108 static RList *entries(RBinFile *bf) {
109 return r_bin_le_get_entrypoints (bf->o->bin_obj);
110 }
111
symbols(RBinFile * bf)112 static RList *symbols(RBinFile *bf) {
113 return r_bin_le_get_symbols (bf->o->bin_obj);
114 }
115
imports(RBinFile * bf)116 static RList *imports(RBinFile *bf) {
117 return r_bin_le_get_imports (bf->o->bin_obj);
118 }
119
libs(RBinFile * bf)120 static RList *libs(RBinFile *bf) {
121 return r_bin_le_get_libs (bf->o->bin_obj);
122 }
123
relocs(RBinFile * bf)124 static RList *relocs(RBinFile *bf) {
125 return r_bin_le_get_relocs (bf->o->bin_obj);
126 }
127
info(RBinFile * bf)128 static RBinInfo *info(RBinFile *bf) {
129 RBinInfo *info = R_NEW0 (RBinInfo);
130 if (info) {
131 r_bin_le_obj_t *bin = bf->o->bin_obj;
132 LE_image_header *h = bin->header;
133 info->bits = 32;
134 info->type = strdup (bin->type);
135 info->cpu = strdup (bin->cpu);
136 info->os = strdup (bin->os);
137 info->arch = strdup (bin->arch);
138 info->file = strdup (r_str_get (bin->filename));
139 info->big_endian = h->worder;
140 info->has_va = true;
141 info->baddr = 0;
142 }
143 return info;
144 }
145
146 RBinPlugin r_bin_plugin_le = {
147 .name = "le",
148 .desc = "LE/LX format r2 plugin",
149 .author = "GustavoLCR",
150 .license = "LGPL3",
151 .check_buffer = &check_buffer,
152 .load_buffer = &load_buffer,
153 .destroy = &destroy,
154 .info = &info,
155 .header = &header,
156 .sections = §ions,
157 .entries = &entries,
158 .symbols = &symbols,
159 .imports = &imports,
160 .libs = &libs,
161 .relocs = &relocs,
162 .minstrlen = 4
163 // .regstate = ®state
164 };
165
166 #ifndef R2_PLUGIN_INCORE
167 R_API RLibStruct radare_plugin = {
168 .type = R_LIB_TYPE_BIN,
169 .data = &r_bin_plugin_le,
170 .version = R2_VERSION
171 };
172 #endif
173