Rizin
unix-like reverse engineering framework and cli tools
rz_magic.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2011-2014 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #ifndef RZ_MAGIC_H
5 #define RZ_MAGIC_H
6 
7 #include <rz_types.h>
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
14 
15 #ifndef MAGICFILE
16 #define MAGICFILE "/etc/magic"
17 #endif
18 
19 #ifdef RZ_API
20 
21 #ifdef __EMX__
22 #define PATHSEP ';'
23 #else
24 #define PATHSEP ':'
25 #endif
26 
27 /* limits */
28 #ifndef HOWMANY
29 #define HOWMANY (256 * 1024) /* how much of the file to look at */
30 #endif
31 #define MAXDESC 64
32 #define MAXMAGIS 8192 /* max entries in any one magic file or directory */
33 #define MAXstring 32 /* max leng of "string" types */
34 
35 /* define this outside to fix build for g++ */
36 union VALUETYPE {
37  ut8 b;
38  ut16 h;
39  ut32 l;
40  ut64 q;
41  ut8 hs[2]; /* 2 bytes of a fixed-endian "short" */
42  ut8 hl[4]; /* 4 bytes of a fixed-endian "long" */
43  ut8 hq[8]; /* 8 bytes of a fixed-endian "quad" */
44  char s[MAXstring]; /* the search string or regex pattern */
45  float f;
46  double d;
47 }; /* either number or string */
48 
49 /* constants */
50 #define MAGICNO 0xF11E041C
51 #define VERSIONNO 5
52 #define FILE_MAGICSIZE (32 * 6)
53 
54 #define FILE_LOAD 0
55 #define FILE_CHECK 1
56 #define FILE_COMPILE 2
57 
58 struct rz_magic {
59  /* Word 1 */
60  ut16 cont_level; /* level of ">" */
61  ut8 flag;
62 
63 #define INDIR 0x01 /* if '(...)' appears */
64 #define OFFADD 0x02 /* if '>&' or '>...(&' appears */
65 #define INDIROFFADD 0x04 /* if '>&(' appears */
66 #define UNSIGNED 0x08 /* comparison is unsigned */
67 #define NOSPACE 0x10 /* suppress space character before output */
68 #define BINTEST 0x20 /* test is for a binary type (set only \
69  for top-level tests) */
70 #define TEXTTEST 0 /* for passing to file_softmagic */
71 
72  ut8 dummy1;
73 
74  /* Word 2 */
75  ut8 reln; /* relation (0=eq, '>'=gt, etc) */
76  ut8 vallen; /* length of string value, if any */
77  ut8 type; /* comparison type (FILE_*) */
78  ut8 in_type; /* type of indirection */
79 #define FILE_INVALID 0
80 #define FILE_BYTE 1
81 #define FILE_SHORT 2
82 #define FILE_DEFAULT 3
83 #define FILE_LONG 4
84 #define FILE_STRING 5
85 #define FILE_DATE 6
86 #define FILE_BESHORT 7
87 #define FILE_BELONG 8
88 #define FILE_BEDATE 9
89 #define FILE_LESHORT 10
90 #define FILE_LELONG 11
91 #define FILE_LEDATE 12
92 #define FILE_PSTRING 13
93 #define FILE_LDATE 14
94 #define FILE_BELDATE 15
95 #define FILE_LELDATE 16
96 #define FILE_REGEX 17
97 #define FILE_BESTRING16 18
98 #define FILE_LESTRING16 19
99 #define FILE_SEARCH 20
100 #define FILE_MEDATE 21
101 #define FILE_MELDATE 22
102 #define FILE_MELONG 23
103 #define FILE_QUAD 24
104 #define FILE_LEQUAD 25
105 #define FILE_BEQUAD 26
106 #define FILE_QDATE 27
107 #define FILE_LEQDATE 28
108 #define FILE_BEQDATE 29
109 #define FILE_QLDATE 30
110 #define FILE_LEQLDATE 31
111 #define FILE_BEQLDATE 32
112 #define FILE_FLOAT 33
113 #define FILE_BEFLOAT 34
114 #define FILE_LEFLOAT 35
115 #define FILE_DOUBLE 36
116 #define FILE_BEDOUBLE 37
117 #define FILE_LEDOUBLE 38
118 #define FILE_NAMES_SIZE 39 /* size of array to contain all names */
119 
120 #define MAGIC_IS_STRING(t) \
121  ((t) == FILE_STRING || \
122  (t) == FILE_PSTRING || \
123  (t) == FILE_BESTRING16 || \
124  (t) == FILE_LESTRING16 || \
125  (t) == FILE_REGEX || \
126  (t) == FILE_SEARCH || \
127  (t) == FILE_DEFAULT)
128 
129 #define FILE_FMT_NONE 0
130 #define FILE_FMT_NUM 1 /* "cduxXi" */
131 #define FILE_FMT_STR 2 /* "s" */
132 #define FILE_FMT_QUAD 3 /* "ll" */
133 #define FILE_FMT_FLOAT 4 /* "eEfFgG" */
134 #define FILE_FMT_DOUBLE 5 /* "eEfFgG" */
135 
136  /* Word 3 */
137  ut8 in_op; /* operator for indirection */
138  ut8 mask_op; /* operator for mask */
139  ut8 cond; /* conditional type */
140  ut8 dummy2;
141 
142 #define FILE_OPS "&|^+-*/%"
143 #define FILE_OPAND 0
144 #define FILE_OPOR 1
145 #define FILE_OPXOR 2
146 #define FILE_OPADD 3
147 #define FILE_OPMINUS 4
148 #define FILE_OPMULTIPLY 5
149 #define FILE_OPDIVIDE 6
150 #define FILE_OPMODULO 7
151 #define FILE_OPS_MASK 0x07 /* mask for above ops */
152 #define FILE_UNUSED_1 0x08
153 #define FILE_UNUSED_2 0x10
154 #define FILE_UNUSED_3 0x20
155 #define FILE_OPINVERSE 0x40
156 #define FILE_OPINDIRECT 0x80
157 
158 #define COND_NONE 0
159 #define COND_IF 1
160 #define COND_ELIF 2
161 #define COND_ELSE 3
162 
163  /* Word 4 */
164  ut32 offset; /* offset to magic number */
165  /* Word 5 */
166  ut32 in_offset; /* offset from indirection */
167  /* Word 6 */
168  ut32 lineno; /* line number in magic file */
169  /* Word 7,8 */
170  union {
171  ut64 _mask; /* for use with numeric and date types */
172  struct {
173  ut32 _count; /* repeat/line count */
174  ut32 _flags; /* modifier flags */
175  } _s; /* for use with string types */
176  } _u;
177 
178 #define num_mask _u._mask
179 #define str_range _u._s._count
180 #define str_flags _u._s._flags
181 
182  /* Words 9-16 */
183  union VALUETYPE value;
184  /* Words 17..31 */
185  char desc[MAXDESC]; /* description */
186  /* Words 32..47 */
187  char mimetype[MAXDESC]; /* MIME type */
188 };
189 
190 #define BIT(A) (1 << (A))
191 #define STRING_COMPACT_BLANK BIT(0)
192 #define STRING_COMPACT_OPTIONAL_BLANK BIT(1)
193 #define STRING_IGNORE_LOWERCASE BIT(2)
194 #define STRING_IGNORE_UPPERCASE BIT(3)
195 #define REGEX_OFFSET_START BIT(4)
196 #define CHAR_COMPACT_BLANK 'B'
197 #define CHAR_COMPACT_OPTIONAL_BLANK 'b'
198 #define CHAR_IGNORE_LOWERCASE 'c'
199 #define CHAR_IGNORE_UPPERCASE 'C'
200 #define CHAR_REGEX_OFFSET_START 's'
201 #define STRING_IGNORE_CASE (STRING_IGNORE_LOWERCASE | STRING_IGNORE_UPPERCASE)
202 #define STRING_DEFAULT_RANGE 100
203 
204 /* list of magic entries */
205 struct mlist {
206  struct rz_magic *magic; /* array of magic entries */
207  ut32 nmagic; /* number of entries in array */
208  int mapped; /* allocation type: 0 => apprentice_file
209  * 1 => apprentice_map + malloc
210  * 2 => apprentice_map + mmap */
211  struct mlist *next, *prev;
212 };
213 
214 #define RZ_MAGIC_NONE 0x000000 /* No flags */
215 #define RZ_MAGIC_DEBUG 0x000001 /* Turn on debugging */
216 #define RZ_MAGIC_SYMLINK 0x000002 /* Follow symlinks */
217 #define RZ_MAGIC_COMPRESS 0x000004 /* Check inside compressed files */
218 #define RZ_MAGIC_DEVICES 0x000008 /* Look at the contents of devices */
219 #define RZ_MAGIC_MIME_TYPE 0x000010 /* Return only the MIME type */
220 #define RZ_MAGIC_CONTINUE 0x000020 /* Return all matches */
221 #define RZ_MAGIC_CHECK 0x000040 /* Print warnings to stderr */
222 #define RZ_MAGIC_PRESERVE_ATIME 0x000080 /* Restore access time on exit */
223 #define RZ_MAGIC_RAW 0x000100 /* Don't translate unprint chars */
224 #define RZ_MAGIC_ERROR 0x000200 /* Handle ENOENT etc as real errors */
225 #define RZ_MAGIC_MIME_ENCODING 0x000400 /* Return only the MIME encoding */
226 #define RZ_MAGIC_MIME (RZ_MAGIC_MIME_TYPE | RZ_MAGIC_MIME_ENCODING)
227 #define RZ_MAGIC_NO_CHECK_COMPRESS 0x001000 /* Don't check for compressed files */
228 #define RZ_MAGIC_NO_CHECK_TAR 0x002000 /* Don't check for tar files */
229 #define RZ_MAGIC_NO_CHECK_SOFT 0x004000 /* Don't check magic entries */
230 #define RZ_MAGIC_NO_CHECK_APPTYPE 0x008000 /* Don't check application type */
231 #define RZ_MAGIC_NO_CHECK_ELF 0x010000 /* Don't check for elf details */
232 #define RZ_MAGIC_NO_CHECK_ASCII 0x020000 /* Don't check for ascii files */
233 #define RZ_MAGIC_NO_CHECK_TOKENS 0x100000 /* Don't check ascii/tokens */
234 
235 /* Defined for backwards compatibility; do nothing */
236 #define MAGIC_NO_CHECK_FORTRAN 0x000000 /* Don't check ascii/fortran */
237 #define MAGIC_NO_CHECK_TROFF 0x000000 /* Don't check ascii/troff */
238 
239 struct rz_magic_set {
240  struct mlist *mlist;
241  struct cont {
242  size_t len;
243  struct level_info {
244  st32 off;
245  int got_match;
246  int last_match;
247  int last_cond; /* used for error checking by parse() */
248  } * li;
249  } c;
250  struct out {
251  char *buf; /* Accumulation buffer */
252  char *pbuf; /* Printable buffer */
253  } o;
254  ut32 offset;
255  int error;
256  int flags;
257  int haderr;
258  const char *file;
259  size_t line; /* current magic line number */
260 
261  /* data for searches */
262  struct {
263  const char *s; /* start of search in original source */
264  size_t s_len; /* length of search region */
265  size_t offset; /* starting offset in source: XXX - should this be off_t? */
266  size_t rm_len; /* match length */
267  } search;
268 
269  /* FIXME: Make the string dynamically allocated so that e.g.
270  strings matched in files can be longer than MAXstring */
271  union VALUETYPE ms_value; /* either number or string */
272 };
273 
274 #if USE_LIB_MAGIC
275 #define RzMagic struct magic_set
276 #else
277 typedef struct rz_magic_set RzMagic;
278 #endif
279 
280 #ifdef RZ_API
281 RZ_API RzMagic *rz_magic_new(int flags);
282 RZ_API void rz_magic_free(RzMagic *);
283 
284 RZ_API const char *rz_magic_file(RzMagic *, const char *);
285 RZ_API const char *rz_magic_descriptor(RzMagic *, int);
286 RZ_API const char *rz_magic_buffer(RzMagic *, const void *, size_t);
287 
288 RZ_API const char *rz_magic_error(RzMagic *);
289 RZ_API void rz_magic_setflags(RzMagic *, int);
290 
291 RZ_API bool rz_magic_load(RzMagic *, const char *);
292 RZ_API bool rz_magic_load_buffer(RzMagic *, const char *);
293 RZ_API bool rz_magic_compile(RzMagic *, const char *);
294 RZ_API bool rz_magic_check(RzMagic *, const char *);
295 RZ_API int rz_magic_errno(RzMagic *);
296 #endif
297 
298 #endif
299 
300 #ifdef __cplusplus
301 }
302 #endif
303 
304 #endif /* _MAGIC_H */
size_t len
Definition: 6502dis.c:15
const char * desc
Definition: bin_vsf.c:19
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
void search()
Definition: cabinfo.c:91
static int value
Definition: cmd_api.c:93
#define RZ_API
uint16_t ut16
uint32_t ut32
voidpf uLong offset
Definition: ioapi.h:144
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
RZ_API const char * rz_magic_descriptor(RzMagic *ms, int fd)
Definition: magic.c:300
RZ_API int rz_magic_errno(RzMagic *ms)
Definition: magic.c:325
RZ_API const char * rz_magic_buffer(RzMagic *ms, const void *buf, size_t nb)
Definition: magic.c:308
RZ_API const char * rz_magic_file(RzMagic *ms, const char *inname)
Definition: magic.c:304
RZ_API bool rz_magic_check(RzMagic *ms, const char *magicfile)
Definition: magic.c:294
RZ_API RzMagic * rz_magic_new(int flags)
Definition: magic.c:235
RZ_API bool rz_magic_compile(RzMagic *ms, const char *magicfile)
Definition: magic.c:288
RZ_API bool rz_magic_load_buffer(RzMagic *ms, const char *magicdata)
Definition: magic.c:264
RZ_API bool rz_magic_load(RzMagic *ms, const char *magicfile)
Definition: magic.c:278
RZ_API void rz_magic_setflags(RzMagic *ms, int flags)
Definition: magic.c:332
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
int type
Definition: mipsasm.c:17
line
Definition: setup.py:34
int off
Definition: pal.c:13
static RzSocket * s
Definition: rtr.c:28
RZ_LIB_VERSION_HEADER(rz_magic)
#define st32
Definition: rz_types_base.h:12
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
#define d(i)
Definition: sha256.c:44
#define b(i)
Definition: sha256.c:42
#define f(i)
Definition: sha256.c:46
#define c(i)
Definition: sha256.c:43
#define h(i)
Definition: sha256.c:48
#define cond(bop, top, mask, flags)
void error(const char *msg)
Definition: untgz.c:593
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int file
Definition: z80asm.c:58