Rizin
unix-like reverse engineering framework and cli tools
cmd_magic.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2009-2019 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_core.h>
5 
6 /* ugly global vars */
7 static int magicdepth = 99; // XXX: do not use global var here
8 static RzMagic *ck = NULL; // XXX: Use RzCore->magic
9 static char *ofile = NULL;
10 static int kw_count = 0;
11 
12 static void rz_core_magic_reset(RzCore *core) {
13  kw_count = 0;
14 }
15 
16 static int rz_core_magic_at(RzCore *core, const char *file, ut64 addr, int depth, int v, PJ *pj, int *hits) {
17  const char *fmt;
18  char *q, *p;
19  const char *str;
20  int delta = 0, adelta = 0, ret;
21  ut64 curoffset = core->offset;
22  int maxHits = rz_config_get_i(core->config, "search.maxhits");
23  if (maxHits > 0 && *hits >= maxHits) {
24  return 0;
25  }
26 #define NAH 32
27 
28  if (--depth < 0) {
29  ret = 0;
30  goto seek_exit;
31  }
32  if (addr != core->offset) {
33 #if 1
34  if (addr >= core->offset && (addr + NAH) < (core->offset + core->blocksize)) {
35  delta = addr - core->offset;
36  } else {
37  rz_core_seek(core, addr, true);
38  }
39 #endif
40  }
41  if (core->search->align) {
42  int mod = addr % core->search->align;
43  if (mod) {
44  eprintf("Unaligned search at %d\n", mod);
45  ret = mod;
46  goto seek_exit;
47  }
48  }
49  if (((addr & 7) == 0) && ((addr & (7 << 8)) == 0))
50  if (!pj) { // update search display
51  eprintf("0x%08" PFMT64x " [%d matches found]\r", addr, *hits);
52  }
53  if (file) {
54  if (*file == ' ')
55  file++;
56  if (!*file)
57  file = NULL;
58  }
59  if (file && ofile && file != ofile) {
60  if (strcmp(file, ofile)) {
62  ck = NULL;
63  }
64  }
65  if (!ck) {
66  // TODO: Move RzMagic into RzCore
68  // allocate once
69  ck = rz_magic_new(0);
70  if (file) {
71  free(ofile);
72  ofile = strdup(file);
73  if (!rz_magic_load(ck, file)) {
74  eprintf("failed rz_magic_load (\"%s\") %s\n", file, rz_magic_error(ck));
75  ck = NULL;
76  ret = -1;
77  goto seek_exit;
78  }
79  } else {
80  const char *magicpath = rz_config_get(core->config, "dir.magic");
81  if (!rz_magic_load(ck, magicpath)) {
82  ck = NULL;
83  eprintf("failed rz_magic_load (dir.magic) %s\n", rz_magic_error(ck));
84  ret = -1;
85  goto seek_exit;
86  }
87  }
88  }
89  // repeat:
90  // if (v) rz_cons_printf (" %d # pm %s @ 0x%"PFMT64x"\n", depth, file? file: "", addr);
91  if (delta + 2 > core->blocksize) {
92  eprintf("EOB\n");
93  ret = -1;
94  goto seek_exit;
95  }
96  str = rz_magic_buffer(ck, core->block + delta, core->blocksize - delta);
97  if (str) {
98  const char *cmdhit;
99 #if USE_LIB_MAGIC
100  if (!v && (!strcmp(str, "data") || strstr(str, "ASCII") || strstr(str, "ISO") || strstr(str, "no line terminator"))) {
101 #else
102  if (!v && (!strcmp(str, "data"))) {
103 #endif
104  int mod = core->search->align;
105  if (mod < 1) {
106  mod = 1;
107  }
108  // rz_magic_free (ck);
109  // ck = NULL;
110  // return -1;
111  ret = mod + 1;
112  goto seek_exit;
113  }
114  p = strdup(str);
115  fmt = p;
116  // processing newlinez
117  for (q = p; *q; q++) {
118  if (q[0] == '\\' && q[1] == 'n') {
119  *q = '\n';
120  strcpy(q + 1, q + ((q[2] == ' ') ? 3 : 2));
121  }
122  }
123  (*hits)++;
124  cmdhit = rz_config_get(core->config, "cmd.hit");
125  if (cmdhit && *cmdhit) {
126  rz_core_cmd0(core, cmdhit);
127  }
128  {
129  const char *searchprefix = rz_config_get(core->config, "search.prefix");
130  const char *flag = sdb_fmt("%s%d_%d", searchprefix, 0, kw_count++);
131  rz_flag_set(core->flags, flag, addr + adelta, 1);
132  }
133  // TODO: This must be a callback .. move this into RSearch?
134  if (!pj) {
135  rz_cons_printf("0x%08" PFMT64x " %d %s\n", addr + adelta, magicdepth - depth, p);
136  } else {
137  pj_o(pj);
138  pj_kN(pj, "offset", addr + adelta);
139  pj_ki(pj, "depth", magicdepth - depth);
140  pj_ks(pj, "info", p);
141  pj_end(pj);
142  }
144  // eprintf ("0x%08"PFMT64x" 0x%08"PFMT64x" %d %s\n", addr+adelta, addr+adelta, magicdepth-depth, p);
145  // walking children
146  for (q = p; *q; q++) {
147  switch (*q) {
148  case ' ':
149  fmt = q + 1;
150  break;
151  case '@': {
152  ut64 addr = 0LL;
153  *q = 0;
154  if (!strncmp(q + 1, "0x", 2)) {
155  sscanf(q + 3, "%" PFMT64x, &addr);
156  } else {
157  sscanf(q + 1, "%" PFMT64d, &addr);
158  }
159  if (!fmt || !*fmt) {
160  fmt = file;
161  }
162  rz_core_magic_at(core, fmt, addr, depth, 1, pj, hits);
163  *q = '@';
164  } break;
165  }
166  }
167  free(p);
168  rz_magic_free(ck);
169  ck = NULL;
170  // return adelta+1;
171  }
172  adelta++;
173  delta++;
174 #if 0
175  rz_magic_free (ck);
176  ck = NULL;
177 #endif
178  {
179  int mod = core->search->align;
180  if (mod) {
181  ret = mod; // adelta%addr + deR_ABS(mod-adelta)+1;
182  goto seek_exit;
183  }
184  }
185  ret = adelta; // found;
186 
187 seek_exit:
188  rz_core_seek(core, curoffset, true);
189  return ret;
190 }
191 
192 static void rz_core_magic(RzCore *core, const char *file, int v, PJ *pj) {
193  ut64 addr = core->offset;
194  int hits = 0;
195  magicdepth = rz_config_get_i(core->config, "magic.depth"); // TODO: do not use global var here
196  rz_core_magic_at(core, file, addr, magicdepth, v, pj, &hits);
197  if (addr != core->offset) {
198  rz_core_seek(core, addr, true);
199  }
200 }
RZ_API int rz_core_cmd0(RzCore *core, const char *cmd)
Definition: cmd.c:5428
#define NAH
static RzMagic * ck
Definition: cmd_magic.c:8
static int kw_count
Definition: cmd_magic.c:10
static int rz_core_magic_at(RzCore *core, const char *file, ut64 addr, int depth, int v, PJ *pj, int *hits)
Definition: cmd_magic.c:16
static int magicdepth
Definition: cmd_magic.c:7
static char * ofile
Definition: cmd_magic.c:9
static void rz_core_magic(RzCore *core, const char *file, int v, PJ *pj)
Definition: cmd_magic.c:192
static void rz_core_magic_reset(RzCore *core)
Definition: cmd_magic.c:12
static const char * searchprefix
Definition: cmd_search.c:157
RZ_API ut64 rz_config_get_i(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:119
RZ_API RZ_BORROW const char * rz_config_get(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:75
RZ_API void rz_cons_clear_line(int std_err)
Definition: cons.c:756
RZ_API int rz_cons_printf(const char *format,...)
Definition: cons.c:1202
#define NULL
Definition: cris-opc.c:27
int mod(int a, int b)
Definition: crypto_rot.c:8
const char * v
Definition: dsignal.c:12
RZ_API RzFlagItem * rz_flag_set(RzFlag *f, const char *name, ut64 off, ut32 size)
Definition: flag.c:521
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
void * p
Definition: libc.cpp:67
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")
RZ_API const char * rz_magic_buffer(RzMagic *ms, const void *buf, size_t nb)
Definition: magic.c:308
RZ_API RzMagic * rz_magic_new(int flags)
Definition: magic.c:235
RZ_API bool rz_magic_load(RzMagic *ms, const char *magicfile)
Definition: magic.c:278
RZ_API const char * rz_magic_error(RzMagic *ms)
Definition: magic.c:318
RZ_API void rz_magic_free(RzMagic *ms)
Definition: magic.c:254
#define eprintf(x, y...)
Definition: rlcc.c:7
RZ_API PJ * pj_ki(PJ *j, const char *k, int d)
Definition: pj.c:149
RZ_API PJ * pj_end(PJ *j)
Definition: pj.c:87
RZ_API PJ * pj_o(PJ *j)
Definition: pj.c:75
RZ_API PJ * pj_ks(PJ *j, const char *k, const char *v)
Definition: pj.c:170
RZ_API PJ * pj_kN(PJ *j, const char *k, st64 n)
Definition: pj.c:128
#define PFMT64d
Definition: rz_types.h:394
#define PFMT64x
Definition: rz_types.h:393
RZ_API bool rz_core_seek(RzCore *core, ut64 addr, bool rb)
Seek to addr.
Definition: seek.c:116
Definition: gzappend.c:170
Definition: rz_pj.h:12
RzSearch * search
Definition: rz_core.h:331
ut64 offset
Definition: rz_core.h:301
ut8 * block
Definition: rz_core.h:305
RzFlag * flags
Definition: rz_core.h:330
ut32 blocksize
Definition: rz_core.h:303
RzConfig * config
Definition: rz_core.h:300
static st64 delta
Definition: vmenus.c:2425
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int file
Definition: z80asm.c:58
static int addr
Definition: z80asm.c:58