1
0
Fork 0

DBG: fixed a bug with pattern finding

This commit is contained in:
Mr. eXoDia 2015-07-11 01:12:40 +02:00
parent f9ea03e863
commit 726bd25210
3 changed files with 78 additions and 49 deletions

View File

@ -1198,10 +1198,15 @@ CMDRESULT cbInstrFindAll(int argc, char* argv[])
int refCount = 0;
uint i = 0;
uint result = 0;
std::vector<PatternByte> searchpattern;
if(!patterntransform(pattern, searchpattern))
{
dputs("failed to transform pattern!");
return STATUS_ERROR;
}
while(refCount < 5000)
{
int patternsize = 0;
uint foundoffset = patternfind(data + start + i, find_size - i, pattern, &patternsize);
uint foundoffset = patternfind(data + start + i, find_size - i, searchpattern);
if(foundoffset == -1)
break;
i += foundoffset + 1;
@ -1212,9 +1217,9 @@ CMDRESULT cbInstrFindAll(int argc, char* argv[])
GuiReferenceSetCellContent(refCount, 0, msg);
if(findData)
{
Memory<unsigned char*> printData(patternsize, "cbInstrFindAll:printData");
MemRead((void*)result, printData, patternsize, 0);
for(int j = 0, k = 0; j < patternsize; j++)
Memory<unsigned char*> printData(searchpattern.size(), "cbInstrFindAll:printData");
MemRead((void*)result, printData(), printData.size(), 0);
for(size_t j = 0, k = 0; j < printData.size(); j++)
{
if(j)
k += sprintf(msg + k, " ");

View File

@ -4,26 +4,22 @@
using namespace std;
struct PatternByte
static inline bool isHex(char ch)
{
struct PatternNibble
{
unsigned char data;
bool wildcard;
} nibble[2];
};
return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f');
}
static string formathexpattern(string patterntext)
static inline string formathexpattern(const string & patterntext)
{
string result;
int len = (int)patterntext.length();
for(int i = 0; i < len; i++)
if(patterntext[i] == '?' || isxdigit(patterntext[i]))
result += toupper(patterntext[i]);
if(patterntext[i] == '?' || isHex(patterntext[i]))
result += patterntext[i];
return result;
}
static int hexchtoint(char ch)
static inline int hexchtoint(char ch)
{
if(ch >= '0' && ch <= '9')
return ch - '0';
@ -31,34 +27,34 @@ static int hexchtoint(char ch)
return ch - 'A' + 10;
else if(ch >= 'a' && ch <= 'f')
return ch - 'a' + 10;
return 0;
return -1;
}
static bool patterntransform(string patterntext, vector<PatternByte> & pattern)
bool patterntransform(const string & patterntext, vector<PatternByte> & pattern)
{
pattern.clear();
patterntext = formathexpattern(patterntext);
int len = (int)patterntext.length();
string formattext = formathexpattern(patterntext);
int len = (int)formattext.length();
if(!len)
return false;
if(len % 2) //not a multiple of 2
{
patterntext += '?';
formattext += '?';
len++;
}
PatternByte newByte;
for(int i = 0, j = 0; i < len; i++)
{
if(patterntext[i] == '?') //wildcard
if(formattext[i] == '?') //wildcard
{
newByte.nibble[j].wildcard = true; //match anything
}
else //hex
{
newByte.nibble[j].wildcard = false;
newByte.nibble[j].data = hexchtoint(patterntext[i]) & 0xF;
newByte.nibble[j].data = hexchtoint(formattext[i]) & 0xF;
}
j++;
@ -71,7 +67,7 @@ static bool patterntransform(string patterntext, vector<PatternByte> & pattern)
return true;
}
static bool patternmatchbyte(unsigned char byte, const PatternByte & pbyte)
static inline bool patternmatchbyte(unsigned char byte, const PatternByte & pbyte)
{
int matched = 0;
@ -90,32 +86,16 @@ static bool patternmatchbyte(unsigned char byte, const PatternByte & pbyte)
return (matched == 2);
}
size_t patternfind(unsigned char* data, size_t datasize, const char* pattern, int* patternsize)
size_t patternfind(const unsigned char* data, size_t datasize, const char* pattern, int* patternsize)
{
string patterntext(pattern);
vector<PatternByte> searchpattern;
if(!patterntransform(pattern, searchpattern))
if(!patterntransform(patterntext, searchpattern))
return -1;
size_t searchpatternsize = searchpattern.size();
if(patternsize)
*patternsize = (int)searchpatternsize;
for(size_t i = 0, pos = 0; i < datasize; i++) //search for the pattern
{
if(patternmatchbyte(data[i], searchpattern.at(pos))) //check if our pattern matches the current byte
{
pos++;
if(pos == searchpatternsize) //everything matched
return i - searchpatternsize + 1;
}
else if(pos > 0) //fix by Computer_Angel
{
i -= pos;
pos = 0; //reset current pattern position
}
}
return -1;
return patternfind(data, datasize, searchpattern);
}
size_t patternfind(unsigned char* data, size_t datasize, unsigned char* pattern, size_t patternsize)
size_t patternfind(const unsigned char* data, size_t datasize, unsigned char* pattern, size_t patternsize)
{
if(patternsize > datasize)
patternsize = datasize;
@ -136,7 +116,7 @@ size_t patternfind(unsigned char* data, size_t datasize, unsigned char* pattern,
return -1;
}
static void patternwritebyte(unsigned char* byte, const PatternByte & pbyte)
static inline void patternwritebyte(unsigned char* byte, const PatternByte & pbyte)
{
unsigned char n1 = (*byte >> 4) & 0xF;
unsigned char n2 = *byte & 0xF;
@ -150,7 +130,8 @@ static void patternwritebyte(unsigned char* byte, const PatternByte & pbyte)
void patternwrite(unsigned char* data, size_t datasize, const char* pattern)
{
vector<PatternByte> writepattern;
if(!patterntransform(pattern, writepattern))
string patterntext(pattern);
if(!patterntransform(patterntext, writepattern))
return;
size_t writepatternsize = writepattern.size();
if(writepatternsize > datasize)
@ -167,3 +148,23 @@ bool patternsnr(unsigned char* data, size_t datasize, const char* searchpattern,
patternwrite(data + found, datasize - found, replacepattern);
return true;
}
size_t patternfind(const unsigned char* data, size_t datasize, const std::vector<PatternByte> & pattern)
{
size_t searchpatternsize = pattern.size();
for(size_t i = 0, pos = 0; i < datasize; i++) //search for the pattern
{
if(patternmatchbyte(data[i], pattern.at(pos))) //check if our pattern matches the current byte
{
pos++;
if(pos == searchpatternsize) //everything matched
return i - searchpatternsize + 1;
}
else if(pos > 0) //fix by Computer_Angel
{
i -= pos;
pos = 0; //reset current pattern position
}
}
return -1;
}

View File

@ -1,9 +1,20 @@
#ifndef _PATTERNFIND_H
#define _PATTERNFIND_H
#include <vector>
struct PatternByte
{
struct PatternNibble
{
unsigned char data;
bool wildcard;
} nibble[2];
};
//returns: offset to data when found, -1 when not found
size_t patternfind(
unsigned char* data, //data
const unsigned char* data, //data
size_t datasize, //size of data
const char* pattern, //pattern to search
int* patternsize = 0 //outputs the number of bytes the pattern is
@ -11,7 +22,7 @@ size_t patternfind(
//returns: offset to data when found, -1 when not found
size_t patternfind(
unsigned char* data, //data
const unsigned char* data, //data
size_t datasize, //size of data
unsigned char* pattern, //bytes to search
size_t patternsize //size of bytes to search
@ -32,4 +43,16 @@ bool patternsnr(
const char* replacepattern //pattern to write
);
//returns: true on success, false on failure
bool patterntransform(const std::string & patterntext, //pattern string
std::vector<PatternByte> & pattern //pattern to feed to patternfind
);
//returns: offset to data when found, -1 when not found
size_t patternfind(
const unsigned char* data, //data
size_t datasize, //size of data
const std::vector<PatternByte> & pattern //pattern to search
);
#endif // _PATTERNFIND_H