View Single Post
  #1  
Old 02-09-2016, 08:50
atom0s's Avatar
atom0s atom0s is offline
Family
 
Join Date: Jan 2015
Location: 127.0.0.1
Posts: 435
Rept. Given: 26
Rept. Rcvd 130 Times in 67 Posts
Thanks Given: 55
Thanks Rcvd at 850 Times in 309 Posts
atom0s Reputation: 100-199 atom0s Reputation: 100-199
[C++] Pattern Scanner

I wrote a pattern scanner that makes use of C++11 features a while back and decided to adjust it to no longer require a mask be passed with it. Instead, the pattern is parsed for wildcards and handled accordingly.

This should be cross-platform and 64bit friendly.

PHP Code:

/**
 * Scans the given data for the pattern.
 *
 * @param {vector} data                     The data to scan within for the given pattern.
 * @param {intptr_t} baseAddress            The base address of where the scan is starting from.
 * @param {const char*} lpPattern           The pattern to scan for. (Wildcards are marked as ?? per byte.)
 * @param {intptr_t} offset                 The offset to add to the found location.
 * @param {intptr_t} resultUsage            The result offset to use when locating signatures that match multiple locations.
 * @returns {intptr_t}                      The address where the pattern was found, 0 otherwise.
 */
intptr_t FindPattern(std::vector<unsigned char> data, intptr_t baseAddress, const char* lpPattern, intptr_t offset, intptr_t resultUsage)
{
    
// Ensure the incoming pattern is properly aligned..
    
if (strlen(lpPattern) % 2 > 0)
        return 
0;

    
// Convert the pattern to a vector of data..
    
std::vector<std::pair<unsigned char, bool>> pattern;
    for (
size_t x = 0, y = strlen(lpPattern) / 2; x < y; x++)
    {
        
// Obtain the current byte..
        
std::stringstream stream(std::string(lpPattern + (x * 2), 2));

        
// Check if this is a wildcard..
        
if (stream.str() == "??")
            
pattern.push_back(std::make_pair(00, false));
        else
        {
            
auto byte = strtol(stream.str().c_str(), nullptr, 16);
            
pattern.push_back(std::make_pair((unsigned char)byte, true));
        }
    }

    
auto scanStart = data.begin();
    
auto resultCnt = 0;

    while (
true)
    {
        
// Search for the pattern..
        
auto ret = std::search(scanStart, data.end(), pattern.begin(), pattern.end(),
            [&](
unsigned char curr, std::pair<unsigned char, bool> currPattern)
        {
            return (!
currPattern.second) || curr == currPattern.first;
        });

        
// Did we find a match..
        
if (ret != data.end())
        {
            
// If we hit the usage count, return the result..
            
if (resultCnt == resultUsage || resultUsage == 0)
                return (
std::distance(data.begin(), ret) + baseAddress) + offset;

            
// Increment the found count and scan again..
            
++resultCnt;
            
scanStart = ++ret;
        }
        else
            break;
    }

    return 
0;
} 
Example usage:
PHP Code:
    // Obtain the raw data of the memory to scan..
    
std::vector<unsigned char> rawdata(0x00400000, 0x00400000 + 0x01000000);

    
// Scan for the pattern..
    
auto result = FindPattern(std::ref(rawdata), (intptr_t)0x00400000, "8B0D????????8B15????????83EC18535556", 2, 0);
    if (
result == 0)
        
// Not found..
    
else
        
// Found.. 
Reply With Quote
The Following 2 Users Gave Reputation+1 to atom0s For This Useful Post:
b30wulf (02-10-2016), mr.exodia (02-09-2016)
The Following 6 Users Say Thank You to atom0s For This Useful Post:
Arkshine (03-26-2016), CryptXor (02-10-2016), Insid3Code (02-10-2016), Nacho_dj (02-10-2016), niculaita (02-10-2016), sh3dow (07-29-2019)