How can I search for a string in the memory of another process?
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;
}
Related videos on Youtube
Dalton Sandbothe
Updated on September 15, 2022Comments
-
Dalton Sandbothe over 1 year
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; } } } } }
-
Retired Ninja about 9 yearsI see several functions that can fail and no error checking. Seems like that would be the place to start. You might also want to make sure something is always returned, you should have gotten a warning about that when you compiled.
-
molbdnilo about 9 years
sizeof(input)
does not mean what you think it means.
-
-
icbytes about 9 yearsQuick and dirty ? Where exactly ? Here for exmple ? chunk.resize(info.RegionSize);
-
Dalton Sandbothe about 9 yearsFor my specific case how would the return part of the function need to be changed? I don't believe I could return a pointer to data in another application. So I would need to return it as an integer somehow I believe.
-
icbytes about 9 yearsWhy not ? You see, that retired ninja in this case calls HIS example in the codesnippet. You can just introspect any file by OpenProcess. So Your application will examine ANOTHER one.
-
Retired Ninja about 9 yearsIt really depends on what you plan to do with the data once you've found it. Your question states no goal other than finding it, and a DWORD isn't guaranteed to be large enough to hold a pointer value.