📄 softmagic.c
字号:
case FILE_OPADD: offset = (int32_t)((p->hl[3]<<24)| (p->hl[2]<<16)| (p->hl[1]<<8)| (p->hl[0])) + off; break; case FILE_OPMINUS: offset = (int32_t)((p->hl[3]<<24)| (p->hl[2]<<16)| (p->hl[1]<<8)| (p->hl[0])) - off; break; case FILE_OPMULTIPLY: offset = (int32_t)((p->hl[3]<<24)| (p->hl[2]<<16)| (p->hl[1]<<8)| (p->hl[0])) * off; break; case FILE_OPDIVIDE: offset = (int32_t)((p->hl[3]<<24)| (p->hl[2]<<16)| (p->hl[1]<<8)| (p->hl[0])) / off; break; case FILE_OPMODULO: offset = (int32_t)((p->hl[3]<<24)| (p->hl[2]<<16)| (p->hl[1]<<8)| (p->hl[0])) % off; break; } } else offset = (int32_t)((p->hl[3]<<24)| (p->hl[2]<<16)| (p->hl[1]<<8)| (p->hl[0])); if (m->in_op & FILE_OPINVERSE) offset = ~offset; break; case FILE_MELONG: if (nbytes < (offset + 4)) return 0; if (off) { switch (m->in_op & FILE_OPS_MASK) { case FILE_OPAND: offset = (int32_t)((p->hl[1]<<24)| (p->hl[0]<<16)| (p->hl[3]<<8)| (p->hl[2])) & off; break; case FILE_OPOR: offset = (int32_t)((p->hl[1]<<24)| (p->hl[0]<<16)| (p->hl[3]<<8)| (p->hl[2])) | off; break; case FILE_OPXOR: offset = (int32_t)((p->hl[1]<<24)| (p->hl[0]<<16)| (p->hl[3]<<8)| (p->hl[2])) ^ off; break; case FILE_OPADD: offset = (int32_t)((p->hl[1]<<24)| (p->hl[0]<<16)| (p->hl[3]<<8)| (p->hl[2])) + off; break; case FILE_OPMINUS: offset = (int32_t)((p->hl[1]<<24)| (p->hl[0]<<16)| (p->hl[3]<<8)| (p->hl[2])) - off; break; case FILE_OPMULTIPLY: offset = (int32_t)((p->hl[1]<<24)| (p->hl[0]<<16)| (p->hl[3]<<8)| (p->hl[2])) * off; break; case FILE_OPDIVIDE: offset = (int32_t)((p->hl[1]<<24)| (p->hl[0]<<16)| (p->hl[3]<<8)| (p->hl[2])) / off; break; case FILE_OPMODULO: offset = (int32_t)((p->hl[1]<<24)| (p->hl[0]<<16)| (p->hl[3]<<8)| (p->hl[2])) % off; break; } } else offset = (int32_t)((p->hl[1]<<24)| (p->hl[0]<<16)| (p->hl[3]<<8)| (p->hl[2])); if (m->in_op & FILE_OPINVERSE) offset = ~offset; break; case FILE_LONG: if (nbytes < (offset + 4)) return 0; if (off) { switch (m->in_op & FILE_OPS_MASK) { case FILE_OPAND: offset = p->l & off; break; case FILE_OPOR: offset = p->l | off; break; case FILE_OPXOR: offset = p->l ^ off; break; case FILE_OPADD: offset = p->l + off; break; case FILE_OPMINUS: offset = p->l - off; break; case FILE_OPMULTIPLY: offset = p->l * off; break; case FILE_OPDIVIDE: offset = p->l / off; break; case FILE_OPMODULO: offset = p->l % off; break; /* case TOOMANYSWITCHBLOCKS: * ugh = p->eye % m->strain; * rub; * case BEER: * off = p->tab & m->in_gest; * sleep; */ } } else offset = p->l; if (m->in_op & FILE_OPINVERSE) offset = ~offset; break; } if (m->flag & INDIROFFADD) offset += ms->c.li[cont_level-1].off; if (mcopy(ms, p, m->type, 0, s, offset, nbytes, count) == -1) return -1; ms->offset = offset; if ((ms->flags & MAGIC_DEBUG) != 0) { mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE)); file_mdump(m); } } /* Verify we have enough data to match magic type */ switch (m->type) { case FILE_BYTE: if (nbytes < (offset + 1)) /* should alway be true */ return 0; break; case FILE_SHORT: case FILE_BESHORT: case FILE_LESHORT: if (nbytes < (offset + 2)) return 0; break; case FILE_LONG: case FILE_BELONG: case FILE_LELONG: case FILE_MELONG: case FILE_DATE: case FILE_BEDATE: case FILE_LEDATE: case FILE_MEDATE: case FILE_LDATE: case FILE_BELDATE: case FILE_LELDATE: case FILE_MELDATE: if (nbytes < (offset + 4)) return 0; break; case FILE_STRING: case FILE_PSTRING: case FILE_SEARCH: if (nbytes < (offset + m->vallen)) return 0; break; case FILE_REGEX: if (nbytes < offset) return 0; break; case FILE_DEFAULT: /* nothing to check */ default: break; } if (!mconvert(ms, m)) return 0; return 1;}private uint64_tfile_strncmp(const char *s1, const char *s2, size_t len, uint32_t flags){ /* * Convert the source args to unsigned here so that (1) the * compare will be unsigned as it is in strncmp() and (2) so * the ctype functions will work correctly without extra * casting. */ const unsigned char *a = (const unsigned char *)s1; const unsigned char *b = (const unsigned char *)s2; uint64_t v; /* * What we want here is: * v = strncmp(m->value.s, p->s, m->vallen); * but ignoring any nulls. bcmp doesn't give -/+/0 * and isn't universally available anyway. */ v = 0; if (0L == flags) { /* normal string: do it fast */ while (len-- > 0) if ((v = *b++ - *a++) != '\0') break; } else { /* combine the others */ while (len-- > 0) { if ((flags & STRING_IGNORE_LOWERCASE) && islower(*a)) { if ((v = tolower(*b++) - *a++) != '\0') break; } else if ((flags & STRING_IGNORE_UPPERCASE) && isupper(*a)) { if ((v = toupper(*b++) - *a++) != '\0') break; } else if ((flags & STRING_COMPACT_BLANK) && isspace(*a)) { a++; if (isspace(*b++)) { while (isspace(*b)) b++; } else { v = 1; break; } } else if ((flags & STRING_COMPACT_OPTIONAL_BLANK) && isspace(*a)) { a++; while (isspace(*b)) b++; } else { if ((v = *b++ - *a++) != '\0') break; } } } return v;}private uint64_tfile_strncmp16(const char *a, const char *b, size_t len, uint32_t flags){ /* * XXX - The 16-bit string compare probably needs to be done * differently, especially if the flags are to be supported. * At the moment, I am unsure. */ flags = 0; return file_strncmp(a, b, len, flags);}private intmagiccheck(struct magic_set *ms, struct magic *m){ uint64_t l = m->value.q; uint64_t v; int matched; union VALUETYPE *p = &ms->ms_value; switch (m->type) { case FILE_BYTE: v = p->b; break; case FILE_SHORT: case FILE_BESHORT: case FILE_LESHORT: v = p->h; break; case FILE_LONG: case FILE_BELONG: case FILE_LELONG: case FILE_MELONG: case FILE_DATE: case FILE_BEDATE: case FILE_LEDATE: case FILE_MEDATE: case FILE_LDATE: case FILE_BELDATE: case FILE_LELDATE: case FILE_MELDATE: v = p->l; break; case FILE_QUAD: case FILE_LEQUAD: case FILE_BEQUAD: case FILE_QDATE: case FILE_BEQDATE: case FILE_LEQDATE: case FILE_QLDATE: case FILE_BEQLDATE: case FILE_LEQLDATE: v = p->q; break; case FILE_DEFAULT: l = 0; v = 0; break; case FILE_STRING: case FILE_PSTRING: l = 0; v = file_strncmp(m->value.s, p->s, (size_t)m->vallen, m->str_flags); break; case FILE_BESTRING16: case FILE_LESTRING16: l = 0; v = file_strncmp16(m->value.s, p->s, (size_t)m->vallen, m->str_flags); break; case FILE_SEARCH: { /* search ms->search.s for the string m->value.s */ size_t slen; size_t idx; if (ms->search.s == NULL) return 0; slen = MIN(m->vallen, sizeof(m->value.s)); l = 0; v = 0; ms->search.offset = m->offset; for (idx = 0; m->str_count == 0 || idx < m->str_count; idx++) { if (slen + idx > ms->search.s_len) break; v = file_strncmp(m->value.s, ms->search.s + idx, slen, m->str_flags); if (v == 0) { /* found match */ ms->search.offset = m->offset + idx; break; } } break; } case FILE_REGEX: { int rc; regex_t rx; char errmsg[512]; if (ms->search.s == NULL) return 0; l = 0; rc = regcomp(&rx, m->value.s, REG_EXTENDED|REG_NEWLINE| ((m->str_flags & STRING_IGNORE_CASE) ? REG_ICASE : 0)); if (rc) { (void)regerror(rc, &rx, errmsg, sizeof(errmsg)); file_magerror(ms, "regex error %d, (%s)", rc, errmsg); v = (uint64_t)-1; } else { regmatch_t pmatch[1];#ifndef REG_STARTEND#define REG_STARTEND 0 size_t l = ms->search.s_len - 1; char c = ms->search.s[l]; ((char *)(intptr_t)ms->search.s)[l] = '\0';#else pmatch[0].rm_so = 0; pmatch[0].rm_eo = ms->search.s_len;#endif rc = regexec(&rx, (const char *)ms->search.s, 1, pmatch, REG_STARTEND);#if REG_STARTEND == 0 ((char *)(intptr_t)ms->search.s)[l] = c;#endif switch (rc) { case 0: ms->search.s += (int)pmatch[0].rm_so; ms->search.offset += (size_t)pmatch[0].rm_so; ms->search.rm_len = (size_t)(pmatch[0].rm_eo - pmatch[0].rm_so); v = 0; break; case REG_NOMATCH: v = 1; break; default: (void)regerror(rc, &rx, errmsg, sizeof(errmsg)); file_magerror(ms, "regexec error %d, (%s)", rc, errmsg); v = (uint64_t)-1; break; } regfree(&rx); } if (v == (uint64_t)-1) return -1; break; } default: file_magerror(ms, "invalid type %d in magiccheck()", m->type); return -1; } v = file_signextend(ms, m, v); switch (m->reln) { case 'x': if ((ms->flags & MAGIC_DEBUG) != 0) (void) fprintf(stderr, "%llu == *any* = 1\n", (unsigned long long)v); matched = 1; break; case '!': matched = v != l; if ((ms->flags & MAGIC_DEBUG) != 0) (void) fprintf(stderr, "%llu != %llu = %d\n", (unsigned long long)v, (unsigned long long)l, matched); break; case '=': matched = v == l; if ((ms->flags & MAGIC_DEBUG) != 0) (void) fprintf(stderr, "%llu == %llu = %d\n", (unsigned long long)v, (unsigned long long)l, matched); break; case '>': if (m->flag & UNSIGNED) { matched = v > l; if ((ms->flags & MAGIC_DEBUG) != 0) (void) fprintf(stderr, "%llu > %llu = %d\n", (unsigned long long)v, (unsigned long long)l, matched); } else { matched = (int64_t) v > (int64_t) l; if ((ms->flags & MAGIC_DEBUG) != 0) (void) fprintf(stderr, "%lld > %lld = %d\n", (long long)v, (long long)l, matched); } break; case '<': if (m->flag & UNSIGNED) { matched = v < l; if ((ms->flags & MAGIC_DEBUG) != 0) (void) fprintf(stderr, "%llu < %llu = %d\n", (unsigned long long)v, (unsigned long long)l, matched); } else { matched = (int64_t) v < (int64_t) l; if ((ms->flags & MAGIC_DEBUG) != 0) (void) fprintf(stderr, "%lld < %lld = %d\n", (long long)v, (long long)l, matched); } break; case '&': matched = (v & l) == l; if ((ms->flags & MAGIC_DEBUG) != 0) (void) fprintf(stderr, "((%llx & %llx) == %llx) = %d\n", (unsigned long long)v, (unsigned long long)l, (unsigned long long)l, matched); break; case '^': matched = (v & l) != l; if ((ms->flags & MAGIC_DEBUG) != 0) (void) fprintf(stderr, "((%llx & %llx) != %llx) = %d\n", (unsigned long long)v, (unsigned long long)l, (unsigned long long)l, matched); break; default: matched = 0; file_magerror(ms, "cannot happen: invalid relation `%c'", m->reln); return -1; } return matched;}private intprint_sep(struct magic_set *ms, int firstline){ if (firstline) return 0; /* * we found another match * put a newline and '-' to do some simple formatting */ return file_printf(ms, "\n- ");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -