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 = &sections,
157 	.entries = &entries,
158 	.symbols = &symbols,
159 	.imports = &imports,
160 	.libs = &libs,
161 	.relocs = &relocs,
162 	.minstrlen = 4
163 	// .regstate = &regstate
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