bool sig_scanner::search(BYTE key, const TCHAR string[], char offset)
{
#ifdef UNICODE
DWORD s_length = wcslen(string);// Pattern's length
#else
DWORD s_length = strlen(string);// Pattern's length
#endif
if (s_length % 2 != 0 || s_length < 2 || !this->BaseAddress || !this->EndAddress) return NULL;// Invalid operation
DWORD length = s_length / 2;// Number of bytes
s_length++;// +1 for the null terminated string
// The buffer is storing the real bytes' values after parsing the string
BYTE* buffer = new BYTE[length];
ZeroMemory(buffer, length);
// Copy of string, making it to uppercase
TCHAR* pattern = new TCHAR[s_length];
//ZeroMemory(pattern, p_length);
#ifdef UNICODE
wcscpy_s(pattern, s_length, string);
_wcsupr_s(pattern, s_length);
#else
strcpy_s(pattern, s_length, string);
_strupr_s(pattern, s_length);
#endif
// Parsing of string
DWORD i;
for (i = 0; i < length; i++)
{
BYTE f_byte = (BYTE)pattern[i*2];// First byte
BYTE s_byte = (BYTE)pattern[(i*2)+1];// Second byte
if ( ( (f_byte <= 'F' && f_byte >= 'A') || (f_byte <= '9' && f_byte >= '0') ) && ( (s_byte <= 'F' && s_byte >= 'A') || (s_byte <= '9' && s_byte >= '0') ) )
{
if (f_byte <= '9') buffer[i] += f_byte - '0';
else buffer[i] += f_byte - 'A' + 10;
buffer[i] *= 16;
if (s_byte <= '9') buffer[i] += s_byte - '0';
else buffer[i] += s_byte - 'A' + 10;
}
else if (f_byte == 'X' || s_byte == 'X') buffer[i] = 'X';
else buffer[i] = '?';// Wildcard
}
// Remove buffer
delete[] pattern;
// Start searching
i = this->BaseAddress;
MEMORY_BASIC_INFORMATION meminfo;
DWORD ret = NULL;
WORD x;
DWORD EOR;
while (i < this->EndAddress)
{
if (!VirtualQuery((LPVOID)i, &meminfo, sizeof(meminfo))) break;
//while (!VirtualQuery((LPVOID)i, &meminfo, sizeof(meminfo)))
// Sleep(100);
if (!(meminfo.Protect &(PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY | PAGE_EXECUTE_READ)) || !(meminfo.State &MEM_COMMIT))
{
i += meminfo.RegionSize;
continue;
}
EOR = i + meminfo.RegionSize;
for (; i < EOR; i++)
{
for (x = 0; x < length; x++)
if (buffer[x] != '?' && buffer[x] != 'X')
if (buffer[x] != ((BYTE*)i)[x])
break;
if (x == length)
{
#ifdef UNICODE
const wchar_t* s_offset = wcsstr(string, L"X");
#else
const char* s_offset = strstr(string, "X");
#endif
if (s_offset != NULL)
{
#ifdef UNICODE
ret = *(DWORD*)&((BYTE*)i)[length - wcslen(s_offset) / 2];
#else
ret = *(DWORD*)&((BYTE*)i)[length - strlen(s_offset) / 2];
#endif
}
else ret = *(DWORD*)&((BYTE*)i)[length + offset];
goto output;// Need to break twice which isn't possible with C++
}
}
}
// Output results
output:
delete[] buffer;
if (!ret) throw key;
this->insert(key, ret);
return true;
}