Help Converting FindPattern Functions

Just starting out? Need help? Post your questions and find answers here.
MyNameBorat
New User
New User
Posts: 3
Joined: Mon Nov 25, 2013 11:24 pm

Help Converting FindPattern Functions

Post by MyNameBorat »

ello, I am working on a plugin for a game. And am in need to using signatures to pull offsets from the game. As coding offsets directly into the plugin will cause the plugin to break after future updates (new offsets). So the purpose of it is to keep the plugin compatible with a majority of future versions without needing to update the plugin any (only rarely). I am need of help converting a few C++ functions to the PureBasic equivalent. Here is the basic FindPattern() function that is standard in plugin and mod development.

Code: Select all

BOOL DataCompare( BYTE* pData, BYTE* bMask, char * szMask )
{
    for( ; *szMask; ++szMask, ++pData, ++bMask )
         if( *szMask == 'x' && *pData != *bMask )
                return FALSE;

    return ( *szMask == NULL );
}

DWORD CTools::FindPattern( DWORD dwAddress, DWORD dwLen, BYTE *bMask, char * szMask )
{
    for( DWORD i = 0; i < dwLen; i++ )
         if( DataCompare( (BYTE*)( dwAddress + i ), bMask, szMask ) )
             return (DWORD)( dwAddress + i );

    return 0;
}
Usage:

Code: Select all

FindPattern( DWORD dwAddress, DWORD dwLen, BYTE *bMask, char * szMask )
Hope its not too much to ask for. I can handle the signatures, masks, and the rest of that on my own.

Greets. :)
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Help Converting FindPattern Functions

Post by Danilo »

:?:

Code: Select all

Procedure DataCompare(*pData.Byte, *bMask.Byte, *szMask.Ascii)
    While *szMask\a
         If *szMask\a = 'x' And (*pData\b <> *bMask\b)
             ProcedureReturn #False
         EndIf
         *szMask + 1
         *pData  + 1
         *bMask  + 1
    Wend
    ProcedureReturn Bool( *szMask\a = 0 )
EndProcedure

Procedure FindPattern(dwAddress, dwLen, *bMask.Byte, *szMask.Ascii)
    Protected i = 0
    While i < dwLen
         If DataCompare( dwAddress + i, *bMask, *szMask )
             ProcedureReturn dwAddress + i
         EndIf
         i + 1
    Wend

    ProcedureReturn 0
EndProcedure
MyNameBorat
New User
New User
Posts: 3
Joined: Mon Nov 25, 2013 11:24 pm

Re: Help Converting FindPattern Functions

Post by MyNameBorat »

Danilo wrote::?:

Code: Select all

Procedure DataCompare(*pData.Byte, *bMask.Byte, *szMask.Ascii)
    While *szMask\a
         If *szMask\a = 'x' And (*pData\b <> *bMask\b)
             ProcedureReturn #False
         EndIf
         *szMask + 1
         *pData  + 1
         *bMask  + 1
    Wend
    ProcedureReturn Bool( *szMask\a = 0 )
EndProcedure

Procedure FindPattern(dwAddress, dwLen, *bMask.Byte, *szMask.Ascii)
    Protected i = 0
    While i < dwLen
         If DataCompare( dwAddress + i, *bMask, *szMask )
             ProcedureReturn dwAddress + i
         EndIf
         i + 1
    Wend

    ProcedureReturn 0
EndProcedure
A quick example of passing the masks to the function?

Code: Select all

FindPattern((DWORD)GetModuleHandleA("Game.exe"),0xAddres,(PBYTE)"\x88\x4d\xff\x0f\xb6\x55\xff\x85\xd2\x00\x00\x0f\xb6\x45\x0c\x85","xxxxxxxxx??xxxxx");
Also these functions are suppose to read from memory. To compare the byte code to match up the signature to determine the offset. Isn't there suppose to be some PeekX() functions being used as well?

Regards.
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Help Converting FindPattern Functions

Post by Danilo »

MyNameBorat wrote:A quick example of passing the masks to the function?

Code: Select all

Procedure DataCompare(*pData.Byte, *bMask.Byte, *szMask.Ascii)
    While *szMask\a
         If *szMask\a = 'x' And (*pData\b <> *bMask\b)
             ProcedureReturn #False
         EndIf
         *szMask + 1
         *pData  + 1
         *bMask  + 1
    Wend
    ProcedureReturn Bool( *szMask\a = 0 )
EndProcedure

Procedure FindPattern(dwAddress, dwLen, *bMask.Byte, *szMask.Ascii)
    Protected i = 0
    While i < dwLen
         If DataCompare( dwAddress + i, *bMask, *szMask )
             ProcedureReturn dwAddress + i
         EndIf
         i + 1
    Wend

    ProcedureReturn 0
EndProcedure

DataSection
    bMask:
    Data.a $88,$4d,$ff,$0f,$b6,$55,$ff,$85,$d2,$00,$00,$0f,$b6,$45,$0c,$85
    szMask:
    Data.b 'x','x','x','x','x','x','x','x','x','?','?','x','x','x','x','x'
EndDataSection

*MemoryAddress = AllocateMemory(1024)
If *MemoryAddress
    
    CopyMemory(?bMask,*MemoryAddress+200,16) ; Copy bMask to memory position 200
    
    len = MemorySize(*MemoryAddress)-16
    result = FindPattern(*MemoryAddress,len,?bMask,?szMask)
    
    Debug "Result: "+Str(result)
    Debug "Result - *MemoryAddress: "+Str(result-*MemoryAddress)
    
EndIf

Now that I know szMask is a string in form "xxxx??xxx", it can get converted to string and is easier useable (Ascii+Unicode mode):

Code: Select all

Procedure DataCompare(*pData.Byte, *bMask.Byte, szMask.s)
    *szMask.Character = @szMask
    While *szMask\c
         If *szMask\c = 'x' And (*pData\b <> *bMask\b)
             ProcedureReturn #False
         EndIf
         *szMask + SizeOf(Character)
         *pData  + 1
         *bMask  + 1
    Wend
    ProcedureReturn Bool( *szMask\c = 0 )
EndProcedure

Procedure FindPattern(dwAddress, dwLen, *bMask.Byte, szMask.s)
    Protected i = 0
    While i < dwLen
         If DataCompare( dwAddress + i, *bMask, szMask )
             ProcedureReturn dwAddress + i
         EndIf
         i + 1
    Wend

    ProcedureReturn 0
EndProcedure

DataSection
    bytesToSearch_01:
    Data.a $88,$4d,$ff,$0f,$b6,$55,$ff,$85,$d2,$00,$00,$0f,$b6,$45,$0c,$85
EndDataSection

*MemoryAddress = AllocateMemory(1024)
If *MemoryAddress
    
    CopyMemory(?bytesToSearch_01,*MemoryAddress+321,16) ; Copy bytesToSearch_01 to memory position 321
    
    len = MemorySize(*MemoryAddress)-16
    result = FindPattern(*MemoryAddress,len,?bytesToSearch_01,"xxxxxxxxx??xxxxx")
    
    Debug "Result: "+Str(result)
    Debug "Result - *MemoryAddress: "+Str(result-*MemoryAddress)
    
EndIf

Debug "--------------------"
;
; Example 2
;
Dim memory.b(1000)
memory(800) = 'a'
memory(801) = 'b'
memory(802) = 'c'
memory(803) = 'd'
memory(804) = 'e'
memory(805) = 'f'

Dim bytesToSearch.b(6)
bytesToSearch(0) = 'a'
bytesToSearch(1) = 'b'
bytesToSearch(2) = 'c'
bytesToSearch(3) = 'x'
bytesToSearch(4) = 'x'
bytesToSearch(5) = 'f'


result = FindPattern(@memory(),1000-6,@bytesToSearch(),"xxx??x")
    
Debug "Result: "+Str(result)
Debug "Result - @memory(): "+Str(result-@memory())
MyNameBorat wrote:Also these functions are suppose to read from memory. To compare the byte code to match up the signature to determine the offset. Isn't there suppose to be some PeekX() functions being used as well?
It uses pointers directly, so no PeekX() required. I just translated the C code as is. ;)
MyNameBorat
New User
New User
Posts: 3
Joined: Mon Nov 25, 2013 11:24 pm

Re: Help Converting FindPattern Functions

Post by MyNameBorat »

Danilo wrote:-snip-
Got it working thanks! :D
Post Reply