1 /* radare - LGPL - Copyright 2009-2019 - nibble, pancake, alvarofe */
2 
3 #include "bin_pe.inc"
4 
check_buffer(RBuffer * b)5 static bool check_buffer(RBuffer *b) {
6 	ut64 length = r_buf_size (b);
7 	if (length <= 0x3d) {
8 		return false;
9 	}
10 	ut16 idx = r_buf_read_le16_at (b, 0x3c);
11 	if (idx + 26 < length) {
12 		/* Here PE signature for usual PE files
13 		 * and PL signature for Phar Lap TNT DOS extender 32bit executables
14 		 */
15 		ut8 buf[2];
16 		r_buf_read_at (b, 0, buf, sizeof (buf));
17 		if (!memcmp (buf, "MZ", 2)) {
18 			r_buf_read_at (b, idx, buf, sizeof (buf));
19 			// TODO: Add one more indicator, to prevent false positives
20 			if (!memcmp (buf, "PL", 2)) {
21 				return true;
22 			}
23 			if (!memcmp (buf, "PE", 2)) {
24 				r_buf_read_at (b, idx + 0x18, buf, sizeof (buf));
25 				return !memcmp (buf, "\x0b\x01", 2);
26 			}
27 		}
28 	}
29 	return false;
30 }
31 
32 /* inspired in http://www.phreedom.org/solar/code/tinype/tiny.97/tiny.asm */
create(RBin * bin,const ut8 * code,int codelen,const ut8 * data,int datalen,RBinArchOptions * opt)33 static RBuffer* create(RBin* bin, const ut8 *code, int codelen, const ut8 *data, int datalen, RBinArchOptions *opt) {
34 	ut32 hdrsize, p_start, p_opthdr, p_sections, p_lsrlc, n;
35 	ut32 baddr = 0x400000;
36 	RBuffer *buf = r_buf_new ();
37 
38 #define B(x,y) r_buf_append_bytes(buf,(const ut8*)(x),y)
39 #define H(x) r_buf_append_ut16(buf,x)
40 #define D(x) r_buf_append_ut32(buf,x)
41 #define Z(x) r_buf_append_nbytes(buf,x)
42 #define W(x,y,z) r_buf_write_at(buf,x,(const ut8*)(y),z)
43 #define WZ(x,y) p_tmp=r_buf_size (buf);Z(x);W(p_tmp,y,strlen(y))
44 
45 	B ("MZ\x00\x00", 4); // MZ Header
46 	B ("PE\x00\x00", 4); // PE Signature
47 	H (0x14c); // Machine
48 	H (1); // Number of sections
49 	D (0); // Timestamp (Unused)
50 	D (0); // PointerToSymbolTable (Unused)
51 	D (0); // NumberOfSymbols (Unused)
52 	p_lsrlc = r_buf_size (buf);
53 	H (-1); // SizeOfOptionalHeader
54 	H (0x103); // Characteristics
55 
56 	/* Optional Header */
57 	p_opthdr = r_buf_size (buf);
58 	H (0x10b); // Magic
59 	B ("\x08\x00", 2); // (Major/Minor)LinkerVersion (Unused)
60 
61 	p_sections = r_buf_size (buf);
62 	n = p_sections - p_opthdr;
63 	W (p_lsrlc, &n, 2); // Fix SizeOfOptionalHeader
64 
65 	/* Sections */
66 	p_start = 0x7c; //HACK: Headersize
67 	hdrsize = 0x7c;
68 
69 	D (R_ROUND (codelen, 4)); // SizeOfCode (Unused)
70 	D (0); // SizeOfInitializedData (Unused)
71 	D (codelen); // codesize
72 	D (p_start);
73 	D (codelen);
74 	D (p_start);
75 	D (baddr); // ImageBase
76 	D (4); // SectionAlignment
77 	D (4); // FileAlignment
78 	H (4); // MajorOperatingSystemVersion (Unused)
79 	H (0); // MinorOperatingSystemVersion (Unused)
80 	H (0); // MajorImageVersion (Unused)
81 	H (0); // MinorImageVersion (Unused)
82 	H (4); // MajorSubsystemVersion
83 	H (0); // MinorSubsystemVersion (Unused)
84 	D (0); // Win32VersionValue (Unused)
85 	D ((R_ROUND (hdrsize, 4)) + (R_ROUND (codelen, 4))); // SizeOfImage
86 	D (R_ROUND (hdrsize, 4)); // SizeOfHeaders
87 	D (0); // CheckSum (Unused)
88 	H (2); // Subsystem (Win32 GUI)
89 	H (0x400); // DllCharacteristics (Unused)
90 	D (0x100000); // SizeOfStackReserve (Unused)
91 	D (0x1000); // SizeOfStackCommit
92 	D (0x100000); // SizeOfHeapReserve
93 	D (0x1000); // SizeOfHeapCommit (Unused)
94 	D (0); // LoaderFlags (Unused)
95 	D (0); // NumberOfRvaAndSizes (Unused)
96 	B (code, codelen);
97 
98 	if (data && datalen>0) {
99 		//ut32 data_section = buf->length;
100 		eprintf ("Warning: DATA section not support for PE yet\n");
101 		B (data, datalen);
102 	}
103 	return buf;
104 }
105 
signature(RBinFile * bf,bool json)106 static char *signature (RBinFile *bf, bool json) {
107 	if (!bf || !bf->o || !bf->o->bin_obj) {
108 		return NULL;
109 	}
110 	struct PE_ (r_bin_pe_obj_t) * bin = bf->o->bin_obj;
111 	if (json) {
112 		PJ *pj = r_pkcs7_cms_json (bin->cms);
113 		if (pj) {
114 			return pj_drain (pj);
115 		}
116 		return strdup ("{}");
117 	}
118 	return r_pkcs7_cms_to_string (bin->cms);
119 }
120 
fields(RBinFile * bf)121 static RList *fields(RBinFile *bf) {
122 	RList *ret  = r_list_new ();
123 	if (!ret) {
124 		return NULL;
125 	}
126 
127 	#define ROWL(nam,siz,val,fmt) \
128 	r_list_append (ret, r_bin_field_new (addr, addr, siz, nam, sdb_fmt ("0x%08x", val), fmt, false));
129 
130 	struct PE_(r_bin_pe_obj_t) * bin = bf->o->bin_obj;
131 	ut64 addr = bin->rich_header_offset ? bin->rich_header_offset : 128;
132 
133 	RListIter *it;
134 	Pe_image_rich_entry *rich;
135 	r_list_foreach (bin->rich_entries, it, rich) {
136 		r_list_append (ret, r_bin_field_new (addr, addr, 0, "RICH_ENTRY_NAME", strdup (rich->productName), "s", false));
137 		ROWL ("RICH_ENTRY_ID", 2, rich->productId, "x"); addr += 2;
138 		ROWL ("RICH_ENTRY_VERSION", 2, rich->minVersion, "x"); addr += 2;
139 		ROWL ("RICH_ENTRY_TIMES", 4, rich->timesUsed, "x"); addr += 4;
140 	}
141 
142 	ROWL ("Signature", 4, bin->nt_headers->Signature, "x"); addr += 4;
143 	ROWL ("Machine", 2, bin->nt_headers->file_header.Machine, "x"); addr += 2;
144 	ROWL ("NumberOfSections", 2, bin->nt_headers->file_header.NumberOfSections, "x"); addr += 2;
145 	ROWL ("TimeDateStamp", 4, bin->nt_headers->file_header.TimeDateStamp, "x"); addr += 4;
146 	ROWL ("PointerToSymbolTable", 4, bin->nt_headers->file_header.PointerToSymbolTable, "x"); addr += 4;
147 	ROWL ("NumberOfSymbols ", 4, bin->nt_headers->file_header.NumberOfSymbols, "x"); addr += 4;
148 	ROWL ("SizeOfOptionalHeader", 2, bin->nt_headers->file_header.SizeOfOptionalHeader, "x"); addr += 2;
149 	ROWL ("Characteristics", 2, bin->nt_headers->file_header.Characteristics, "x"); addr += 2;
150 	ROWL ("Magic", 2, bin->nt_headers->optional_header.Magic, "x"); addr += 2;
151 	ROWL ("MajorLinkerVersion", 1, bin->nt_headers->optional_header.MajorLinkerVersion, "x"); addr += 1;
152 	ROWL ("MinorLinkerVersion", 1, bin->nt_headers->optional_header.MinorLinkerVersion, "x"); addr += 1;
153 	ROWL ("SizeOfCode", 4, bin->nt_headers->optional_header.SizeOfCode, "x"); addr += 4;
154 	ROWL ("SizeOfInitializedData", 4, bin->nt_headers->optional_header.SizeOfInitializedData, "x"); addr += 4;
155 	ROWL ("SizeOfUninitializedData", 4, bin->nt_headers->optional_header.SizeOfUninitializedData, "x"); addr += 4;
156 	ROWL ("AddressOfEntryPoint", 4, bin->nt_headers->optional_header.AddressOfEntryPoint, "x"); addr += 4;
157 	ROWL ("BaseOfCode", 4, bin->nt_headers->optional_header.BaseOfCode, "x"); addr += 4;
158 	ROWL ("BaseOfData", 4, bin->nt_headers->optional_header.BaseOfData, "x"); addr += 4;
159 	ROWL ("ImageBase", 4, bin->nt_headers->optional_header.ImageBase, "x"); addr += 4;
160 	ROWL ("SectionAlignment", 4, bin->nt_headers->optional_header.SectionAlignment, "x"); addr += 4;
161 	ROWL ("FileAlignment", 4, bin->nt_headers->optional_header.FileAlignment, "x"); addr += 4;
162 	ROWL ("MajorOperatingSystemVersion", 2, bin->nt_headers->optional_header.MajorOperatingSystemVersion, "x"); addr += 2;
163 	ROWL ("MinorOperatingSystemVersion", 2, bin->nt_headers->optional_header.MinorOperatingSystemVersion, "x"); addr += 2;
164 	ROWL ("MajorImageVersion", 2, bin->nt_headers->optional_header.MajorImageVersion, "x"); addr += 2;
165 	ROWL ("MinorImageVersion", 2, bin->nt_headers->optional_header.MinorImageVersion, "x"); addr += 2;
166 	ROWL ("MajorSubsystemVersion", 2, bin->nt_headers->optional_header.MajorSubsystemVersion, "x"); addr += 2;
167 	ROWL ("MinorSubsystemVersion", 2, bin->nt_headers->optional_header.MinorSubsystemVersion, "x"); addr += 2;
168 	ROWL ("Win32VersionValue", 4, bin->nt_headers->optional_header.Win32VersionValue, "x"); addr += 4;
169 	ROWL ("SizeOfImage", 4, bin->nt_headers->optional_header.SizeOfImage, "x"); addr += 4;
170 	ROWL ("SizeOfHeaders", 4, bin->nt_headers->optional_header.SizeOfHeaders, "x"); addr += 4;
171 	ROWL ("CheckSum", 4, bin->nt_headers->optional_header.CheckSum, "x"); addr += 4;
172 	ROWL ("Subsystem",24, bin->nt_headers->optional_header.Subsystem, "x"); addr += 2;
173 	ROWL ("DllCharacteristics", 2, bin->nt_headers->optional_header.DllCharacteristics, "x"); addr += 2;
174 	ROWL ("SizeOfStackReserve", 4, bin->nt_headers->optional_header.SizeOfStackReserve, "x"); addr += 4;
175 	ROWL ("SizeOfStackCommit", 4, bin->nt_headers->optional_header.SizeOfStackCommit, "x"); addr += 4;
176 	ROWL ("SizeOfHeapReserve", 4, bin->nt_headers->optional_header.SizeOfHeapReserve, "x"); addr += 4;
177 	ROWL ("SizeOfHeapCommit", 4, bin->nt_headers->optional_header.SizeOfHeapCommit, "x"); addr += 4;
178 	ROWL ("LoaderFlags", 4, bin->nt_headers->optional_header.LoaderFlags, "x"); addr += 4;
179 	ROWL ("NumberOfRvaAndSizes", 4, bin->nt_headers->optional_header.NumberOfRvaAndSizes, "x"); addr += 4;
180 
181 	int i;
182 	ut64 tmp = addr;
183 	for (i = 0; i < PE_IMAGE_DIRECTORY_ENTRIES - 1; i++) {
184 		if (bin->nt_headers->optional_header.DataDirectory[i].Size > 0) {
185 			addr = tmp + i*8;
186 			switch (i) {
187 			case PE_IMAGE_DIRECTORY_ENTRY_EXPORT:
188 				ROWL ("IMAGE_DIRECTORY_ENTRY_EXPORT", 4, \
189 				bin->nt_headers->optional_header.DataDirectory[i].VirtualAddress, "x");
190 				addr += 4;
191 				ROWL ("SIZE_IMAGE_DIRECTORY_ENTRY_EXPORT", 4, \
192 				bin->nt_headers->optional_header.DataDirectory[i].Size, "x");
193 				break;
194 			case PE_IMAGE_DIRECTORY_ENTRY_IMPORT:
195 				ROWL ("IMAGE_DIRECTORY_ENTRY_IMPORT", 4, \
196 				bin->nt_headers->optional_header.DataDirectory[i].VirtualAddress, "x");
197 				addr += 4;
198 				ROWL ("SIZE_IMAGE_DIRECTORY_ENTRY_IMPORT", 4, \
199 				bin->nt_headers->optional_header.DataDirectory[i].Size, "x");
200 				break;
201 			case PE_IMAGE_DIRECTORY_ENTRY_RESOURCE:
202 				ROWL ("IMAGE_DIRECTORY_ENTRY_RESOURCE", 4, \
203 				bin->nt_headers->optional_header.DataDirectory[i].VirtualAddress, "x");
204 				addr += 4;
205 				ROWL ("SIZE_IMAGE_DIRECTORY_ENTRY_RESOURCE", 4, \
206 				bin->nt_headers->optional_header.DataDirectory[i].Size, "x");
207 				break;
208 			case PE_IMAGE_DIRECTORY_ENTRY_EXCEPTION:
209 				ROWL ("IMAGE_DIRECTORY_ENTRY_EXCEPTION", 4, \
210 				bin->nt_headers->optional_header.DataDirectory[i].VirtualAddress, "x");
211 				addr += 4;
212 				ROWL ("SIZE_IMAGE_DIRECTORY_ENTRY_EXCEPTION", 4, \
213 				bin->nt_headers->optional_header.DataDirectory[i].Size, "x");
214 				break;
215 			case PE_IMAGE_DIRECTORY_ENTRY_SECURITY:
216 				ROWL ("IMAGE_DIRECTORY_ENTRY_SECURITY", 4, \
217 				bin->nt_headers->optional_header.DataDirectory[i].VirtualAddress, "x");
218 				addr += 4;
219 				ROWL ("SIZE_IMAGE_DIRECTORY_ENTRY_SECURITY", 4, \
220 				bin->nt_headers->optional_header.DataDirectory[i].Size, "x");
221 				break;
222 			case PE_IMAGE_DIRECTORY_ENTRY_BASERELOC:
223 				ROWL ("IMAGE_DIRECTORY_ENTRY_BASERELOC", 4, \
224 				bin->nt_headers->optional_header.DataDirectory[i].VirtualAddress, "x");
225 				addr += 4;
226 				ROWL ("SIZE_IMAGE_DIRECTORY_ENTRY_BASERELOC", 4, \
227 				bin->nt_headers->optional_header.DataDirectory[i].Size, "x");
228 				break;
229 			case PE_IMAGE_DIRECTORY_ENTRY_DEBUG:
230 				ROWL ("IMAGE_DIRECTORY_ENTRY_DEBUG", 4, \
231 				bin->nt_headers->optional_header.DataDirectory[i].VirtualAddress, "x");
232 				addr += 4;
233 				ROWL ("SIZE_IMAGE_DIRECTORY_ENTRY_DEBUG", 4, \
234 				bin->nt_headers->optional_header.DataDirectory[i].Size, "x");
235 				break;
236 			case PE_IMAGE_DIRECTORY_ENTRY_COPYRIGHT:
237 				ROWL ("IMAGE_DIRECTORY_ENTRY_COPYRIGHT", 4, \
238 				bin->nt_headers->optional_header.DataDirectory[i].VirtualAddress, "x");
239 				addr += 4;
240 				ROWL ("SIZE_IMAGE_DIRECTORY_ENTRY_COPYRIGHT", 4, \
241 				bin->nt_headers->optional_header.DataDirectory[i].Size, "x");
242 				break;
243 			case PE_IMAGE_DIRECTORY_ENTRY_GLOBALPTR:
244 				ROWL ("IMAGE_DIRECTORY_ENTRY_GLOBALPTR", 4, \
245 				bin->nt_headers->optional_header.DataDirectory[i].VirtualAddress, "x");
246 				addr += 4;
247 				ROWL ("SIZE_IMAGE_DIRECTORY_ENTRY_GLOBALPTR", 4, \
248 				bin->nt_headers->optional_header.DataDirectory[i].Size, "x");
249 				break;
250 			case PE_IMAGE_DIRECTORY_ENTRY_TLS:
251 				ROWL ("IMAGE_DIRECTORY_ENTRY_TLS", 4, \
252 				bin->nt_headers->optional_header.DataDirectory[i].VirtualAddress, "x");
253 				addr += 4;
254 				ROWL ("SIZE_IMAGE_DIRECTORY_ENTRY_TLS", 4, \
255 				bin->nt_headers->optional_header.DataDirectory[i].Size, "x");
256 				break;
257 			case PE_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG:
258 				ROWL ("IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG", 4, \
259 				bin->nt_headers->optional_header.DataDirectory[i].VirtualAddress, "x");
260 				addr += 4;
261 				ROWL ("SIZE_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG", 4, \
262 				bin->nt_headers->optional_header.DataDirectory[i].Size, "x");
263 				break;
264 			case PE_IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT:
265 				ROWL ("IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT", 4, \
266 				bin->nt_headers->optional_header.DataDirectory[i].VirtualAddress, "x");
267 				addr += 4;
268 				ROWL ("SIZE_IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT", 4, \
269 				bin->nt_headers->optional_header.DataDirectory[i].Size, "x");
270 				break;
271 			case PE_IMAGE_DIRECTORY_ENTRY_IAT:
272 				ROWL ("IMAGE_DIRECTORY_ENTRY_IAT", 4, \
273 				bin->nt_headers->optional_header.DataDirectory[i].VirtualAddress, "x");
274 				addr += 4;
275 				ROWL ("SIZE_IMAGE_DIRECTORY_ENTRY_IAT", 4, \
276 				bin->nt_headers->optional_header.DataDirectory[i].Size, "x");
277 				break;
278 			case PE_IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT:
279 				ROWL ("IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT", 4, \
280 				bin->nt_headers->optional_header.DataDirectory[i].VirtualAddress, "x");
281 				addr += 4;
282 				ROWL ("SIZE_IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT", 4, \
283 				bin->nt_headers->optional_header.DataDirectory[i].Size, "x");
284 				break;
285 			case PE_IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR:
286 				ROWL ("IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR", 4, \
287 				bin->nt_headers->optional_header.DataDirectory[i].VirtualAddress, "x");
288 				addr += 4;
289 				ROWL ("SIZE_IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR", 4, \
290 				bin->nt_headers->optional_header.DataDirectory[i].Size, "x");
291 				break;
292 			}
293 		}
294 	}
295 
296 	return ret;
297 }
298 
header(RBinFile * bf)299 static void header(RBinFile *bf) {
300 	struct PE_(r_bin_pe_obj_t) * bin = bf->o->bin_obj;
301 	struct r_bin_t *rbin = bf->rbin;
302 	rbin->cb_printf ("PE file header:\n");
303 	rbin->cb_printf ("IMAGE_NT_HEADERS\n");
304 	rbin->cb_printf ("  Signature : 0x%x\n", bin->nt_headers->Signature);
305 	rbin->cb_printf ("IMAGE_FILE_HEADERS\n");
306 	rbin->cb_printf ("  Machine : 0x%x\n", bin->nt_headers->file_header.Machine);
307 	rbin->cb_printf ("  NumberOfSections : 0x%x\n", bin->nt_headers->file_header.NumberOfSections);
308 	rbin->cb_printf ("  TimeDateStamp : 0x%x\n", bin->nt_headers->file_header.TimeDateStamp);
309 	rbin->cb_printf ("  PointerToSymbolTable : 0x%x\n", bin->nt_headers->file_header.PointerToSymbolTable);
310 	rbin->cb_printf ("  NumberOfSymbols : 0x%x\n", bin->nt_headers->file_header.NumberOfSymbols);
311 	rbin->cb_printf ("  SizeOfOptionalHeader : 0x%x\n", bin->nt_headers->file_header.SizeOfOptionalHeader);
312 	rbin->cb_printf ("  Characteristics : 0x%x\n", bin->nt_headers->file_header.Characteristics);
313 	rbin->cb_printf ("IMAGE_OPTIONAL_HEADERS\n");
314 	rbin->cb_printf ("  Magic : 0x%x\n", bin->nt_headers->optional_header.Magic);
315 	rbin->cb_printf ("  MajorLinkerVersion : 0x%x\n", bin->nt_headers->optional_header.MajorLinkerVersion);
316 	rbin->cb_printf ("  MinorLinkerVersion : 0x%x\n", bin->nt_headers->optional_header.MinorLinkerVersion);
317 	rbin->cb_printf ("  SizeOfCode : 0x%x\n", bin->nt_headers->optional_header.SizeOfCode);
318 	rbin->cb_printf ("  SizeOfInitializedData : 0x%x\n", bin->nt_headers->optional_header.SizeOfInitializedData);
319 	rbin->cb_printf ("  SizeOfUninitializedData : 0x%x\n", bin->nt_headers->optional_header.SizeOfUninitializedData);
320 	rbin->cb_printf ("  AddressOfEntryPoint : 0x%x\n", bin->nt_headers->optional_header.AddressOfEntryPoint);
321 	rbin->cb_printf ("  BaseOfCode : 0x%x\n", bin->nt_headers->optional_header.BaseOfCode);
322 	rbin->cb_printf ("  BaseOfData : 0x%x\n", bin->nt_headers->optional_header.BaseOfData);
323 	rbin->cb_printf ("  ImageBase : 0x%x\n", bin->nt_headers->optional_header.ImageBase);
324 	rbin->cb_printf ("  SectionAlignment : 0x%x\n", bin->nt_headers->optional_header.SectionAlignment);
325 	rbin->cb_printf ("  FileAlignment : 0x%x\n", bin->nt_headers->optional_header.FileAlignment);
326 	rbin->cb_printf ("  MajorOperatingSystemVersion : 0x%x\n", bin->nt_headers->optional_header.MajorOperatingSystemVersion);
327 	rbin->cb_printf ("  MinorOperatingSystemVersion : 0x%x\n", bin->nt_headers->optional_header.MinorOperatingSystemVersion);
328 	rbin->cb_printf ("  MajorImageVersion : 0x%x\n", bin->nt_headers->optional_header.MajorImageVersion);
329 	rbin->cb_printf ("  MinorImageVersion : 0x%x\n", bin->nt_headers->optional_header.MinorImageVersion);
330 	rbin->cb_printf ("  MajorSubsystemVersion : 0x%x\n", bin->nt_headers->optional_header.MajorSubsystemVersion);
331 	rbin->cb_printf ("  MinorSubsystemVersion : 0x%x\n", bin->nt_headers->optional_header.MinorSubsystemVersion);
332 	rbin->cb_printf ("  Win32VersionValue : 0x%x\n", bin->nt_headers->optional_header.Win32VersionValue);
333 	rbin->cb_printf ("  SizeOfImage : 0x%x\n", bin->nt_headers->optional_header.SizeOfImage);
334 	rbin->cb_printf ("  SizeOfHeaders : 0x%x\n", bin->nt_headers->optional_header.SizeOfHeaders);
335 	rbin->cb_printf ("  CheckSum : 0x%x\n", bin->nt_headers->optional_header.CheckSum);
336 	rbin->cb_printf ("  Subsystem : 0x%x\n", bin->nt_headers->optional_header.Subsystem);
337 	rbin->cb_printf ("  DllCharacteristics : 0x%x\n", bin->nt_headers->optional_header.DllCharacteristics);
338 	rbin->cb_printf ("  SizeOfStackReserve : 0x%x\n", bin->nt_headers->optional_header.SizeOfStackReserve);
339 	rbin->cb_printf ("  SizeOfStackCommit : 0x%x\n", bin->nt_headers->optional_header.SizeOfStackCommit);
340 	rbin->cb_printf ("  SizeOfHeapReserve : 0x%x\n", bin->nt_headers->optional_header.SizeOfHeapReserve);
341 	rbin->cb_printf ("  SizeOfHeapCommit : 0x%x\n", bin->nt_headers->optional_header.SizeOfHeapCommit);
342 	rbin->cb_printf ("  LoaderFlags : 0x%x\n", bin->nt_headers->optional_header.LoaderFlags);
343 	rbin->cb_printf ("  NumberOfRvaAndSizes : 0x%x\n", bin->nt_headers->optional_header.NumberOfRvaAndSizes);
344 	RListIter *it;
345 	Pe_image_rich_entry *entry;
346 	rbin->cb_printf ("RICH_FIELDS\n");
347 	r_list_foreach (bin->rich_entries, it, entry) {
348 		rbin->cb_printf ("  Product: %d Name: %s Version: %d Times: %d\n", entry->productId, entry->productName, entry->minVersion, entry->timesUsed);
349 	}
350 	int i;
351 	for (i = 0; i < PE_IMAGE_DIRECTORY_ENTRIES - 1; i++) {
352 		if (bin->nt_headers->optional_header.DataDirectory[i].Size > 0) {
353 			switch (i) {
354 			case PE_IMAGE_DIRECTORY_ENTRY_EXPORT:
355 				rbin->cb_printf ("IMAGE_DIRECTORY_ENTRY_EXPORT\n");
356 				break;
357 			case PE_IMAGE_DIRECTORY_ENTRY_IMPORT:
358 				rbin->cb_printf ("IMAGE_DIRECTORY_ENTRY_IMPORT\n");
359 				break;
360 			case PE_IMAGE_DIRECTORY_ENTRY_RESOURCE:
361 				rbin->cb_printf ("IMAGE_DIRECTORY_ENTRY_RESOURCE\n");
362 				break;
363 			case PE_IMAGE_DIRECTORY_ENTRY_EXCEPTION:
364 				rbin->cb_printf ("IMAGE_DIRECTORY_ENTRY_EXCEPTION\n");
365 				break;
366 			case PE_IMAGE_DIRECTORY_ENTRY_SECURITY:
367 				rbin->cb_printf ("IMAGE_DIRECTORY_ENTRY_SECURITY\n");
368 				break;
369 			case PE_IMAGE_DIRECTORY_ENTRY_BASERELOC:
370 				rbin->cb_printf ("IMAGE_DIRECTORY_ENTRY_BASERELOC\n");
371 				break;
372 			case PE_IMAGE_DIRECTORY_ENTRY_DEBUG:
373 				rbin->cb_printf ("IMAGE_DIRECTORY_ENTRY_DEBUG\n");
374 				break;
375 			case PE_IMAGE_DIRECTORY_ENTRY_COPYRIGHT:
376 				rbin->cb_printf ("IMAGE_DIRECTORY_ENTRY_COPYRIGHT\n");
377 				rbin->cb_printf ("IMAGE_DIRECTORY_ENTRY_ARCHITECTURE\n");
378 				break;
379 			case PE_IMAGE_DIRECTORY_ENTRY_GLOBALPTR:
380 				rbin->cb_printf ("IMAGE_DIRECTORY_ENTRY_GLOBALPTR\n");
381 				break;
382 			case PE_IMAGE_DIRECTORY_ENTRY_TLS:
383 				rbin->cb_printf ("IMAGE_DIRECTORY_ENTRY_TLS\n");
384 				break;
385 			case PE_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG:
386 				rbin->cb_printf ("IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG\n");
387 				break;
388 			case PE_IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT:
389 				rbin->cb_printf ("IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT\n");
390 				break;
391 			case PE_IMAGE_DIRECTORY_ENTRY_IAT:
392 				rbin->cb_printf ("IMAGE_DIRECTORY_ENTRY_IAT\n");
393 				break;
394 			case PE_IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT:
395 				rbin->cb_printf ("IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT\n");
396 				break;
397 			case PE_IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR:
398 				rbin->cb_printf ("IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR\n");
399 				break;
400 			}
401 			rbin->cb_printf ("  VirtualAddress : 0x%x\n", bin->nt_headers->optional_header.DataDirectory[i].VirtualAddress);
402 			rbin->cb_printf ("  Size : 0x%x\n", bin->nt_headers->optional_header.DataDirectory[i].Size);
403 		}
404 	}
405 }
406 
407 extern struct r_bin_write_t r_bin_write_pe;
408 
409 RBinPlugin r_bin_plugin_pe = {
410 	.name = "pe",
411 	.desc = "PE bin plugin",
412 	.license = "LGPL3",
413 	.get_sdb = &get_sdb,
414 	.load_buffer = &load_buffer,
415 	.destroy = &destroy,
416 	.check_buffer = &check_buffer,
417 	.baddr = &baddr,
418 	.binsym = &binsym,
419 	.entries = &entries,
420 	.sections = &sections,
421 	.signature = &signature,
422 	.symbols = &symbols,
423 	.imports = &imports,
424 	.info = &info,
425 	.header = &header,
426 	.fields = &fields,
427 	.libs = &libs,
428 	.relocs = &relocs,
429 	.minstrlen = 4,
430 	.create = &create,
431 	.get_vaddr = &get_vaddr,
432 	.write = &r_bin_write_pe,
433 	.hashes = &compute_hashes
434 };
435 
436 #ifndef R2_PLUGIN_INCORE
437 R_API RLibStruct radare_plugin = {
438 	.type = R_LIB_TYPE_BIN,
439 	.data = &r_bin_plugin_pe,
440 	.version = R2_VERSION
441 };
442 #endif
443