Rizin
unix-like reverse engineering framework and cli tools
bin_pebble.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2014-2019 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_types.h>
5 #include <rz_util.h>
6 #include <rz_lib.h>
7 #include <rz_bin.h>
8 
9 // Taken from https://pebbledev.org/wiki/Applications
10 
11 #define APP_NAME_BYTES 32
12 #define COMPANY_NAME_BYTES 32
13 
15  typedef struct {
16  ut8 major;
17  ut8 minor;
18  })
19 Version;
20 
21 RZ_PACKED(
22  typedef struct {
23  char header[8];
24  Version struct_version;
25  Version sdk_version;
26  Version app_version;
27  ut16 size;
28  ut32 offset;
29  ut32 crc;
30  char name[APP_NAME_BYTES];
31  char company[COMPANY_NAME_BYTES];
32  ut32 icon_resource_id;
33  ut32 sym_table_addr;
34  ut32 flags;
35  ut32 reloc_list_start;
36  ut32 num_reloc_entries;
37  ut8 uuid[16];
38  })
40 
41 static bool check_buffer(RzBuffer *b) {
42  ut8 magic[8];
43  if (rz_buf_read_at(b, 0, magic, sizeof(magic)) != sizeof(magic)) {
44  return false;
45  }
46  return !memcmp(magic, "PBLAPP\x00\x00", 8);
47 }
48 
49 static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *b, Sdb *sdb) {
50  return check_buffer(b);
51 }
52 
53 static ut64 baddr(RzBinFile *bf) {
54  return 0LL;
55 }
56 
57 /* accelerate binary load */
58 static RzList *strings(RzBinFile *bf) {
59  return NULL;
60 }
61 
62 static RzBinInfo *info(RzBinFile *bf) {
63  RzBinInfo *ret = NULL;
64  PebbleAppInfo pai;
65  memset(&pai, 0, sizeof(pai));
66  int reat = rz_buf_read_at(bf->buf, 0, (ut8 *)&pai, sizeof(pai));
67  if (reat != sizeof(pai)) {
68  RZ_LOG_ERROR("Truncated Header\n");
69  return NULL;
70  }
71  if (!(ret = RZ_NEW0(RzBinInfo))) {
72  return NULL;
73  }
74  ret->lang = NULL;
75  ret->file = strdup(bf->file);
76  ret->type = strdup("pebble");
77  ret->bclass = rz_str_ndup(pai.name, 32);
78  ret->rclass = rz_str_ndup(pai.company, 32);
79  ret->os = strdup("rtos");
80  ret->subsystem = strdup("pebble");
81  ret->machine = strdup("watch");
82  ret->arch = strdup("arm"); // thumb only
83  ret->has_va = 1;
84  ret->bits = 16;
85  ret->big_endian = 0;
86  ret->dbg_info = 0;
87  return ret;
88 }
89 
90 static RzList *sections(RzBinFile *bf) {
91  ut64 textsize = UT64_MAX;
92  RzList *ret = NULL;
93  RzBinSection *ptr = NULL;
94  PebbleAppInfo pai = { { 0 } };
95  if (!rz_buf_read_at(bf->buf, 0, (ut8 *)&pai, sizeof(pai))) {
96  RZ_LOG_ERROR("Truncated Header\n");
97  return NULL;
98  }
99  if (!(ret = rz_list_new())) {
100  return NULL;
101  }
102  ret->free = free;
103  // TODO: load all relocs
104  if (!(ptr = RZ_NEW0(RzBinSection))) {
105  return ret;
106  }
107  ptr->name = strdup("relocs");
108  ptr->vsize = ptr->size = pai.num_reloc_entries * sizeof(ut32);
109  ptr->vaddr = ptr->paddr = pai.reloc_list_start;
110  ptr->perm = RZ_PERM_RW;
111  rz_list_append(ret, ptr);
112  if (ptr->vaddr < textsize) {
113  textsize = ptr->vaddr;
114  }
115 
116  // imho this must be a symbol
117  if (!(ptr = RZ_NEW0(RzBinSection))) {
118  return ret;
119  }
120  ptr->name = strdup("symtab");
121  ptr->vsize = ptr->size = 0;
122  ptr->vaddr = ptr->paddr = pai.sym_table_addr;
123  ptr->perm = RZ_PERM_R;
124  rz_list_append(ret, ptr);
125  if (ptr->vaddr < textsize) {
126  textsize = ptr->vaddr;
127  }
128 
129  if (!(ptr = RZ_NEW0(RzBinSection))) {
130  return ret;
131  }
132  ptr->name = strdup("text");
133  ptr->vaddr = ptr->paddr = 0x80;
134  ptr->vsize = ptr->size = textsize - ptr->paddr;
135  ptr->perm = RZ_PERM_RWX;
136  rz_list_append(ret, ptr);
137 
138  if (!(ptr = RZ_NEW0(RzBinSection))) {
139  return ret;
140  }
141  ptr->name = strdup("header");
142  ptr->vsize = ptr->size = sizeof(PebbleAppInfo);
143  ptr->vaddr = ptr->paddr = 0;
144  ptr->perm = RZ_PERM_R;
145  rz_list_append(ret, ptr);
146 
147  return ret;
148 }
149 
150 #if 0
151 static RzList* relocs(RzBinFile *bf) {
152  RzList *ret = NULL;
153  RzBinReloc *ptr = NULL;
154  ut64 got_addr;
155  int i;
156 
157  if (!(ret = rz_list_new ()))
158  return NULL;
159  ret->free = free;
160  return ret;
161 }
162 #endif
163 
164 static RzList *entries(RzBinFile *bf) {
165  RzBinAddr *ptr = NULL;
166  RzList *ret;
167  PebbleAppInfo pai;
168  if (!rz_buf_read_at(bf->buf, 0, (ut8 *)&pai, sizeof(pai))) {
169  RZ_LOG_ERROR("Truncated Header\n");
170  return NULL;
171  }
172  if (!(ret = rz_list_new())) {
173  return NULL;
174  }
175  ret->free = free;
176  if (!(ptr = RZ_NEW0(RzBinAddr))) {
177  return ret;
178  }
179  ptr->paddr = pai.offset;
180  ptr->vaddr = pai.offset;
181  rz_list_append(ret, ptr);
182  return ret;
183 }
184 
186  .name = "pebble",
187  .desc = "Pebble Watch App",
188  .license = "LGPL",
189  .load_buffer = &load_buffer,
190  .check_buffer = &check_buffer,
191  .baddr = &baddr,
192  .entries = entries,
194  .sections = sections,
195  .strings = &strings,
196  .info = &info,
197  //.relocs = &relocs
198 };
199 
200 #ifndef RZ_PLUGIN_INCORE
203  .data = &rz_bin_plugin_pebble,
205 };
206 #endif
lzma_index ** i
Definition: index.h:629
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
RzList * relocs(RzBinFile *bf)
Definition: bin_ne.c:114
static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *b, Sdb *sdb)
Definition: bin_pebble.c:49
RzBinPlugin rz_bin_plugin_pebble
Definition: bin_pebble.c:185
#define APP_NAME_BYTES
Definition: bin_pebble.c:11
PebbleAppInfo
Definition: bin_pebble.c:39
#define COMPANY_NAME_BYTES
Definition: bin_pebble.c:12
static RzList * strings(RzBinFile *bf)
Definition: bin_pebble.c:58
RZ_API RzLibStruct rizin_plugin
Definition: bin_pebble.c:201
static bool check_buffer(RzBuffer *b)
Definition: bin_pebble.c:41
static RzBinInfo * info(RzBinFile *bf)
Definition: bin_pebble.c:62
static ut64 baddr(RzBinFile *bf)
Definition: bin_pebble.c:53
static RzList * entries(RzBinFile *bf)
Definition: bin_pebble.c:164
RZ_PACKED(typedef struct { ut8 major;ut8 minor;})
Definition: bin_pebble.c:14
static RzList * sections(RzBinFile *bf)
Definition: bin_pebble.c:90
#define RZ_API
#define NULL
Definition: cris-opc.c:27
uint16_t ut16
uint32_t ut32
#define minor(dev)
Definition: fsmagic.c:57
#define major(dev)
Definition: fsmagic.c:56
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
voidpf uLong offset
Definition: ioapi.h:144
uint8_t ut8
Definition: lh5801.h:11
return memset(p, 0, total)
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
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")
#define header(is_bt, len_min, ret_op)
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
@ RZ_LIB_TYPE_BIN
Definition: rz_lib.h:75
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API char * rz_str_ndup(RZ_NULLABLE const char *ptr, int len)
Create new copy of string ptr limited to size len.
Definition: str.c:1006
#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_RWX
Definition: rz_types.h:98
#define UT64_MAX
Definition: rz_types_base.h:86
#define RZ_VERSION
Definition: rz_version.h:8
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
#define b(i)
Definition: sha256.c:42
Definition: z80asm.h:102
ut64 vaddr
Definition: rz_bin.h:186
ut64 paddr
Definition: rz_bin.h:187
XX curplugin == o->plugin.
Definition: rz_bin.h:298
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
const char * lang
Definition: rz_bin.h:224
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
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)()