1 /* radare - LGPL - Copyright 2009-2019 - GustavoLCR, nibble, pancake, alvarofe */
2 
3 #include <r_bin.h>
4 #include "../i/private.h"
5 #include "../format/ne/ne.h"
6 
check_buffer(RBuffer * b)7 static bool check_buffer(RBuffer *b) {
8 	ut64 length = r_buf_size (b);
9 	if (length <= 0x3d) {
10 		return false;
11 	}
12 	ut16 idx = r_buf_read_le16_at (b, 0x3c);
13 	if ((ut64)idx + 26 < length) {
14 		ut8 buf[2];
15 		r_buf_read_at (b, 0, buf, sizeof (buf));
16 		if (!memcmp (buf, "MZ", 2)) {
17 			r_buf_read_at (b, idx, buf, sizeof (buf));
18 			if (!memcmp (buf, "NE", 2)) {
19 				return true;
20 			}
21 		}
22 	}
23 	return false;
24 }
25 
load_buffer(RBinFile * bf,void ** bin_obj,RBuffer * buf,ut64 loadaddr,Sdb * sdb)26 static bool load_buffer(RBinFile *bf, void **bin_obj, RBuffer *buf, ut64 loadaddr, Sdb *sdb) {
27 	r_return_val_if_fail (bf && bin_obj && buf, false);
28 	r_bin_ne_obj_t *res = r_bin_ne_new_buf (buf, bf->rbin->verbose);
29 	if (res) {
30 		*bin_obj = res;
31 		return true;
32 	}
33 	return false;
34 }
35 
destroy(RBinFile * bf)36 static void destroy (RBinFile *bf) {
37 	r_bin_ne_free (bf->o->bin_obj);
38 }
39 
header(RBinFile * bf)40 static void header(RBinFile *bf) {
41 	struct r_bin_t *rbin = bf->rbin;
42 	r_bin_ne_obj_t *ne = bf->o->bin_obj;
43 	rbin->cb_printf ("Signature: NE\n");
44 	rbin->cb_printf ("MajLinkerVersion: %d\n", ne->ne_header->MajLinkerVersion);
45 	rbin->cb_printf ("MinLinkerVersion: %d\n", ne->ne_header->MinLinkerVersion);
46 	rbin->cb_printf ("EntryTableOffset: 0x%04x\n", ne->ne_header->EntryTableOffset);
47 	rbin->cb_printf ("EntryTableLength: %d\n", ne->ne_header->EntryTableLength);
48 	rbin->cb_printf ("FileLoadCRC: %08x\n", ne->ne_header->FileLoadCRC);
49 	rbin->cb_printf ("ProgFlags: %d\n", ne->ne_header->ProgFlags);
50 	rbin->cb_printf ("ApplFlags: %d\n", ne->ne_header->ApplFlags);
51 	rbin->cb_printf ("AutoDataSegIndex: %d\n", ne->ne_header->AutoDataSegIndex);
52 	rbin->cb_printf ("InitHeapSize: %d\n", ne->ne_header->InitHeapSize);
53 	rbin->cb_printf ("InitStackSize: %d\n", ne->ne_header->InitStackSize);
54 	rbin->cb_printf ("EntryPointCSIndex: %d\n", ne->ne_header->csEntryPoint);
55 	rbin->cb_printf ("EntryPointIPOff: 0x%04x\n", ne->ne_header->ipEntryPoint);
56 	rbin->cb_printf ("InitStack: %d\n", ne->ne_header->InitStack);
57 	rbin->cb_printf ("SegCount: %d\n", ne->ne_header->SegCount);
58 	rbin->cb_printf ("ModuleRefsCount: %d\n", ne->ne_header->ModRefs);
59 	rbin->cb_printf ("NonResNamesTblSiz: 0x%x\n", ne->ne_header->NoResNamesTabSiz);
60 	rbin->cb_printf ("SegTableOffset: 0x%x\n", ne->ne_header->SegTableOffset);
61 	rbin->cb_printf ("ResourceTblOff: 0x%x\n", ne->ne_header->ResTableOffset);
62 	rbin->cb_printf ("ResidentNameTblOff: 0x%x\n", ne->ne_header->ResidNamTable);
63 	rbin->cb_printf ("ModuleRefTblOff: 0x%x\n", ne->ne_header->ModRefTable);
64 	rbin->cb_printf ("ImportNameTblOff: 0x%x\n", ne->ne_header->ImportNameTable);
65 	rbin->cb_printf ("OffStartNonResTab: %d\n", ne->ne_header->OffStartNonResTab);
66 	rbin->cb_printf ("MovEntryCount: %d\n", ne->ne_header->MovEntryCount);
67 	rbin->cb_printf ("FileAlnSzShftCnt: %d\n", ne->ne_header->FileAlnSzShftCnt);
68 	rbin->cb_printf ("nResTabEntries: %d\n", ne->ne_header->nResTabEntries);
69 	rbin->cb_printf ("OS: %s\n", ne->os);
70 	rbin->cb_printf ("OS2EXEFlags: %x\n", ne->ne_header->OS2EXEFlags);
71 	rbin->cb_printf ("retThunkOffset: %d\n", ne->ne_header->retThunkOffset);
72 	rbin->cb_printf ("segRefThunksOff: %d\n", ne->ne_header->segrefthunksoff);
73 	rbin->cb_printf ("mincodeswap: %d\n", ne->ne_header->mincodeswap);
74 	rbin->cb_printf ("winver: %d.%d\n", ne->ne_header->expctwinver[1], ne->ne_header->expctwinver[0]);
75 }
76 
info(RBinFile * bf)77 RBinInfo *info(RBinFile *bf) {
78 	r_bin_ne_obj_t *ne = bf->o->bin_obj;
79 	RBinInfo *i = R_NEW0 (RBinInfo);
80 	if (i) {
81 		i->bits = 16;
82 		i->arch = strdup ("x86");
83 		i->os = strdup (ne->os);
84 		i->claimed_checksum = r_str_newf ("%08x", ne->ne_header->FileLoadCRC);
85 	}
86 	return i;
87 }
88 
entries(RBinFile * bf)89 RList *entries(RBinFile *bf) {
90 	return r_bin_ne_get_entrypoints (bf->o->bin_obj);
91 }
92 
symbols(RBinFile * bf)93 RList *symbols(RBinFile *bf) {
94 	return r_bin_ne_get_symbols (bf->o->bin_obj);
95 }
96 
imports(RBinFile * bf)97 RList *imports(RBinFile *bf) {
98 	return r_bin_ne_get_imports (bf->o->bin_obj);
99 }
100 
sections(RBinFile * bf)101 RList *sections(RBinFile *bf) {
102 	return r_bin_ne_get_segments (bf->o->bin_obj);
103 }
104 
relocs(RBinFile * bf)105 RList *relocs(RBinFile *bf) {
106 	return r_bin_ne_get_relocs (bf->o->bin_obj);
107 }
108 
109 RBinPlugin r_bin_plugin_ne = {
110 	.name = "ne",
111 	.desc = "NE format r2 plugin",
112 	.author = "GustavoLCR",
113 	.license = "LGPL3",
114 	.check_buffer = &check_buffer,
115 	.load_buffer = &load_buffer,
116 	.destroy = &destroy,
117 	.header = &header,
118 	.info = &info,
119 	.entries = &entries,
120 	.sections = &sections,
121 	.symbols = &symbols,
122 	.imports = &imports,
123 	.relocs = &relocs,
124 	.minstrlen = 4
125 };
126 
127 #ifndef R2_PLUGIN_INCORE
128 R_API RLibStruct radare_plugin = {
129 	.type = R_LIB_TYPE_BIN,
130 	.data = &r_bin_plugin_ne,
131 	.version = R2_VERSION
132 };
133 #endif
134