Hello guys
------------
I decided to release the IDA supported pattern/signature scanner here..
After benchmarking it, it took only 200 ms.
------------------
Code:
template <typename T> inline bool InRange(T Target, T Min, T Max)
{
if (Target >= Min && Target <= Max)
return true;
return false;
}
inline char GetBit(char cTarget)
{
if (InRange(cTarget, '0', '9'))
{
return (cTarget - '0');
}
return ((cTarget&(~0x20)) - 'A' + 0xa);
}
inline uint8_t GetByte(uint8_t* Target)
{
return (GetBit(Target[0]) << 4 | GetBit(Target[1]));
}
size_t PatternConvert(uint8_t* charArray, uint8_t* byteArray)
{
size_t len = 0;
for (size_t skip(3); *charArray; charArray += skip, ++len) //Skipping through characters of the array
{
if (*charArray == '\?') //If it equals a "?" wild card (mask)
{
byteArray[len] = '?'; //Store this mask in the byte array
skip = (*charArray == '\?\?') ? 3 : 2; //Skip 2 characters if its only one wild card, but if it is 2 wild cards then skip 3 characters
continue;
}
byteArray[len] = GetByte(charArray); //Convert the pattern
skip = 3; //Skip 3 characters in the char arraty
}
return len;
}
bool FullMatch(uint8_t* Array, uint8_t* Pattern, size_t l)
{
for (size_t c(0); c < l; c++)
{
if (Pattern[c] != '?' && Pattern[c] != Array[c]) // If It isn't equal to a wildcard and it doesn't equal to the pattern we have
return false;
}
return true;
}
DWORD FindPattern(uint8_t* pPattern, uint8_t* scanStart, size_t scanSize)
{
uint8_t* cPattern = new uint8_t[strlen(reinterpret_cast<char*>(pPattern))]; // Allocate the size of the original pattern
const size_t strLength = PatternConvert(pPattern, cPattern); // Convert it to byte array
uint8_t* pCurrent = scanStart; //Store the current scan in the scan start
for (; pCurrent < scanStart + scanSize - strLength; ++pCurrent) // Loop through memory to find the pattern
{
if (Pattern::FullMatch(pCurrent, cPattern, strLength))
{
delete[] cPattern;
return reinterpret_cast<DWORD>(pCurrent);
}
}
return NULL;
}