Memory scanner crashes

When i go to inject my dll into any process it crashes at the part where i push back the address of a unsigned char* to a vector<unsigned char*> object i got from a block of memory i scanned. i also made sure to protect it to PAGE_EXECUTE_READWRITE and revert it back to its original protection but it still crashes. The code ran fine when i didn't include my scanner function.
i've done some debugging to it in the past and made sure there was no access violations.
code:

int scanprocess(vector<unsigned char*> &storage,int find)
{
MEMORY_BASIC_INFORMATION mbi = { 0 };
unsigned char *pAddress = NULL,
*pEndRegion = NULL;

DWORD dwFindData = find,
dwProtectionMask = PAGE_READONLY | PAGE_EXECUTE_WRITECOPY
| PAGE_READWRITE | PAGE_WRITECOMBINE;
while (sizeof(mbi) == VirtualQuery(pEndRegion, &mbi, sizeof(mbi))) {

pAddress = pEndRegion;
pEndRegion += mbi.RegionSize;
if ((mbi.AllocationProtect & dwProtectionMask) && (mbi.State & MEM_COMMIT)) {

for (pAddress; pAddress < pEndRegion; pAddress++) {
if (*pAddress == dwFindData) {

// dostaff
unsigned long oldProtection;
VirtualProtect((LPVOID)pAddress, 1, PAGE_EXECUTE_READWRITE, &oldProtection);

storage.push_back((unsigned char*)pAddress);
VirtualProtect((LPVOID)pAddress, 1, oldProtection, NULL);

}
}
}
}

return 0;
}
the coded i used to call the function and store the data:

vector<unsigned char*> values;
scanprocess(values, 42);
It looks like it should crash at this point: *pAddress == dwFindData
You can't dereference pointers across processes, because they exist in separate memory spaces. You need to use ReadProcessMemory().
its a dll inside the process its not external process
It doesn't make sense to scan memory from within the same address space that you want to scan. For example, how do handle the case where pAddress points to dwFindData, or to find, or to other copies of the same value? Which is bound to happen, since you're searching the entire address space.
You really should do this from a separate process.

Anyway, this is probably a problem:
lpflOldProtect [out]
A pointer to a variable that receives the previous access protection value of the first page in the specified region of pages. If this parameter is NULL or does not point to a valid variable, the function fails.
> if ((mbi.AllocationProtect & dwProtectionMask) && ...

Need to check mbi.Protect instead of mbi.AllocationProtect; they need not be the same.

Something like this, perhaps:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <vector>
#include <string>
#include <windows.h>
#include <psapi.h>

std::vector< const void* > scan_memory( void* address_low, std::size_t nbytes, DWORD data_to_find )
{
    std::vector< const void* > addresses_found ;

    ::MEMORY_BASIC_INFORMATION mbi {};
    constexpr DWORD pmask = PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE |
                            PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY ;
    
    char* address = static_cast<char*>(address_low) ;
    char* address_high = address + nbytes ;


    while( address < address_high && ::VirtualQuery( address, std::addressof( mbi ), sizeof( mbi ) ) )
    {
        if( mbi.State == MEM_COMMIT && mbi.Protect | pmask )
        {
            DWORD* p = static_cast< DWORD* >( mbi.BaseAddress ) ; // search in aligned addresses
            for( std::size_t i = 0 ; i < mbi.RegionSize / sizeof( DWORD ) ; ++i )
                if( p[i] == data_to_find ) addresses_found.push_back( p + i ) ;
        }

        address += mbi.RegionSize ;
        mbi = {} ;
    }

    return addresses_found ;
}

std::vector< const void* > scan_memory( std::string module_name, DWORD data_to_find ) 
{
    auto base = ::GetModuleHandleA( module_name.c_str() ) ;
    if( base == nullptr ) return {} ;

    MODULEINFO minfo {} ;
    ::GetModuleInformation( GetCurrentProcess(), base, std::addressof( minfo ), sizeof( minfo ) ) ;
    return scan_memory( base, minfo.SizeOfImage, data_to_find ) ;
}

http://rextester.com/VTZ38176
Topic archived. No new replies allowed.