1 /* radare - LGPL - Copyright 2015-2019 - ampotos, pancake */
2 
3 #include <r_types.h>
4 #include <r_util.h>
5 #include <r_lib.h>
6 #include <r_bin.h>
7 #include "omf/omf.h"
8 
load_buffer(RBinFile * bf,void ** bin_obj,RBuffer * b,ut64 loadaddr,Sdb * sdb)9 static bool load_buffer (RBinFile *bf, void **bin_obj, RBuffer *b, ut64 loadaddr, Sdb *sdb) {
10 	ut64 size;
11 	const ut8 *buf = r_buf_data (b, &size);
12 	r_return_val_if_fail (buf, false);
13 	*bin_obj = r_bin_internal_omf_load (buf, size);
14 	return *bin_obj != NULL;
15 }
16 
destroy(RBinFile * bf)17 static void destroy(RBinFile *bf) {
18 	r_bin_free_all_omf_obj (bf->o->bin_obj);
19 	bf->o->bin_obj = NULL;
20 }
21 
check_buffer(RBuffer * b)22 static bool check_buffer(RBuffer *b) {
23 	int i;
24 	ut8 ch;
25 	if (r_buf_read_at (b, 0, &ch, 1) != 1) {
26 		return false;
27 	}
28 	if (ch != 0x80 && ch != 0x82) {
29 		return false;
30 	}
31 	ut16 rec_size = r_buf_read_le16_at (b, 1);
32 	ut8 str_size; (void)r_buf_read_at (b, 3, &str_size, 1);
33 	ut64 length = r_buf_size (b);
34 	if (str_size + 2 != rec_size || length < rec_size + 3) {
35 		return false;
36 	}
37 	// check that the string is ASCII
38 	for (i = 4; i < str_size + 4; i++) {
39 		if (r_buf_read_at (b, i, &ch, 1) != 1) {
40 			break;
41 		}
42 		if (ch > 0x7f) {
43 			return false;
44 		}
45 	}
46 	const ut8 *buf = r_buf_data (b, NULL);
47 	if (buf == NULL) {
48 		// hackaround until we make this plugin not use RBuf.data
49 		ut8 buf[1024] = {0};
50 		r_buf_read_at (b, 0, buf, sizeof (buf));
51 		return r_bin_checksum_omf_ok (buf, sizeof (buf));
52 	}
53 	r_return_val_if_fail (buf, false);
54 	return r_bin_checksum_omf_ok (buf, length);
55 }
56 
baddr(RBinFile * bf)57 static ut64 baddr(RBinFile *bf) {
58 	return OMF_BASE_ADDR;
59 }
60 
entries(RBinFile * bf)61 static RList *entries(RBinFile *bf) {
62 	RList *ret;
63 	RBinAddr *addr;
64 
65 	if (!(ret = r_list_newf (free))) {
66 		return NULL;
67 	}
68 	if (!(addr = R_NEW0 (RBinAddr))) {
69 		r_list_free (ret);
70 		return NULL;
71 	}
72 	if (!r_bin_omf_get_entry (bf->o->bin_obj, addr)) {
73 		R_FREE (addr);
74 	} else {
75 		r_list_append (ret, addr);
76 	}
77 	return ret;
78 }
79 
sections(RBinFile * bf)80 static RList *sections(RBinFile *bf) {
81 	RList *ret;
82 	ut32 ct_omf_sect = 0;
83 
84 	if (!bf || !bf->o || !bf->o->bin_obj) {
85 		return NULL;
86 	}
87 	r_bin_omf_obj *obj = bf->o->bin_obj;
88 
89 	if (!(ret = r_list_new ())) {
90 		return NULL;
91 	}
92 
93 	while (ct_omf_sect < obj->nb_section) {
94 		if (!r_bin_omf_send_sections (ret,\
95 			    obj->sections[ct_omf_sect++], bf->o->bin_obj)) {
96 			return ret;
97 		}
98 	}
99 	return ret;
100 }
101 
symbols(RBinFile * bf)102 static RList *symbols(RBinFile *bf) {
103 	RList *ret;
104 	RBinSymbol *sym;
105 	OMF_symbol *sym_omf;
106 	int ct_sym = 0;
107 	if (!bf || !bf->o || !bf->o->bin_obj) {
108 		return NULL;
109 	}
110 	if (!(ret = r_list_new ())) {
111 		return NULL;
112 	}
113 
114 	ret->free = free;
115 
116 	while (ct_sym < ((r_bin_omf_obj *) bf->o->bin_obj)->nb_symbol) {
117 		if (!(sym = R_NEW0 (RBinSymbol))) {
118 			return ret;
119 		}
120 		sym_omf = ((r_bin_omf_obj *) bf->o->bin_obj)->symbols[ct_sym++];
121 		sym->name = strdup (sym_omf->name);
122 		sym->forwarder = "NONE";
123 		sym->paddr = r_bin_omf_get_paddr_sym (bf->o->bin_obj, sym_omf);
124 		sym->vaddr = r_bin_omf_get_vaddr_sym (bf->o->bin_obj, sym_omf);
125 		sym->ordinal = ct_sym;
126 		sym->size = 0;
127 		r_list_append (ret, sym);
128 	}
129 	return ret;
130 }
131 
info(RBinFile * bf)132 static RBinInfo *info(RBinFile *bf) {
133 	RBinInfo *ret;
134 
135 	if (!(ret = R_NEW0 (RBinInfo))) {
136 		return NULL;
137 	}
138 	ret->file = strdup (bf->file);
139 	ret->bclass = strdup ("OMF");
140 	ret->rclass = strdup ("omf");
141 	// the "E" is here to made rva return the same value for 16 bit en 32 bits files
142 	ret->type = strdup ("E OMF (Relocatable Object Module Format)");
143 	ret->os = strdup ("any");
144 	ret->machine = strdup ("i386");
145 	ret->arch = strdup ("x86");
146 	ret->big_endian = false;
147 	ret->has_va = true;
148 	ret->has_lit = true;
149 	ret->bits = r_bin_omf_get_bits (bf->o->bin_obj);
150 	ret->dbg_info = 0;
151 	ret->has_nx = false;
152 	return ret;
153 }
154 
get_vaddr(RBinFile * bf,ut64 baddr,ut64 paddr,ut64 vaddr)155 static ut64 get_vaddr(RBinFile *bf, ut64 baddr, ut64 paddr, ut64 vaddr) {
156 	return vaddr;
157 }
158 
159 RBinPlugin r_bin_plugin_omf = {
160 	.name = "omf",
161 	.desc = "omf bin plugin",
162 	.license = "LGPL3",
163 	.load_buffer = &load_buffer,
164 	.destroy = &destroy,
165 	.check_buffer = &check_buffer,
166 	.baddr = &baddr,
167 	.entries = &entries,
168 	.sections = &sections,
169 	.symbols = &symbols,
170 	.info = &info,
171 	.get_vaddr = &get_vaddr,
172 };
173 
174 #ifndef R2_PLUGIN_INCORE
175 R_API RLibStruct radare_plugin = {
176 	.type = R_LIB_TYPE_BIN,
177 	.data = &r_bin_plugin_omf,
178 	.version = R2_VERSION
179 };
180 #endif
181