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 = §ions,
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