rizin/librz/search/bytepat.c
2025-03-10 23:24:30 +08:00

135 lines
3.1 KiB
C

// SPDX-FileCopyrightText: 2006-2019 esteve <eslack.org>
// SPDX-FileCopyrightText: 2006-2019 pancake <pancake@nopcode.org>
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_search.h>
#include <rz_util.h>
#include <rz_util/rz_print.h>
#define CTXMINB 5
#define BSIZE (1024 * 1024)
#define MAX_PATLEN 1024
typedef struct _fnditem {
unsigned char str[MAX_PATLEN];
void *next;
} fnditem;
static fnditem *init_fi(void) {
fnditem *n;
n = (fnditem *)malloc(sizeof(fnditem));
if (!n) {
return NULL;
}
n->next = NULL;
return n;
}
static void fini_fi(fnditem *fi) {
fnditem *fu;
fu = fi;
while (fi->next) {
fu = fi;
fi = fi->next;
free(fu);
fu = NULL;
}
free(fu);
}
static void add_fi(fnditem *n, unsigned char *blk, int patlen) {
fnditem *p;
for (p = n; p->next != NULL; p = p->next) {
;
}
p->next = (fnditem *)malloc(sizeof(fnditem));
p = p->next;
memcpy(p->str, blk, patlen);
p->next = NULL;
}
static int is_fi_present(fnditem *n, unsigned char *blk, int patlen) {
fnditem *p;
for (p = n; p->next != NULL; p = p->next) {
if (!memcmp(blk, p->str, patlen)) {
return true;
}
}
return false;
}
RZ_API bool rz_search_pattern(RzSearch *s, ut64 from, ut64 to) {
ut8 block[BSIZE + MAX_PATLEN], sblk[BSIZE + MAX_PATLEN + 1];
ut64 addr, bact, bytes, intaddr, rb, bproc = 0;
int nr, i, moar = 0, pcnt, cnt = 0, k = 0;
int patlen = s->pattern_size;
fnditem *root;
eprintf("Searching patterns between 0x%08" PFMT64x " and 0x%08" PFMT64x "\n", from, to);
if (patlen < 1 || patlen > MAX_PATLEN) {
eprintf("Invalid pattern length (must be > 1 and < %d)\n", MAX_PATLEN);
return false;
}
bact = from;
bytes = to;
// bytes += bact;
root = init_fi();
pcnt = -1;
// bact = from
// bytes = to
// bproc = from2
while (bact < bytes) {
addr = bact;
if (rz_print_is_interrupted()) {
break;
}
bproc = bact + patlen;
// read ( fd, sblk, patlen );
// XXX bytepattern should be used with a read callback
nr = ((bytes - bproc) < BSIZE) ? (bytes - bproc) : BSIZE;
// XXX rizin_read_at(bact, sblk, patlen);
s->iob.read_at(s->iob.io, addr, sblk, nr);
sblk[patlen] = 0; // XXX
intaddr = bact;
cnt = 0;
while (bproc < bytes) {
// TODO: handle ^C here
nr = ((bytes - bproc) < BSIZE) ? (bytes - bproc) : BSIZE;
nr += (patlen - (nr % patlen)); // tamany de bloc llegit multiple superior de tamany busqueda
rb = s->iob.read_at(s->iob.io, bproc, block, nr);
if (rb < 1) {
break;
}
nr = rb;
addr += nr;
moar = 0;
for (i = 0; i < nr; i++) {
if (!memcmp(&block[i], sblk, patlen) && !is_fi_present(root, sblk, patlen)) {
if (cnt == 0) {
add_fi(root, sblk, patlen);
pcnt++;
eprintf("\nbytes: %d: ", pcnt);
for (k = 0; k < patlen; k++) {
eprintf("%02x", sblk[k]);
}
eprintf("\nfound: %d: 0x%08" PFMT64x " ", pcnt, intaddr);
}
moar++;
cnt++;
eprintf("0x%08" PFMT64x " ", bproc + i);
}
}
if (moar > 0) {
eprintf("\ncount: %d: %d\n", pcnt, moar + 1);
}
bproc += rb;
}
bact += (moar > 0) ? patlen : 1;
}
eprintf("\n");
fini_fi(root);
return true;
}