0

So i have this function iv'e written in C, it's supposed to scan a process' memory. I'm running it on notepad, but since it's failing iv'e tried a few more processes. It never works properly and the output is always as follows :

0x00010000
0x7FFE0000
0x7FFE1000

When i'm using windows 7 the function works just fine. Here it is :

int ScanProcess(int pid)
{
    HANDLE hProc;
    SYSTEM_INFO si;
    MEMORY_BASIC_INFORMATION mbi;
    LPVOID *minAddress, *maxAddress;

    GetSystemInfo(&si);
    minAddress = si.lpMinimumApplicationAddress;
    maxAddress = si.lpMaximumApplicationAddress;

    hProc = OpenProcess(PROCESS_ALL_ACCESS, NULL, pid);

    if (!hProc) {
        printf("[-] OpenProcess() failed.\n");
        return 0;}

    while (minAddress < maxAddress)
    {
        printf("0x%08X\n", minAddress);
        if(!VirtualQueryEx(hProc, minAddress, &mbi, sizeof(mbi))) printf("[-] VirtualQueryEx() failed. %d\n", GetLastError());
        if (mbi.State == MEM_COMMIT && mbi.Protect == PAGE_READWRITE)
        {
            printf("MEM_COMMIT\n"); //When the scan would work i will read the memory and work with it.
        }
        minAddress = (LPVOID)((long)mbi.BaseAddress + mbi.RegionSize);
    }

    return 0;
}

Can someone figure out the problem? thanks :)

@Harry Johnston, this is what i got so far.

int ScanProcess(int pid)
{
HANDLE hProc;
SYSTEM_INFO si;
MEMORY_BASIC_INFORMATION mbi;
DWORD64 minAddress, maxAddress;

GetSystemInfo(&si);
minAddress = (DWORD64)si.lpMinimumApplicationAddress;
maxAddress = (DWORD64)si.lpMaximumApplicationAddress;

hProc = OpenProcess(PROCESS_ALL_ACCESS, NULL, pid);

if (!hProc) {
    printf("[-] OpenProcess() failed.\n");
    return 0;}

while (minAddress < maxAddress)
{
    printf("0x%08X\n", minAddress);
    if(!VirtualQueryEx(hProc, (LPCVOID)minAddress, &mbi, sizeof(mbi))) printf("[-] VirtualQueryEx() failed. %d\n", GetLastError());
    if (mbi.State == MEM_COMMIT && mbi.Protect == PAGE_READWRITE)
    {
        printf("MEM_COMMIT\n"); //When the scan would work i will read the memory and work with it.
    }
    minAddress = (DWORD64)mbi.BaseAddress + mbi.RegionSize;
}

return 0;
}
26
  • I don't know if it's related, but you have one too many levels of indirection. minAddress and maxAddress should be LPVOID, not LPVOID*, Commented Sep 24, 2015 at 18:17
  • that's right. anyway, i changed them to just LPVOID and the output remained same. Commented Sep 24, 2015 at 18:24
  • Can you be more specific what you mean by "never works properly"? Step through the code in a debugger and clarify which step does not do what you expect. Commented Sep 24, 2015 at 19:05
  • VirtualQueryEx returns the addresses for every process, and there's never a memory block i can work with. the if statement that checks. mbi.State and mbi.Protect is never true. on windows 7 the code behaves completely different Commented Sep 24, 2015 at 19:10
  • what do you mean by: "the code behaves completely different"? Commented Sep 24, 2015 at 20:35

1 Answer 1

3

Try this version:

int ScanProcess(int pid)
{
    HANDLE hProc;
    SYSTEM_INFO si;
    MEMORY_BASIC_INFORMATION mbi;
    LPVOID minAddress, maxAddress;

    GetSystemInfo(&si);
    minAddress = si.lpMinimumApplicationAddress;
    maxAddress = si.lpMaximumApplicationAddress;

    hProc = OpenProcess(PROCESS_ALL_ACCESS, NULL, pid);

    if (!hProc) {
        printf("[-] OpenProcess() failed.\n");
        return 0;}

    while (minAddress < maxAddress)
    {
        printf("0x%p\n", minAddress);
        if(!VirtualQueryEx(hProc, minAddress, &mbi, sizeof(mbi))) printf("[-] VirtualQueryEx() failed. %d\n", GetLastError());
        if (mbi.State == MEM_COMMIT && mbi.Protect == PAGE_READWRITE)
        {
            printf("MEM_COMMIT\n"); //When the scan would work i will read the memory and work with it.
        }
        minAddress = (LPBYTE)mbi.BaseAddress + mbi.RegionSize;
    }

    return 0;
}

It uses LPVOID as a pointer type is fine for this application, the only real change is the pointer arithmetic is done using a cast to LPBYTE (since you can't add void pointers).

The other change is to use %p as the printf formatting string, since this will work correctly with a 64-bit pointer.

Sign up to request clarification or add additional context in comments.

7 Comments

It works! thanks a lot, i started getting frustrated. the %p is new to me and i understand its usage so thanks for that. can you explain me the logic of using LPBYTE and why it works?
@hyprnir LPBYTE is a byte-sized pointer, and since mbi.RegionSize is measured in bytes you need to use a compatible pointer size for the arithmetic to work.
i tried using char* and it wouldn't work. iv'e done some reading and found out that LPBYTE is unsigned char*. can you explain me the difference between char* and unsigned char* when working with pointers?
@hyprnir char* works as well (I just tried it). There's no difference in this case between the two - they're both byte-sized pointers. The only difference comes when dereferencing the pointer which you're not doing in this code.
what do you mean by dereferencing a pointer? you mind writing a little example?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.