Rizin
unix-like reverse engineering framework and cli tools
nxo.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2018 rkx1209 <rkx1209dev@gmail.com>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <assert.h>
8 #include <rz_types.h>
9 #include <rz_util.h>
10 #include <rz_lib.h>
11 #include <rz_bin.h>
12 #include "nxo.h"
13 
14 static char *readString(RzBuffer *buf, int off) {
15  char symbol[128]; // assume 128 as max symbol name length
16  int left = rz_buf_read_at(buf, off, (ut8 *)symbol, sizeof(symbol));
17  if (left < 1) {
18  return NULL;
19  }
20  symbol[sizeof(symbol) - 1] = 0;
21  return strdup(symbol);
22 }
23 
24 const char *fileType(const ut8 *buf) {
25  if (!memcmp(buf, "NRO0", 4)) {
26  return "nro0";
27  }
28  if (!memcmp(buf, "NRR0", 4)) {
29  return "nrr0";
30  }
31  if (!memcmp(buf, "MOD0", 4)) {
32  return "mod0";
33  }
34  if (!memcmp(buf, "NSO0", 4)) {
35  return "nso0";
36  }
37  return NULL;
38 }
39 
40 static void walkSymbols(RzBuffer *buf, RzBinNXOObj *bin, ut64 symtab, ut64 strtab, ut64 strtab_size, ut64 relplt, ut64 baddr) {
41  int i, import = 0;
42  RzBinSymbol *sym;
43  RzBinImport *imp;
44  for (i = 8; i < 99999; i++) {
45  ut64 addr;
46  if (!rz_buf_read_le64_at(buf, symtab + i, &addr)) {
47  break;
48  }
49  ut64 size;
50  if (!rz_buf_read_le64_at(buf, symtab + i + 8, &size)) {
51  break;
52  }
53 
54  i += 16; // NULL, NULL
55  ut32 name;
56  if (!rz_buf_read_le32_at(buf, symtab + i, &name)) {
57  break;
58  }
59  // ut64 type = rz_buf_read_le32_at (buf, symtab + i + 4);
60  char *symName = readString(buf, strtab + name);
61  if (!symName) {
62  break;
63  }
64  sym = RZ_NEW0(RzBinSymbol);
65  if (!sym) {
66  free(symName);
67  break;
68  }
70  sym->bind = "NONE";
71  sym->size = size;
72 
73  if (addr == 0) {
74  import++;
75  ut64 pltSym;
76  if (!rz_buf_read_le64_at(buf, relplt + (import * 24), &pltSym)) {
77  free(symName);
78  rz_bin_symbol_free(sym);
79  break;
80  }
81  imp = RZ_NEW0(RzBinImport);
82  if (!imp) {
83  RZ_FREE(sym);
84  free(symName);
85  break;
86  }
87  imp->name = symName;
88  if (!imp->name) {
89  goto out_walk_symbol;
90  }
91  imp->type = "FUNC";
92  if (!imp->type) {
93  goto out_walk_symbol;
94  }
95  imp->bind = "NONE";
96  if (!imp->bind) {
97  goto out_walk_symbol;
98  }
99  imp->ordinal = bin->imports_list->length;
100  rz_list_append(bin->imports_list, imp);
101  sym->is_imported = true;
102  sym->name = strdup(symName);
103  if (!sym->name) {
104  goto out_walk_symbol;
105  }
106  sym->paddr = pltSym - 8;
107  sym->vaddr = sym->paddr + baddr;
108  RZ_LOG_INFO("f sym.imp.%s @ 0x%" PFMT64x "\n", symName, pltSym - 8);
109  } else {
110  sym->name = symName;
111  if (!sym->name) {
112  RZ_FREE(sym);
113  break;
114  }
115  sym->paddr = addr;
116  sym->vaddr = sym->paddr + baddr;
117  RZ_LOG_INFO("f sym.%s %" PFMT64u " @ 0x%" PFMT64x "\n", symName, size, addr);
118  }
119  rz_list_append(bin->methods_list, sym);
120  i += 8 - 1;
121  }
122  return;
123 
124 out_walk_symbol:
125  RZ_FREE(sym);
126  RZ_FREE(imp);
127  return;
128 }
129 
131  ut32 ptr;
132  if (!rz_buf_read_le32_at(buf, mod0, &ptr)) {
133  return;
134  }
135 
136  RZ_LOG_INFO("magic %x at 0x%x\n", ptr, mod0);
137  if (ptr == 0x30444f4d) { // MOD0
138  RZ_LOG_INFO("is mode0\n");
139  MODHeader mh = { 0 };
140  if (!rz_buf_read_le32_at(buf, mod0, &mh.magic) ||
141  !rz_buf_read_le32_at(buf, mod0 + 4, &mh.dynamic) ||
142  !rz_buf_read_le32_at(buf, mod0 + 8, &mh.bss_start) ||
143  !rz_buf_read_le32_at(buf, mod0 + 12, &mh.bss_end) ||
144  !rz_buf_read_le32_at(buf, mod0 + 16, &mh.unwind_start) ||
145  !rz_buf_read_le32_at(buf, mod0 + 20, &mh.unwind_end) ||
146  !rz_buf_read_le32_at(buf, mod0 + 24, &mh.mod_object)) {
147  return;
148  }
149  mh.mod_object += mod0;
150  RZ_LOG_INFO("magic 0x%x\n", mh.magic);
151  RZ_LOG_INFO("dynamic 0x%x\n", mh.dynamic);
152  RZ_LOG_INFO("bss 0x%x 0x%x\n", mh.bss_start, mh.bss_end);
153  RZ_LOG_INFO("unwind 0x%x 0x%x\n", mh.unwind_start, mh.unwind_end);
154  RZ_LOG_INFO("-------------\n");
155  RZ_LOG_INFO("mod 0x%x\n", mh.mod_object);
156 #define MO_(x) rz_buf_read_le64_at(buf, mh.mod_object + rz_offsetof(MODObject, x), &mo.x)
157  MODObject mo = { 0 };
158  if (!MO_(next) || !MO_(prev) || !MO_(relplt) || !MO_(reldyn) ||
159  !MO_(base) || !MO_(dynamic) || !MO_(is_rela) ||
160  !MO_(relplt_size) || !MO_(init) || !MO_(fini) ||
161  !MO_(bucket) || !MO_(chain) || !MO_(strtab) ||
162  !MO_(symtab) || !MO_(strtab_size)) {
163  return;
164  };
165  RZ_LOG_INFO("next 0x%" PFMT64x "\n", mo.next);
166  RZ_LOG_INFO("prev 0x%" PFMT64x "\n", mo.prev);
167  RZ_LOG_INFO("base 0x%" PFMT64x "\n", mo.base);
168  RZ_LOG_INFO("init 0x%" PFMT64x "\n", mo.init);
169  RZ_LOG_INFO("fini 0x%" PFMT64x "\n", mo.fini);
170  RZ_LOG_INFO("relplt 0x%" PFMT64x "\n", mo.relplt - mo.base);
171  RZ_LOG_INFO("symtab = 0x%" PFMT64x "\n", mo.symtab - mo.base);
172  RZ_LOG_INFO("strtab = 0x%" PFMT64x "\n", mo.strtab - mo.base);
173  RZ_LOG_INFO("strtabsz = 0x%" PFMT64x "\n", mo.strtab_size);
174  // ut32 modo = mh.mod_object;
175  ut64 strtab = mo.strtab - mo.base;
176  ut64 symtab = mo.symtab - mo.base;
177  walkSymbols(buf, bin, symtab, strtab, mo.strtab_size, mo.relplt - mo.base, baddr);
178  }
179 }
static bool fini(void *user)
lzma_index ** i
Definition: index.h:629
RZ_API void rz_bin_symbol_free(RzBinSymbol *sym)
Definition: bin.c:175
static ut64 baddr(RzBinFile *bf)
Definition: bin_any.c:58
#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 uLong size
Definition: ioapi.h:138
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
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
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")
static char * readString(RzBuffer *buf, int off)
Definition: nxo.c:14
#define MO_(x)
static void walkSymbols(RzBuffer *buf, RzBinNXOObj *bin, ut64 symtab, ut64 strtab, ut64 strtab_size, ut64 relplt, ut64 baddr)
Definition: nxo.c:40
void parseMod(RzBuffer *buf, RzBinNXOObj *bin, ut32 mod0, ut64 baddr)
Definition: nxo.c:130
const char * fileType(const ut8 *buf)
Definition: nxo.c:24
const char * name
Definition: op.c:541
int off
Definition: pal.c:13
int dynamic(struct state *s)
Definition: puff.c:665
#define RZ_BIN_TYPE_FUNC_STR
Definition: rz_bin.h:119
RZ_API st64 rz_buf_read_at(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL RZ_OUT ut8 *buf, ut64 len)
Read len bytes of the buffer at the specified address.
Definition: buf.c:1136
#define rz_buf_read_le32_at(b, addr, result)
Definition: rz_buf.h:271
#define rz_buf_read_le64_at(b, addr, result)
Definition: rz_buf.h:272
#define RZ_LOG_INFO(fmtstr,...)
Definition: rz_log.h:54
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define PFMT64u
Definition: rz_types.h:395
#define RZ_FREE(x)
Definition: rz_types.h:369
#define PFMT64x
Definition: rz_types.h:393
Definition: nxo.h:13
ut32 magic
Definition: nxo.h:14
ut32 bss_end
Definition: nxo.h:17
ut32 bss_start
Definition: nxo.h:16
ut32 dynamic
Definition: nxo.h:15
ut32 unwind_start
Definition: nxo.h:18
ut32 mod_object
Definition: nxo.h:20
ut32 unwind_end
Definition: nxo.h:19
Definition: nxo.h:23
ut64 prev
Definition: nxo.h:25
ut64 fini
Definition: nxo.h:33
ut64 symtab
Definition: nxo.h:37
ut64 init
Definition: nxo.h:32
ut64 next
Definition: nxo.h:24
ut64 strtab_size
Definition: nxo.h:38
ut64 base
Definition: nxo.h:28
ut64 relplt
Definition: nxo.h:26
ut64 strtab
Definition: nxo.h:36
Definition: malloc.c:26
Definition: z80asm.h:102
const char * type
Definition: rz_bin.h:704
const char * bind
Definition: rz_bin.h:703
ut32 ordinal
Definition: rz_bin.h:707
char * name
Definition: rz_bin.h:701
const char * bind
Definition: rz_bin.h:681
bool is_imported
Definition: rz_bin.h:684
const char * type
Definition: rz_bin.h:682
char * name
Definition: rz_bin.h:675
bool init
Definition: core.c:77
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58