Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I search for a string in the memory of another process?

Currently I'm using this function which I've cobbled together from reading several loosely related questions all over the internet. The problem I'm having is that the first time I ran it it returned an error, but unfortunately I haven't been able to reproduce it. Now when I run it it simply returns 0 every time.

DWORD GetAddressOfString(char *input)
{
    unsigned char *p = NULL;
    MEMORY_BASIC_INFORMATION info;
    HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, _processID);

    for (p = NULL; VirtualQueryEx(process, p, &info, sizeof(info)) == sizeof(info); p += info.RegionSize)
    {
        if (info.State == MEM_COMMIT && (info.Type == MEM_MAPPED || info.Type == MEM_PRIVATE))
        {
            char *buffer = new char[info.RegionSize];
            SIZE_T bytesRead;
            ReadProcessMemory(process, p, &buffer, info.RegionSize, &bytesRead);
            for (int i = 0; i <= (info.RegionSize - sizeof(input)); i++)
            {
                if (memcmp(input, &buffer[i], sizeof(input)) == 0)
                {
                    return i;
                }
            }
        }
    }
}
like image 833
Dalton Sandbothe Avatar asked Jan 30 '15 07:01

Dalton Sandbothe


1 Answers

Here's a quick and dirty version that searches for data in itself. If you open up Notepad++, type "SomeDataToFind", replace the pid with the correct value, and run it, it should find the data as well. It might give you something to start with and embellish to suit your needs.

Your code was searching for the wrong length, returning the wrong offset, leaking memory like a sieve, and not always returning a value which is undefined behavior.

#include <Windows.h>
#include <iostream>
#include <string>
#include <vector>

char* GetAddressOfData(DWORD pid, const char *data, size_t len)
{
    HANDLE process = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, pid);
    if(process)
    {
        SYSTEM_INFO si;
        GetSystemInfo(&si);

        MEMORY_BASIC_INFORMATION info;
        std::vector<char> chunk;
        char* p = 0;
        while(p < si.lpMaximumApplicationAddress)
        {
            if(VirtualQueryEx(process, p, &info, sizeof(info)) == sizeof(info))
            {
                p = (char*)info.BaseAddress;
                chunk.resize(info.RegionSize);
                SIZE_T bytesRead;
                if(ReadProcessMemory(process, p, &chunk[0], info.RegionSize, &bytesRead))
                {
                    for(size_t i = 0; i < (bytesRead - len); ++i)
                    {
                        if(memcmp(data, &chunk[i], len) == 0)
                        {
                            return (char*)p + i;
                        }
                    }
                }
                p += info.RegionSize;
            }
        }
    }
    return 0;
}

int main()
{
    const char someData[] = "SomeDataToFind";
    std::cout << "Local data address: " << (void*)someData << "\n";

    //Pass whatever process id you like here instead.
    DWORD pid = GetCurrentProcessId();
    char* ret = GetAddressOfData(pid, someData, sizeof(someData));
    if(ret)
    {
        std::cout << "Found: " << (void*)ret << "\n";
    }
    else
    {
        std::cout << "Not found\n";
    }

    return 0;
}
like image 50
Retired Ninja Avatar answered Oct 19 '22 23:10

Retired Ninja