Rizin
unix-like reverse engineering framework and cli tools
bin_p9.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2009-2019 nibble <nibble.ds@gmail.com>
2 // SPDX-FileCopyrightText: 2009-2019 pancake <pancake@nopcode.org>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include <rz_types.h>
6 #include <rz_util.h>
7 #include <rz_lib.h>
8 #include <rz_bin.h>
9 #include "../format/p9/p9bin.h"
10 
11 static bool check_buffer(RzBuffer *buf) {
12  return rz_bin_p9_get_arch(buf, NULL, NULL);
13 }
14 
15 static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *b, Sdb *sdb) {
16  return check_buffer(b);
17 }
18 
19 static void destroy(RzBinFile *bf) {
20  rz_buf_free(bf->o->bin_obj);
21 }
22 
23 static ut64 baddr(RzBinFile *bf) {
24  return 0x1000000; // XXX
25 }
26 
28  return NULL; // TODO
29 }
30 
31 static RzList *entries(RzBinFile *bf) {
32  RzList *ret;
33  RzBinAddr *ptr = NULL;
34 
35  if (!(ret = rz_list_new())) {
36  return NULL;
37  }
38  ret->free = free;
39  if ((ptr = RZ_NEW0(RzBinAddr))) {
40  ptr->paddr = 8 * 4;
41  ptr->vaddr = 8 * 4; // + baddr (bf);
42  rz_list_append(ret, ptr);
43  }
44  return ret;
45 }
46 
47 static RzList *sections(RzBinFile *bf) {
48  RzList *ret = NULL;
49  RzBinSection *ptr = NULL;
50  if (!bf->o->info) {
51  return NULL;
52  }
53 
54  if (!(ret = rz_list_newf((RzListFree)free))) {
55  return NULL;
56  }
57  if (rz_buf_size(bf->buf) < 28) {
58  rz_list_free(ret);
59  return NULL;
60  }
61  // add text segment
62  ut32 textsize;
63  if (!rz_buf_read_le32_at(bf->buf, 4, &textsize)) {
64  rz_list_free(ret);
65  return NULL;
66  }
67 
68  if (!(ptr = RZ_NEW0(RzBinSection))) {
69  rz_list_free(ret);
70  return NULL;
71  }
72  ptr->name = strdup("text");
73  ptr->size = textsize;
74  ptr->vsize = textsize + (textsize % 4096);
75  ptr->paddr = 8 * 4;
76  ptr->vaddr = ptr->paddr;
77  ptr->perm = RZ_PERM_RX; // r-x
78  rz_list_append(ret, ptr);
79  // add data segment
80  ut32 datasize;
81  if (!rz_buf_read_le32_at(bf->buf, 8, &datasize)) {
82  rz_list_free(ret);
83  return NULL;
84  }
85  if (datasize > 0) {
86  if (!(ptr = RZ_NEW0(RzBinSection))) {
87  return ret;
88  }
89  ptr->name = strdup("data");
90  ptr->size = datasize;
91  ptr->vsize = datasize + (datasize % 4096);
92  ptr->paddr = textsize + (8 * 4);
93  ptr->vaddr = ptr->paddr;
94  ptr->perm = RZ_PERM_RW;
95  rz_list_append(ret, ptr);
96  }
97  // ignore bss or what
98  // add syms segment
99  ut32 symssize;
100  if (!rz_buf_read_le32_at(bf->buf, 16, &symssize)) {
101  rz_list_free(ret);
102  return NULL;
103  }
104 
105  if (symssize) {
106  if (!(ptr = RZ_NEW0(RzBinSection))) {
107  return ret;
108  }
109  ptr->name = strdup("syms");
110  ptr->size = symssize;
111  ptr->vsize = symssize + (symssize % 4096);
112  ptr->paddr = datasize + textsize + (8 * 4);
113  ptr->vaddr = ptr->paddr;
114  ptr->perm = RZ_PERM_R; // r--
115  rz_list_append(ret, ptr);
116  }
117  // add spsz segment
118  ut32 spszsize;
119  if (!rz_buf_read_le32_at(bf->buf, 24, &spszsize)) {
120  rz_list_free(ret);
121  return NULL;
122  }
123  if (spszsize) {
124  if (!(ptr = RZ_NEW0(RzBinSection))) {
125  return ret;
126  }
127  ptr->name = strdup("spsz");
128  ptr->size = spszsize;
129  ptr->vsize = spszsize + (spszsize % 4096);
130  ptr->paddr = symssize + datasize + textsize + (8 * 4);
131  ptr->vaddr = ptr->paddr;
132  ptr->perm = RZ_PERM_R; // r--
133  rz_list_append(ret, ptr);
134  }
135 
136  // add pcsz segment
137  ut32 pcszsize;
138  if (!rz_buf_read_le32_at(bf->buf, 24, &pcszsize)) {
139  rz_list_free(ret);
140  return NULL;
141  }
142 
143  if (pcszsize) {
144  if (!(ptr = RZ_NEW0(RzBinSection))) {
145  return ret;
146  }
147  ptr->name = strdup("pcsz");
148  ptr->size = pcszsize;
149  ptr->vsize = pcszsize + (pcszsize % 4096);
150  ptr->paddr = spszsize + symssize + datasize + textsize + (8 * 4);
151  ptr->vaddr = ptr->paddr;
152  ptr->perm = RZ_PERM_R; // r--
153  rz_list_append(ret, ptr);
154  }
155  return ret;
156 }
157 
158 static RzList *symbols(RzBinFile *bf) {
159  // TODO: parse symbol table
160  return NULL;
161 }
162 
163 static RzList *imports(RzBinFile *bf) {
164  return NULL;
165 }
166 
167 static RzList *libs(RzBinFile *bf) {
168  return NULL;
169 }
170 
171 static RzBinInfo *info(RzBinFile *bf) {
172  RzBinInfo *ret = NULL;
173  int bits = 32, bina, big_endian = 0;
174 
175  if (!(bina = rz_bin_p9_get_arch(bf->buf, &bits, &big_endian))) {
176  return NULL;
177  }
178  if (!(ret = RZ_NEW0(RzBinInfo))) {
179  return NULL;
180  }
181  ret->file = strdup(bf->file);
182  ret->bclass = strdup("program");
183  ret->rclass = strdup("p9");
184  ret->os = strdup("Plan9");
185  ret->arch = strdup(rz_sys_arch_str(bina));
186  ret->machine = strdup(ret->arch);
187  ret->subsystem = strdup("plan9");
188  ret->type = strdup("EXEC (executable file)");
189  ret->bits = bits;
190  ret->has_va = true;
191  ret->big_endian = big_endian;
192  ret->dbg_info = 0;
193  return ret;
194 }
195 
196 static ut64 size(RzBinFile *bf) {
197  if (!bf) {
198  return 0;
199  }
200  if (!bf->o->info) {
201  bf->o->info = info(bf);
202  }
203  if (!bf->o->info) {
204  return 0;
205  }
206  // TODO: reuse section list
207  if (rz_buf_size(bf->buf) < 28) {
208  return 0;
209  }
210 
211  ut32 text;
212  if (!rz_buf_read_le32_at(bf->buf, 4, &text)) {
213  return 0;
214  }
215 
216  ut32 data;
217  if (!rz_buf_read_le32_at(bf->buf, 8, &data)) {
218  return 0;
219  }
220 
221  ut32 syms;
222  if (!rz_buf_read_le32_at(bf->buf, 16, &syms)) {
223  return 0;
224  }
225 
226  ut32 spsz;
227  if (!rz_buf_read_le32_at(bf->buf, 24, &spsz)) {
228  return 0;
229  }
230 
231  return text + data + syms + spsz + (6 * 4);
232 }
233 
234 #if !RZ_BIN_P9
235 
236 /* inspired in http://www.phreedom.org/solar/code/tinype/tiny.97/tiny.asm */
237 static RzBuffer *create(RzBin *bin, const ut8 *code, int codelen, const ut8 *data, int datalen, RzBinArchOptions *opt) {
239 #define B(x, y) rz_buf_append_bytes(buf, (const ut8 *)(x), y)
240 #define D(x) rz_buf_append_ut32(buf, x)
241  D(I_MAGIC); // i386 only atm
242  D(codelen);
243  D(datalen);
244  D(4096); // bss
245  D(0); // syms
246  D(8 * 4); // entry
247  D(4096); // spsz
248  D(4096); // pcsz
249  B(code, codelen);
250  if (datalen > 0) {
251  B(data, datalen);
252  }
253  return buf;
254 }
255 
257  .name = "p9",
258  .desc = "Plan9 bin plugin",
259  .license = "LGPL3",
260  .load_buffer = &load_buffer,
261  .size = &size,
262  .destroy = &destroy,
263  .check_buffer = &check_buffer,
264  .baddr = &baddr,
265  .binsym = &binsym,
266  .entries = &entries,
268  .sections = &sections,
269  .symbols = &symbols,
270  .imports = &imports,
271  .info = &info,
272  .libs = &libs,
273  .create = &create,
274 };
275 
276 #ifndef RZ_PLUGIN_INCORE
279  .data = &rz_bin_plugin_p9,
281 };
282 #endif
283 #endif
RZ_API RZ_OWN RzList * rz_bin_maps_of_file_sections(RZ_NONNULL RzBinFile *binfile)
Create a list of RzBinMap from RzBinSections queried from the given file.
Definition: bin.c:1040
static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *b, Sdb *sdb)
Definition: bin_p9.c:15
static RzBuffer * create(RzBin *bin, const ut8 *code, int codelen, const ut8 *data, int datalen, RzBinArchOptions *opt)
Definition: bin_p9.c:237
static bool check_buffer(RzBuffer *buf)
Definition: bin_p9.c:11
static RzList * symbols(RzBinFile *bf)
Definition: bin_p9.c:158
static RzBinAddr * binsym(RzBinFile *bf, RzBinSpecialSymbol type)
Definition: bin_p9.c:27
static ut64 size(RzBinFile *bf)
Definition: bin_p9.c:196
static RzList * libs(RzBinFile *bf)
Definition: bin_p9.c:167
static void destroy(RzBinFile *bf)
Definition: bin_p9.c:19
RZ_API RzLibStruct rizin_plugin
Definition: bin_p9.c:277
RzBinPlugin rz_bin_plugin_p9
Definition: bin_p9.c:256
static RzBinInfo * info(RzBinFile *bf)
Definition: bin_p9.c:171
#define B(x, y)
static ut64 baddr(RzBinFile *bf)
Definition: bin_p9.c:23
static RzList * entries(RzBinFile *bf)
Definition: bin_p9.c:31
static RzList * sections(RzBinFile *bf)
Definition: bin_p9.c:47
static RzList * imports(RzBinFile *bf)
Definition: bin_p9.c:163
#define D(x)
int bits(struct state *s, int need)
Definition: blast.c:72
#define RZ_API
#define NULL
Definition: cris-opc.c:27
uint32_t ut32
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
int type
Definition: mipsasm.c:17
int rz_bin_p9_get_arch(RzBuffer *b, int *bits, int *big_endian)
Definition: p9bin.c:7
#define I_MAGIC
Definition: p9bin.h:29
RzBinSpecialSymbol
Definition: rz_bin.h:136
#define rz_buf_read_le32_at(b, addr, result)
Definition: rz_buf.h:271
RZ_API void rz_buf_free(RzBuffer *b)
Free all internal data hold by the buffer and the buffer.
Definition: buf.c:1253
RZ_API RZ_OWN RzBuffer * rz_buf_new_with_bytes(RZ_NULLABLE RZ_BORROW const ut8 *bytes, ut64 len)
Creates a new buffer with a bytes array.
Definition: buf.c:465
RZ_API ut64 rz_buf_size(RZ_NONNULL RzBuffer *b)
Return the size of the buffer.
Definition: buf.c:1225
@ RZ_LIB_TYPE_BIN
Definition: rz_lib.h:75
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
RZ_API const char * rz_sys_arch_str(int arch)
Definition: sys.c:798
#define RZ_PERM_R
Definition: rz_types.h:93
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_PERM_RW
Definition: rz_types.h:96
#define RZ_PERM_RX
Definition: rz_types.h:97
#define RZ_VERSION
Definition: rz_version.h:8
#define b(i)
Definition: sha256.c:42
Definition: malloc.c:26
Definition: inftree9.h:24
ut64 vaddr
Definition: rz_bin.h:186
ut64 paddr
Definition: rz_bin.h:187
XX curplugin == o->plugin.
Definition: rz_bin.h:298
RzBinObject * o
Definition: rz_bin.h:305
char * file
Definition: rz_bin.h:299
RzBuffer * buf
Definition: rz_bin.h:303
int has_va
Definition: rz_bin.h:228
char * type
Definition: rz_bin.h:211
char * os
Definition: rz_bin.h:219
char * subsystem
Definition: rz_bin.h:220
char * machine
Definition: rz_bin.h:216
char * bclass
Definition: rz_bin.h:212
char * file
Definition: rz_bin.h:210
ut64 dbg_info
Definition: rz_bin.h:240
char * rclass
Definition: rz_bin.h:213
char * arch
Definition: rz_bin.h:214
int big_endian
Definition: rz_bin.h:235
RzBinInfo * info
Definition: rz_bin.h:287
void * bin_obj
Definition: rz_bin.h:293
char * name
Definition: rz_bin.h:509
char * version
Definition: rz_bin.h:512
char * name
Definition: rz_bin.h:619
RzListFree free
Definition: rz_list.h:21
Definition: sdb.h:63
ut64(WINAPI *w32_GetEnabledXStateFeatures)()