I tried to scan the whole process, but it crashed. I do not understand why that happened. What's another equivalent but safer way to do so?
void searchAddrByValue(const int value) {
int *p = (int *)0x00FFFFFF;
while ((int *)0x0FFFFFFF >= p) {
if(value == *p)
fprintf(filePointer, "Addr:%p -- Val:%d\n", p, *p);
++p;
}
display(L"Finished");
}
If you want to search all memory inside your process, you should first use VirtualQueryEx to find out which pages are valid addresses, and then search inside readable pages.
The MSDN article on Managing Virtual Memory outlines how to walk the address ranges in your process address space.
To loop through all properly allocated memory you can use VirtualQueryEx, ensure the region's state is MEM_COMMIT and the protection is not PAGE_NOACCESS, before doing anything else. If you want to ReadProcessMemory() each region into a local buffer you can certainly do that, just replace the console output in this code with the code you want to execute on each region:
MEMORY_BASIC_INFORMATION meminfo;
unsigned char* addr = 0;
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
MEMORY_BASIC_INFORMATION mbi;
while (VirtualQueryEx(hProc, addr, &mbi, sizeof(mbi)))
{
if (mbi.State == MEM_COMMIT && mbi.Protect != PAGE_NOACCESS)
{
std::cout << "base : 0x" << std::hex << mbi.BaseAddress << " end : 0x" << std::hex << (uintptr_t)mbi.BaseAddress + mbi.RegionSize << "\n";
}
addr += mbi.RegionSize;
}
CloseHandle(hProc);
This code will print out the start and end address of each region
Make sure you run as admin and you may also want to check for PAGE_GUARD as well, but I haven't run into that being a problem.
Related
I'm new to reverse engineering, and quite new to C++. I'm trying to collect a player's character name in a game using ReadProcessMemory() from the Win32 API, but it throws an exception whenever I try to read it:
if (procId != NULL) {
hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procId);
ModuleBase = getModuleBaseAddr(procId, "ac_client.exe");
localPlayerptr = ModuleBase + 0x10f4f4;
healthaddr = findDMAaddy(hprocess, localPlayerptr, { 0xf8 });
//load to entitylist Array
ReadProcessMemory(hprocess, (BYTE*)localPlayerptr, &Entitylist[0], sizeof(Entitylist[0]), 0);
for (int i = 1; i < 10; ++i) {
ReadProcessMemory(hprocess, (BYTE*)ModuleBase + 0x10f4f8, &Entitylist[i], sizeof(Entitylist[i]), 0);
ReadProcessMemory(hprocess,(BYTE*) Entitylist[i]+(i*4), &Entitylist[i], sizeof(Entitylist[i]), 0);
std::cout << std::hex << Entitylist[i] << std::endl;
uintptr_t nameaddres;
std::string name;
nameaddres = Entitylist[i] + 0x225;
//ReadProcessMemory(hprocess, (BYTE*)nameaddres, &name, sizeof(name), 0);
/*--> ** This is where I have a problem. ***/
std::cout << name << std::endl;
}
First, you need to determine whether the string you want to read is a wide-byte (wchar) or multi-byte (char) version, then you could use std::string/char* or std::wstring/wchar_t*.
Second, do not use sizeof(std::string), you need to determine the length of the string you want to read.
For wide-byte:
&(std::string)name is not a writable address, as comments pointed out, you could use a wchat_t array instead:
wchat_t name[100];
BOOL ret = ReadProcessMemory(hprocess, (BYTE*)nameaddres, name, sizeof(name), 0);
Or you could use &name[0](From #Remy):
std::wstring name;
name.reserve(100);
BOOL ret = ReadProcessMemory(hprocess, (BYTE*)nameaddres, &name[0], 100*sizeof(wchar_t), 0);
std::wcout << name << std::endl;
Then, std::cout is not available for the wchar_t*, it only prints the address value. It is a local variable in the for loop, so it will reallocate the address every time comes in. Due to certain rules, the system may prefer to choose the same address, so you've got the same address value.
Use the std::wcout << name to out put the wchar_t string, and If the output is always only one character, then you may consider using the multi-byte version to read memory.
I have a server that sends raw binary data to print a "map" that a user must traverse through, however, I am having trouble clearing out my buffer after each line read and thus keep getting residual data printed at the end of the shorter lines. In the screenshot below you can see my output on the left, and what the output should be on the right. What is the best way to solve this? I feel like I am missing something but cant seem to find a solution.
And the code that is reading/printing this is below:
char* mapData = NULL;
string command = "command> ";
size_t dataSize = 0;
while(mapData != command.c_str()) {
unsigned char* buffer = (unsigned char*) &dataSize;
connection = read(mySocket, buffer, 8);
if(connection == -1 || connection < 0) {
cerr << "**Error: could not read text size" << endl;
return 1;
}
mapData = (char*)malloc(dataSize);
buffer = (unsigned char*) mapData;
while((connection = read(mySocket, buffer, dataSize)) != -1) {
if(connection == -1 || connection < 0) {
cerr << "**Error: could not read text size" << endl;
return 1;
}
if(dataSize != 1) {
cout << buffer;
}
free(buffer);
buffer = NULL;
}
}
You are ignoring the return value of read() to know how many bytes are in the buffer.
read() returns the actual number of bytes that were read, which may be fewer than you requested. So you need to call read() in a loop until you have read all of the bytes you are expecting, eg:
int readAll(int sock, void *buffer, size_t buflen)
{
unsigned char* pbuf = reinterpret_cast<unsigned char*>(buffer);
while (buflen > 0) {
int numRead = read(sock, pbuf, buflen);
if (numRead < 0) return -1;
if (numRead == 0) return 0;
pbuf += numRead;
buflen -= numRead;
}
return 1;
}
Also, after reading the buffer, you are treating it as if it were null-terminated, but it is not, which is why you get extra garbage in your output.
More importantly, mapData != command.c_str() will ALWAYS be true, so your while loop iterates indefinitely (until a socket error occurs), which is not what you want. You want the loop to end when you receive a "command> " string instead.
mapData is initially NULL, and c_str() NEVER returns NULL, so the loop ALWAYS iterates at least once.
Then you allocate and free mapData but don't reset it to NULL, so it is left pointing at invalid memory. Which doesn't really matter, since your while loop is just comparing pointers. c_str() will NEVER return a pointer to memory that mapData ever points to.
To end your loop correctly, you need to compare the contents of mapData after reading, not compare its memory address.
Try this instead:
char *mapData = NULL;
uint64_t dataSize = 0;
const string command = "command> ";
bool keepLooping = true;
do {
if (readAll(mySocket, &dataSize, sizeof(dataSize)) <= 0) {
cerr << "**Error: could not read text size" << endl;
return 1;
}
if (dataSize == 0)
continue;
mapData = new char[dataSize];
if (readAll(mySocket, mapData, dataSize) <= 0) {
cerr << "**Error: could not read text" << endl;
delete[] mapData;
return 1;
}
cout.write(mapData, dataSize);
keepLooping = (dataSize != command.size()) || (strncmp(mapData, command.c_str(), command.size()) != 0);
delete[] mapData;
}
while (keepLooping);
Alternatively:
string mapData;
uint64_t dataSize = 0;
const string command = "command> ";
do {
if (readAll(mySocket, &dataSize, sizeof(dataSize)) <= 0) {
cerr << "**Error: could not read text size" << endl;
return 1;
}
mapData.resize(dataSize);
if (dataSize > 0) {
if (readAll(mySocket, &mapData[0], dataSize) <= 0) {
cerr << "**Error: could not read text" << endl;
return 1;
}
cout << mapData;
}
}
while (mapData != command);
like #eozd pointed out, calling malloc and free in your loop is a bad idea since you use return statements. Your code may leak memory. You should ensure you call free before returns. Even better, you could declare your buffer outside of while loop, and use break instead of return, and call free if there was en error
Looking at your solution, it seems that the communication protocol involves sending data size first, followed by the actual data. How is data size written to the wire? You may need to convert it from network byte order.
To debug, you could print out the value of dataSize before every read to make sure that it is what you expect
You should clear the buffer too. Add:
memset(mapData, 0, dataSize);
after the malloc.
I want to access and edit multiple addresses in memory.
In case it's vague, the question is: If I used memory scanner and the results were a list of addresses, how would I be able to access and edit them all?
I've already been told to try putting all the addresses in an array, how do I do this?
Here's the code so far:
//
#include "stdafx.h"
#include "iostream"
#include "Windows.h"
#include <cstdint>
#include <stdint.h>
using namespace std;
int main()
{
int newValue = 0;
int* p;
p = (int*)0x4F6DCFE3DC; // now p points to address 0x220202
HWND hwnd = FindWindowA(NULL, "Call of Duty®: Modern Warfare® 3 Multiplayer");// Finds Window
if (hwnd == NULL) {// Tests for success
cout << "The window is not open" << endl;
Sleep(3000);
exit(-1);
}
else {
cout << "It's open boss!";
}
else {// If Successful Begins the following
DWORD procID;
GetWindowThreadProcessId(hwnd, &procID);
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID);//Gets handle on process
if (procID == NULL) {
cout << "Cannot obtain process." << endl;
Sleep(3000);
exit(-1);
}
else {//Begins writing to memory
while (newValue == 0) {
/*This Writes*/WriteProcessMemory(handle, (LPVOID)0x04F6DCFE3DC, &newValue, sizeof(newValue), 0);
cout << p;
Sleep(3000);
}
}
}
}
It's fairly easy. Just use a std::vector<std::pair<int*,int>> to contain all these addresses you want to modify along with the value they should achieve:
std::vector<std::pair<int*,int>> changeMap = {
{ (int*)0x4F6DCFE3DC , 0 }
// more address value pairs ...
};
Then you can process them in a loop:
for(auto it = std::begin(changeMap); it != std::end(changeMap); ++it)
{
WriteProcessMemory(handle, (LPVOID)it->first, &(it->second),
sizeof(it->second), 0);
}
Whatever you want to achieve with that1.
I've already been told to try putting all the addresses in an array, how do I do this?
If you want to set all the address contents to 0 you may use a simpler construct:
int newValue = 0;
std::vector<int*> changeAddrList = {
(int*)0x4F6DCFE3DC ,
// more addresses to change ...
};
// ...
for(auto addr : changeAddrList)
{
WriteProcessMemory(handle, (LPVOID)addr , &newValue ,
sizeof(newValue), 0);
}
1Fiddling around in another processes memory is error prone and might lead to all kinds of unexpected behavior!
Your code may fail miserably at a newer version of that program, where you're trying to apply your cheat codez.
I want to get the entry point to a 64bit process I wrote from a 32bit process, the same way you'd use EnumProcessModule and take the memory addr of the main module.
My end goal is to read a byte from memory in my 64bit process from an offset to it (entry+Offset).
But my NtWow64ReadVirtualMemory64 function keeps failing.
I think it has something to do with my entry memory addr.
#define PROC_BASIC_INFO 0
#define NT_WOW64_QUERY_INFORMATION_PROCESS_64_NAME "NtWow64QueryInformationProcess64"
#define NT_WOW64_READ_VIRTUAL_MEMORY_64_NAME "NtWow64ReadVirtualMemory64"
typedef UINT64 SYM;
typedef SIZE_T SIZE_T64;
HWND WINDOW_HANDLE;
HANDLE PROC_HANDLE;
DWORD PROC_ID;
UINT address;
UINT64 address64;
SIZE_T bytesRead;
SIZE_T64 bytesRead64;
using namespace std;
//initialize variables for importing of essential 64 bit reading functions
//from ntdll
typedef NTSTATUS(NTAPI *FUNC_NtReadVirtualMemory64)
(
IN HANDLE ProcessHandle,
IN PVOID64 BaseAddress,
OUT PVOID Buffer,
IN ULONGLONG BufferLength,
OUT PULONGLONG ReturnLength OPTIONAL
);
typedef NTSTATUS (NTAPI *FUNC_NtWow64QueryInformationProcess64)
(
IN HANDLE ProcessHandle,
IN ULONG ProcessInformationClass,
OUT PVOID ProcessInformation64,
IN ULONG Length,
OUT PULONG ReturnLength OPTIONAL
);
struct PROCESS_BASIC_INFORMATION64 {
SYM Reserved1;
SYM PebBaseAddress;
SYM Reserved2[2];
SYM UniqueProcessId;
SYM Reserved3;
/*
NTSTATUS ExitStatus;
ULONG64 PebBaseAddress;
ULONG64 AffinityMask;
LONG BasePriority;
UINT64 Reserved1;
ULONG64 UniqueProcessId;
ULONG64 InheritedFromUniqueProcessId;
*/
};
HINSTANCE ntdll = LoadLibrary("ntdll.dll");
FUNC_NtWow64QueryInformationProcess64 NtWow64QueryInformationProcess64 = (FUNC_NtWow64QueryInformationProcess64)GetProcAddress(ntdll, NT_WOW64_QUERY_INFORMATION_PROCESS_64_NAME);
FUNC_NtReadVirtualMemory64 NtReadVirtualMemory64 = (FUNC_NtReadVirtualMemory64)GetProcAddress(ntdll, NT_WOW64_READ_VIRTUAL_MEMORY_64_NAME);
int Init32To64MemoryRead(const char* windowClass, const char* caption, SYM addressOffset)
{
DWORD cbNeeded;
DWORD dwdResult;
HMODULE mainModule;
BOOL enumResult;
ULONG read_length=0;
HINSTANCE ntdll;
PROCESS_BASIC_INFORMATION64 procInfo;
ZeroMemory(&procInfo, sizeof(procInfo));
//Get the window handle
WINDOW_HANDLE = FindWindow(windowClass, NULL);
if (WINDOW_HANDLE == NULL)
{
//Window was not foud
return 10;
}
//Get the process ID
dwdResult = GetWindowThreadProcessId(WINDOW_HANDLE, &PROC_ID);
if (dwdResult == 0)
{
//Getting Process ID failed
return 20;
}
//Open the process
PROC_HANDLE = OpenProcess(PROCESS_ALL_ACCESS, false, PROC_ID);
if (PROC_HANDLE == NULL)
{
//Process failed to open
return 30;
}
DWORD result;
//Query Proc Information to get .exe entry point
result = NtWow64QueryInformationProcess64( PROC_HANDLE, 0, &procInfo, sizeof(procInfo), &read_length);
if (result != 0)
{
cerr << "Query Information Process has failed" << endl;
return 40;
}
address64 = (procInfo.PebBaseAddress + addressOffset);
cerr << address64 << endl;
string number;
stringstream stristream;
stristream << address64;
stristream >> number;
byte testByte = 0;
(byte)ReadMemory64<byte>(testByte);
system("PAUSE");
return 1;
}
template <typename _ret_t> _ret_t ReadMemory64(_ret_t& ret)
{
NTSTATUS result = NtReadVirtualMemory64(PROC_HANDLE, (void*)address64, &ret, 8, NULL);
///* Debug # when too lazy for breakpoints
cerr <<"value: " << ret << endl;
cerr << "Error Code: " << GetLastError() << endl;
if (result != 0)
{
cerr << "ReadMemory Failed.\r\nAddress: " << address64 << "\r\nSize: " << sizeof(_ret_t) << "\r\nResult: " << result << endl;
cerr << "NtReadVirtualMemory64 has failed" << endl;
system("PAUSE");
} //*/
return ret;
};
I'd like to know what I am doing wrong.
Edit:
Upon further inspection, I noticed that NtWow64ReadVirtualMemory, does not store a value in the variable "ret" used as the buffer.
I ran a simple test and figured out that the value of my buffer-"ret" was not changed when inserted to the function "NtWow64ReadVirtualMemory64".
The code did compile and run without errors(compile and runtime) except for NtReadMemory64 returning a weird number (there is no documentation available for the ntdll NtWow64 functions, so goolgling it did not yield anything useful).
So i figured I am either providing a faulty buffer or am not reading from a valid memory addr.
since I did initialize the buffer explicitly outside of the function, I figured
that my problem is the latter(not providing a valid memory address).
I was using the following when calling NtReadVirtualMemory
NTSTATUS result = NtReadVirtualMemory64(PROC_HANDLE, (void*)address64, &ret, 8, NULL);
apparently, when calling NtWow64ReadVirtualMemory64, I cast the addr to a 32 bit void pointer (void*)address64 , and since address64 is a UINT64-type , the cast truncated the address, and I was trying to read off of a memory segment I wasn't able to read
I resolved it by changing the cast to (PVOID64)address64
which casts it to a native 64bit pointer.
simpler than I thought, but finding it was hell after days of googling and reviewing the code.
Edit:
this didn't cut it since my address is wrong.
I need to get the ".exe"s' entry point through the location of the process' main module in memory.
looking at the how to now.
any help is appreciated!
I have a application that I need to scan for certain datatypes in the memory. To get some benchmarking tests, I whipped up this program :
long count = 0;
MEMORY_BASIC_INFORMATION meminfo;
unsigned char *addr = 0;
HANDLE hProc = GetCurrentProcess();
while (true){
if ( VirtualQueryEx( hProc, addr, &meminfo, sizeof( meminfo ) ) == 0 ){
break;
}
if ( ( meminfo.State & MEM_COMMIT ) && ( meminfo.Protect & WRITABLE ) ){
addr = (unsigned char*)meminfo.BaseAddress + meminfo.RegionSize;
count++;
printf("%d",count);
}
}
printf("%ld\n",count);
This program doesn't work, it blocks/crashes at the first memory chunk. And conceptually it fails too, ideally I need pointers to all of the variables in the current process, so I can check if they're of any relevance to me. I've google'd around for a while now to no avail, if someone could push me in the right direction that'd be great.
I know it's generally a bad idea to do this in the first place, I'd just like to know how it'd be done if I needed to do it.
WRITEABLE (at the second if block) is not one of the memory protection constants. Did you mean PAGE_READWRITE? You can find the full list of options here.
Memory access permissions are tricky. The rest of the function works though. This works, though one can view addr only when stepping through:
#include <Windows.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
long count = 0;
MEMORY_BASIC_INFORMATION meminfo;
unsigned char *addr = 0;
HANDLE hProc = GetCurrentProcess();
while (true)
{
if (VirtualQueryEx(hProc, addr, &meminfo, sizeof(meminfo)) == 0)
{
// TODO GetLastError
break;
}
// if ((meminfo.State & MEM_COMMIT) && (meminfo.Protect & PAGE_READWRITE))
{
addr = (unsigned char*) meminfo.BaseAddress + meminfo.RegionSize;
count++;
printf("%d", count);
}
}
printf("%ld\n", count);
}