First of all, this is how dwFindPattern is implemented codewise (credit where credit is due):
Code:
bool bDataCompare(const BYTE* pData, const BYTE* bMask, const char* szMask)
{
for(;*szMask;++szMask,++pData,++bMask)
if(*szMask=='x' && *pData!=*bMask )
return false;
return (*szMask) == NULL;
}
DWORD dwFindPattern(DWORD dwAddress,DWORD dwLen,BYTE *bMask,char * szMask)
{
for(DWORD i=0; i < dwLen; i++)
if( bDataCompare( (BYTE*)( dwAddress+i ),bMask,szMask) )
return (DWORD)(dwAddress+i);
return 0;
}
Lets assume you have indentified a static addresss that contains relevant information (.data:012EF7A0 TlsIndex in this example) Heres a snippet from the code section inside wow:
Code:
.text:0046BA53 mov eax, TlsIndex
.text:0046BA58 mov eax, [ecx+eax*4]
.text:0046BA5B mov ecx, [eax+8]
.text:0046BA61 mov edx, [ebp+arg_0]
.text:0046BA64 cmp edx, ecx
The same snippet in Hex-View
Code:
.text:0046BA50 00 00 00 A1 A0 F7 2E 01 8B 04 81 8B 88 08 00 00 ...íá¸.ïüïê..
.text:0046BA60 00 8B 55 08 3B D1 74 0C 89 0D E4 60 01 01 89 90 .ïU;**të
õ`ëÉ
The code starts at 0046BA53 and ends at 0046BA64 so the assembled version of the snippet above would be (I might be off by one byte)
Code:
A1 (mov eax)
A0 F7 2E 01 (012EF7A0)
8B 04 81 8B 88 08 00 00 00 8B 55 08 3B (all the rest)
In this snippet, the only thing that will likely change every patch is the address of TLSIndex (012EF7A0), everything else is statically assembled.
The FindPattern for TLSIndex would look like this:
Code:
DWORD address = dwFindPattern(0x40000,0x800000,(BYTE*)"\xA1\xA0\xF7\x2E\x01\x8B\x04\x81\x8B\x88\x08\x00\x00\x00\x8B\x55\x08\x3B","x????xxxxxxxxxxxxx");
address += 0x1;
The first paramenter is where to start searching, ideally this would be the programs startaddress. Param2 is the size of the memory to be searching, ideally this would be the programs total size in memory.
For this example I just assumed two values.
Param3 is the byte-string we previously extracted, Param4 tells the function which parts in the byte-string to ignore (a '?' means ignore it).
Lastly we add 1 to the adress it returns because it would point to the beginning of the byte-string which in this case is not the address were looking for (Im actually not very sure on this part but I think it would return an address that points to 0xA1 so adding 0x1 makes it point to TLSIndex).
Hopefully this gave you an idea on how FindPattern works, I havent actually implemented this into any of my programs yet so I might be wrong on some parts. Please do correct me if Im wrong.