Update patternfind.c

This commit is contained in:
zeffy
2018-03-26 02:35:32 -07:00
parent 8ccdd2a50b
commit 0523eb1b7b

View File

@@ -3,7 +3,9 @@
static inline bool isHex(char ch) static inline bool isHex(char ch)
{ {
return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f'); return (ch >= '0' && ch <= '9')
|| (ch >= 'A' && ch <= 'F')
|| (ch >= 'a' && ch <= 'f');
} }
static inline int hexchtoint(char ch) static inline int hexchtoint(char ch)
@@ -17,10 +19,14 @@ static inline int hexchtoint(char ch)
return -1; return -1;
} }
static inline size_t formathexpattern(const char *patterntext, char *formattext, size_t formattextsize) static inline size_t formathexpattern(const char *patterntext,
char *formattext,
size_t formattextsize)
{ {
size_t len = strlen(patterntext); size_t len;
size_t result = 0; size_t result = 0;
len = strlen(patterntext);
for ( size_t i = 0; i < len; i++ ) { for ( size_t i = 0; i < len; i++ ) {
if ( patterntext[i] == '?' || hexchtoint(patterntext[i]) != -1 ) { if ( patterntext[i] == '?' || hexchtoint(patterntext[i]) != -1 ) {
if ( formattext && result + 1 < formattextsize ) if ( formattext && result + 1 < formattextsize )
@@ -44,18 +50,24 @@ static inline size_t formathexpattern(const char *patterntext, char *formattext,
return result; return result;
} }
bool patterntransform(const char *patterntext, PatternByte *pattern, size_t patternsize) bool patterntransform(const char *patterntext,
PatternByte *pattern,
size_t patternsize)
{ {
size_t len;
size_t size;
char *formattext;
PatternByte newByte;
memset(pattern, 0, patternsize * (sizeof *pattern)); memset(pattern, 0, patternsize * (sizeof *pattern));
size_t len = formathexpattern(patterntext, NULL, 0); len = formathexpattern(patterntext, NULL, 0);
if ( !len || len / 2 > patternsize ) if ( !len || len / 2 > patternsize )
return false; return false;
size_t size = len + 1; size = len + 1;
char *formattext = malloc(size); formattext = malloc(size);
formathexpattern(patterntext, formattext, size); formathexpattern(patterntext, formattext, size);
PatternByte newByte;
for ( size_t i = 0, j = 0, k = 0; i < len && k <= patternsize; i++ ) { for ( size_t i = 0, j = 0, k = 0; i < len && k <= patternsize; i++ ) {
if ( formattext[i] == '?' ) { //wildcard if ( formattext[i] == '?' ) { //wildcard
@@ -78,14 +90,16 @@ bool patterntransform(const char *patterntext, PatternByte *pattern, size_t patt
static inline bool patternmatchbyte(uint8_t byte, const PatternByte pbyte) static inline bool patternmatchbyte(uint8_t byte, const PatternByte pbyte)
{ {
int matched = 0; int matched = 0;
uint8_t n1;
uint8_t n2;
uint8_t n1 = (byte >> 4) & 0xF; n1 = (byte >> 4) & 0xF;
if ( pbyte.nibble[0].wildcard ) if ( pbyte.nibble[0].wildcard )
matched++; matched++;
else if ( pbyte.nibble[0].data == n1 ) else if ( pbyte.nibble[0].data == n1 )
matched++; matched++;
uint8_t n2 = byte & 0xF; n2 = byte & 0xF;
if ( pbyte.nibble[1].wildcard ) if ( pbyte.nibble[1].wildcard )
matched++; matched++;
else if ( pbyte.nibble[1].data == n2 ) else if ( pbyte.nibble[1].data == n2 )
@@ -96,10 +110,13 @@ static inline bool patternmatchbyte(uint8_t byte, const PatternByte pbyte)
size_t patternfind(uint8_t *data, size_t datasize, const char *pattern) size_t patternfind(uint8_t *data, size_t datasize, const char *pattern)
{ {
size_t searchpatternsize = formathexpattern(pattern, NULL, 0) / 2; size_t searchpatternsize;
PatternByte *searchpattern = calloc(searchpatternsize, sizeof(PatternByte)); PatternByte *searchpattern;
size_t result = -1; size_t result = -1;
searchpatternsize = formathexpattern(pattern, NULL, 0) / 2;
searchpattern = calloc(searchpatternsize, sizeof *searchpattern);
if ( patterntransform(pattern, searchpattern, searchpatternsize) ) if ( patterntransform(pattern, searchpattern, searchpatternsize) )
result = patternfind_pbyte(data, datasize, searchpattern, searchpatternsize); result = patternfind_pbyte(data, datasize, searchpattern, searchpatternsize);
@@ -108,7 +125,10 @@ size_t patternfind(uint8_t *data, size_t datasize, const char *pattern)
} }
__declspec(noinline) __declspec(noinline)
size_t patternfind_bytes(uint8_t *data, size_t datasize, const uint8_t *pattern, size_t patternsize) size_t patternfind_bytes(uint8_t *data,
size_t datasize,
const uint8_t *pattern,
size_t patternsize)
{ {
if ( patternsize > datasize ) if ( patternsize > datasize )
patternsize = datasize; patternsize = datasize;
@@ -137,28 +157,38 @@ static inline void patternwritebyte(uint8_t *byte, const PatternByte pbyte)
*byte = ((n1 << 4) & 0xF0) | (n2 & 0xF); *byte = ((n1 << 4) & 0xF0) | (n2 & 0xF);
} }
void patternwrite(uint8_t *data, size_t datasize, const char *pattern) void patternwrite(uint8_t *data,
size_t datasize,
const char *pattern)
{ {
size_t writepatternsize = formathexpattern(pattern, NULL, 0) / 2; size_t writepatternsize;
PatternByte *writepattern = calloc(writepatternsize, sizeof(PatternByte)); PatternByte *writepattern;
DWORD fOldProtect;
writepatternsize = formathexpattern(pattern, NULL, 0) / 2;
writepattern = calloc(writepatternsize, sizeof *writepattern);
if ( patterntransform(pattern, writepattern, writepatternsize) ) { if ( patterntransform(pattern, writepattern, writepatternsize) ) {
DWORD OldProtect; VirtualProtect(data, writepatternsize, PAGE_EXECUTE_READWRITE, &fOldProtect);
BOOL result = VirtualProtect(data, writepatternsize, PAGE_EXECUTE_READWRITE, &OldProtect);
if ( writepatternsize > datasize ) if ( writepatternsize > datasize )
writepatternsize = datasize; writepatternsize = datasize;
for ( size_t i = 0; i < writepatternsize; i++ ) for ( size_t i = 0; i < writepatternsize; i++ )
patternwritebyte(&data[i], writepattern[i]); patternwritebyte(&data[i], writepattern[i]);
result = VirtualProtect(data, writepatternsize, OldProtect, &OldProtect); VirtualProtect(data, writepatternsize, fOldProtect, &fOldProtect);
FlushInstructionCache(GetCurrentProcess(), data, datasize); FlushInstructionCache(GetCurrentProcess(), data, datasize);
} }
free(writepattern); free(writepattern);
} }
bool patternsnr(uint8_t *data, size_t datasize, const char *searchpattern, const char *replacepattern) bool patternsnr(uint8_t *data,
size_t datasize,
const char *searchpattern,
const char *replacepattern)
{ {
size_t found = patternfind(data, datasize, searchpattern); size_t found;
found = patternfind(data, datasize, searchpattern);
if ( found == -1 ) if ( found == -1 )
return false; return false;
patternwrite(data + found, found - datasize, replacepattern); patternwrite(data + found, found - datasize, replacepattern);
@@ -166,7 +196,10 @@ bool patternsnr(uint8_t *data, size_t datasize, const char *searchpattern, const
} }
__declspec(noinline) __declspec(noinline)
size_t patternfind_pbyte(uint8_t *data, size_t datasize, const PatternByte *pattern, size_t searchpatternsize) size_t patternfind_pbyte(uint8_t *data,
size_t datasize,
const PatternByte *pattern,
size_t searchpatternsize)
{ {
for ( size_t i = 0, pos = 0; i < datasize; i++ ) { //search for the pattern for ( size_t i = 0, pos = 0; i < datasize; i++ ) { //search for the pattern
if ( patternmatchbyte(data[i], pattern[pos]) ) { //check if our pattern matches the current byte if ( patternmatchbyte(data[i], pattern[pos]) ) { //check if our pattern matches the current byte