Are you tied to using an array of bytes for the signature? You might consider modifying your signature structure to something like:
Code:
struct signature_chunk {
char *bytes; // null here signifies end of list
int offset;
int len;
};
Then, each signature is an array of these elements, like so:
Code:
struct signature_chunk sig[] = {
{{0x20, 0xE6, 0xEA, 0x19, 0xBE, 0x28}, 0, 6},
{{0x13}, 10, 1},
{{0x20, 0x39, 0xEA, 0x19, 0xBE, 0x28}, 12, 6},
{0x13}, 22, 1},
{{0x11}, 24, 1},
{{0x11}, 26, 1},
{{0x16, 0x1F, 0x40, 0x28}, 28, 4}
{{0x26}, 36, 1},
{NULL, -1, -1} // end of list marker
};
You can use Tater's method of finding possible starts by scanning your input for sig[0].bytes[0]. Once you've found a possible start, you can loop through each chunk of your signature and do something like
Code:
loop through each byte of file // index i
if the current byte in file matches the first byte of the first chunk of our signature
for each chunk in our signature // index j
if (memcmp(file[i + sig[j].offset], sig[j].bytes, sig[j].len)) {
// memcmp failed, so this doesnt match the signature
This saves you in at least two ways. First, you don't waste time checking for "wildcard" bytes in the signature to tell you to ignore that byte in file. You just don't check them. Second, you are leveraging the optimized library routine memcmp instead of writing your own, less optimal version. Combine this with some tips from other posters, like using pointer arithmetic instead of array indexes, and caching values you will use multiple times throughout your function, and you should be in decent shape. You should be able to extend this to multiple signatures if need be by creating an array of arrays of signature chunks.
Since I'm guessing you actually have a number of signatures, you may want to make an array of