Rizin
unix-like reverse engineering framework and cli tools
bin_avr.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2016-2017 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_bin.h>
5 #include <rz_lib.h>
6 
7 #define CHECK4INSTR(b, instr, size) \
8  if (!instr(b, 0) || \
9  !instr((b), (size)) || \
10  !instr((b), (size)*2) || \
11  !instr((b), (size)*3)) { \
12  return false; \
13  }
14 
15 #define CHECK3INSTR(b, instr, size) \
16  if (!instr((b), (size)) || \
17  !instr((b), (size)*2) || \
18  !instr((b), (size)*3)) { \
19  return false; \
20  }
21 
23 
24 static bool rjmp(RzBuffer *b, ut64 addr) {
25  ut8 tmp;
26  if (!rz_buf_read8_at(b, addr + 1, &tmp)) {
27  return false;
28  }
29 
30  return (tmp & 0xf0) == 0xc0;
31 }
32 
33 static bool jmp(RzBuffer *b, ut64 addr) {
34  ut8 tmp;
35  if (!rz_buf_read8_at(b, addr, &tmp)) {
36  return false;
37  }
38 
39  if (tmp != 0x0c) {
40  return false;
41  }
42 
43  return rz_buf_read8_at(b, addr + 1, &tmp) && tmp == 0x94;
44 }
45 
46 static bool rjmp_dest(RzBuffer *b, ut64 addr, ut64 *result) {
47  ut8 tmp;
48  if (!rz_buf_read8_at(b, addr, &tmp)) {
49  return false;
50  }
51 
52  ut64 dst = 2 + addr + (ut64)tmp * 2;
53 
54  if (!rz_buf_read8_at(b, addr + 1, &tmp)) {
55  return false;
56  }
57 
58  *result = dst + ((((ut64)tmp & 0xf) * 2) << 8);
59 
60  return true;
61 }
62 
63 static bool jmp_dest(RzBuffer *b, ut64 addr, ut64 *result) {
64  ut8 tmp;
65  if (!rz_buf_read8_at(b, addr + 2, &tmp)) {
66  return false;
67  }
68 
69  *result = tmp;
70 
71  if (!rz_buf_read8_at(b, addr + 3, &tmp)) {
72  return false;
73  }
74 
75  *result += (ut64)tmp << 8;
76  *result *= 2;
77 
78  return true;
79 }
80 
81 static bool check_buffer_rjmp(RzBuffer *b) {
82  CHECK3INSTR(b, rjmp, 4);
83  ut64 dst;
84  if (!rjmp_dest(b, 0, &dst)) {
85  return false;
86  }
87 
88  if (dst < 1 || dst > rz_buf_size(b)) {
89  return false;
90  }
91  tmp_entry = dst;
92  return true;
93 }
94 
95 static bool check_buffer_jmp(RzBuffer *b) {
96  CHECK4INSTR(b, jmp, 4);
97  ut64 dst;
98  if (!jmp_dest(b, 0, &dst)) {
99  return false;
100  }
101 
102  if (dst < 1 || dst > rz_buf_size(b)) {
103  return false;
104  }
105  tmp_entry = dst;
106  return true;
107 }
108 
109 static bool check_buffer(RzBuffer *buf) {
110  if (rz_buf_size(buf) < 32) {
111  return false;
112  }
113  if (!rjmp(buf, 0)) {
114  return check_buffer_jmp(buf);
115  }
116  return check_buffer_rjmp(buf);
117 }
118 
119 static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb) {
120  return check_buffer(buf);
121 }
122 
123 static void destroy(RzBinFile *bf) {
124  rz_buf_free(bf->o->bin_obj);
125 }
126 
127 static RzBinInfo *info(RzBinFile *bf) {
129  RzBinInfo *bi = RZ_NEW0(RzBinInfo);
130  if (bi) {
131  bi->file = strdup(bf->file);
132  bi->type = strdup("ROM");
133  bi->machine = strdup("ATmel");
134  bi->os = strdup("avr");
135  bi->has_va = 0; // 1;
136  bi->arch = strdup("avr");
137  bi->bits = 8;
138  }
139  return bi;
140 }
141 
142 static RzList *entries(RzBinFile *bf) {
143  RzList *ret;
144  RzBinAddr *ptr = NULL;
145  if (tmp_entry == UT64_MAX) {
146  return false;
147  }
148  if (!(ret = rz_list_new())) {
149  return NULL;
150  }
151  ret->free = free;
152  if ((ptr = RZ_NEW0(RzBinAddr))) {
153  ut64 addr = tmp_entry;
154  ptr->vaddr = ptr->paddr = addr;
155  rz_list_append(ret, ptr);
156  }
157  return ret;
158 }
159 
160 static void addsym(RzList *ret, const char *name, ut64 addr) {
162  if (ptr) {
163  ptr->name = strdup(name ? name : "");
164  ptr->paddr = ptr->vaddr = addr;
165  ptr->size = 0;
166  ptr->ordinal = 0;
167  rz_list_append(ret, ptr);
168  }
169 }
170 
171 static void addptr(RzList *ret, const char *name, ut64 addr, RzBuffer *b) {
172  if (b && rjmp(b, 0)) {
173  addsym(ret, sdb_fmt("vector.%s", name), addr);
174  ut64 ptr_addr;
175  if (rjmp_dest(b, addr, &ptr_addr)) {
176  addsym(ret, sdb_fmt("syscall.%s", name), ptr_addr);
177  }
178  }
179 }
180 
181 static RzList *symbols(RzBinFile *bf) {
182  RzList *ret = NULL;
183  RzBuffer *obj = bf->o->bin_obj;
184 
185  if (!(ret = rz_list_newf((RzListFree)rz_bin_symbol_free))) {
186  return NULL;
187  }
188  /* atmega8 */
189  addptr(ret, "int0", 2, obj);
190  addptr(ret, "int1", 4, obj);
191  addptr(ret, "timer2cmp", 6, obj);
192  addptr(ret, "timer2ovf", 8, obj);
193  addptr(ret, "timer1capt", 10, obj);
194  addptr(ret, "timer1cmpa", 12, obj);
195  return ret;
196 }
197 
198 static RzList *strings(RzBinFile *bf) {
199  // we dont want to find strings in avr bins because there are lot of false positives
200  return NULL;
201 }
202 
204  .name = "avr",
205  .desc = "ATmel AVR MCUs",
206  .license = "LGPL3",
207  .load_buffer = &load_buffer,
208  .destroy = &destroy,
209  .entries = &entries,
210  .symbols = &symbols,
211  .check_buffer = &check_buffer,
212  .info = &info,
213  .strings = &strings,
214 };
215 
216 #ifndef RZ_PLUGIN_INCORE
219  .data = &rz_bin_plugin_avr,
221 };
222 #endif
RZ_API void rz_bin_symbol_free(RzBinSymbol *sym)
Definition: bin.c:175
static bool rjmp(RzBuffer *b, ut64 addr)
Definition: bin_avr.c:24
static bool check_buffer(RzBuffer *buf)
Definition: bin_avr.c:109
static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *buf, Sdb *sdb)
Definition: bin_avr.c:119
static RzList * symbols(RzBinFile *bf)
Definition: bin_avr.c:181
static void addsym(RzList *ret, const char *name, ut64 addr)
Definition: bin_avr.c:160
RzBinPlugin rz_bin_plugin_avr
Definition: bin_avr.c:203
static bool jmp(RzBuffer *b, ut64 addr)
Definition: bin_avr.c:33
static RzList * strings(RzBinFile *bf)
Definition: bin_avr.c:198
static void destroy(RzBinFile *bf)
Definition: bin_avr.c:123
RZ_API RzLibStruct rizin_plugin
Definition: bin_avr.c:217
static ut64 tmp_entry
Definition: bin_avr.c:22
static bool check_buffer_rjmp(RzBuffer *b)
Definition: bin_avr.c:81
static RzBinInfo * info(RzBinFile *bf)
Definition: bin_avr.c:127
static bool jmp_dest(RzBuffer *b, ut64 addr, ut64 *result)
Definition: bin_avr.c:63
static bool check_buffer_jmp(RzBuffer *b)
Definition: bin_avr.c:95
static RzList * entries(RzBinFile *bf)
Definition: bin_avr.c:142
static bool rjmp_dest(RzBuffer *b, ut64 addr, ut64 *result)
Definition: bin_avr.c:46
#define CHECK3INSTR(b, instr, size)
Definition: bin_avr.c:15
static void addptr(RzList *ret, const char *name, ut64 addr, RzBuffer *b)
Definition: bin_avr.c:171
#define CHECK4INSTR(b, instr, size)
Definition: bin_avr.c:7
#define RZ_API
#define NULL
Definition: cris-opc.c:27
RZ_API char * sdb_fmt(const char *fmt,...)
Definition: fmt.c:26
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
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")
char * dst
Definition: lz4.h:724
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API bool rz_buf_read8_at(RzBuffer *b, ut64 addr, RZ_NONNULL RZ_OUT ut8 *result)
Read a byte at the specified address in the buffer.
Definition: buf.c:876
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 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
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define UT64_MAX
Definition: rz_types_base.h:86
#define RZ_VERSION
Definition: rz_version.h:8
#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
RzBinObject * o
Definition: rz_bin.h:305
char * file
Definition: rz_bin.h:299
int has_va
Definition: rz_bin.h:228
char * type
Definition: rz_bin.h:211
char * os
Definition: rz_bin.h:219
char * machine
Definition: rz_bin.h:216
char * file
Definition: rz_bin.h:210
char * arch
Definition: rz_bin.h:214
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:675
ut32 ordinal
Definition: rz_bin.h:692
RzListFree free
Definition: rz_list.h:21
Definition: sdb.h:63
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58