Access violation reading location...,it made me confused - c++

I want to read another program's variable in memory,a pointer point to an int.I want this int.But i got an error.The pointer's address is 0x420CEFFC40,its value is 0x420CEFFC30,buffer should be 123456,but access violated.
#include <Windows.h>
#include <iostream>
using namespace std;
int main()
{
DWORD pid;
cout<<"INPUT PID:";
cin>>pid;
HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,false,pid);
if(hProcess==NULL)
{
cout<<"OpenProcess failed.Error code:"<<GetLastError()<<endl;
system("pause");
return EXIT_FAILURE;
}
uintptr_t memaddress;
uintptr_t buffer;
cout<<"Target memory address:";
cin>>hex>>memaddress;
if (!ReadProcessMemory(hProcess,(LPCVOID)&(*(uintptr_t*)memaddress),(LPVOID)&buffer,sizeof(int),NULL))
{
cout<<"ReadProcessMemory failed.Error code:"<<GetLastError()<<endl;
return EXIT_FAILURE;
}
cout<<"buffer:"<<*(uintptr_t*)buffer<<endl;
system("pause");
return 0;
}
I got a 'Access violation reading location 0x000000000CEFFC30.'
But,why?

In modern operating systems every process has own map of memory. Each process under same address can have different piece of memory or even nothing.
That is why you have to use system API ReadProcessMemory to be able to read other process memory.
Now when you have read some memory from other process (value of ptr2int) it doesn't meter that read value is a pointer, from current process point of view address in this cell has no significant meaning. This address is valid in other process, but in current process points to invalid location.
So basically this line is undefined behavior:
cout<<"buffer:"<<*(uintptr_t*)buffer<<endl;
It should be:
cout << "buffer:" << buffer << endl;
If you need to read what is point by ptr2int you have to call ReadProcessMemory again with respective arguments.

Related

When injected into a program's memory space, how do you read each byte from 0 to 0xFFFFFFFFF? I am creating a pattern scanner

I am trying to create a pattern scanner, to find every byte sequence starting with "MZ" (4d5a) inside a programs memory. For that I'm injecting a DLL into the target program.
I try to look for the "MZ" pattern as I see some sneaky modules that are unlinking themselves from the modulelist.
From within the program's memory space I was hoping to iterate from 0 to 0xFFFFFFFFF and check for byte patterns. By simply doing something like this:
unsigned i = 0;
while (i < 0xFFFFFFFFF) {
if ((BYTE*) i != NULL) {
std::cout << "Print byte: " << ConvertToHexString( (BYTE*) i) << std::endl;
}
i++;
}
ConvertToHexString successfully converts (BYTE*) to std::string.
I thought it was that easy, even if I hit memory I wasn't allowed to read. I thought my NULL check was sufficient. Seemed it was not. However, if I start from the modulebase (uintptr_t pModuleBase = (uintptr_t)GetModuleHandle(NULL)), I can actually see the bytes.
Below is my code:
DllMain:
BOOL APIENTRY DllMain(
...snip...
CloseHandle(CreateThread(0, 0, (LPTHREAD_START_ROUTINE)SignatureScanner, moduleHandle, 0, 0));
...snip...
}
SignatureScanner:
DWORD WINAPI SignatureScanner(HMODULE moduleHandle)
{
// Create Console
AllocConsole();
FILE* f;
freopen_s(&f, "CONOUT$", "w", stdout);
// Get module base
uintptr_t pModuleBase = (uintptr_t)GetModuleHandle(NULL);
while (true)
{
if (GetAsyncKeyState(VK_NUMPAD1) & 1)
{
unsigned i = 0;
while (i < 0xFFFFFFFFF) {
if ((BYTE*) i != NULL) {
std::cout << "Print byte: " << ConvertToHexString( (BYTE*) i) << std::endl;
}
i++;
}
}
if (GetAsyncKeyState(VK_NUMPAD2) & 1)
{
break;
}
Sleep(100);
}
fclose(f);
FreeConsole();
FreeLibraryAndExitThread(moduleHandle, 0);
return 0;
}
Virtual Address Space
The virtual address space for a process is the set of virtual memory
addresses that it can use. The address space for each process is
private and cannot be accessed by other processes unless it is shared.
Default Virtual Address Space for 32-bit Windows:
Low 2GB (0x00000000 through 0x7FFFFFFF) - Used by the process.
High 2GB (0x80000000 through 0xFFFFFFFF) - Used by the system.
You are trying to read the address space that does not belong to your process, try to use VirtualProtectEx + ReadProcessMemory.
In addition, It is not recommended to use CreateThread in DllMain: Dynamic-Link Library Best Practices(You don't need to inject Dll as well)
Then, we don't need to read all the address. A module is an executable file or DLL. Each process consists of one or more modules. The first module is the executable file. It is mapped into the module base address. So you could ReadProcessMemory from the module base address(Refer to PE Format.)
You could use the EnumProcessModules + GetModuleInformation to get the base address and the size of the linear space that the module occupies, in bytes.
Or You can just use EnumProcessModules + GetModuleBaseName to check modules list and confirm which module has unlinked.

Read memory from application which does not allow it

I am currently trying to read the entirety of the memory of a game which blocks calls to OpenProcess and ReadProcessMemory (I believe this is done through a windows driver/service, although I'm not sure how).
I use the following code to do try and open the process and read its memory to a file:
HANDLE process = OpenProcess(PROCESS_VM_READ, 0, pid);
if (!process) {
cout << "Failed to open process.";
return 1;
}
cout << "Successfully opened processs." << endl << "Dumping memory to mem.dmp..." << endl;
ofstream fout;
fout.open("mem.dmp");
char *base = (char *)0;
char *readCount = (char *)0;
do {
char buffer[PAGE_SIZE];
if (ReadProcessMemory(process, base, buffer, PAGE_SIZE, NULL) != 0)
{
fout << buffer;
}
base += PAGE_SIZE;
readCount++;
} while (base != 0);
if (readCount == 0) {
cout << "Warning: No memory was read from the process." << endl;
}
fout.flush();
fout.close();
However, when run, this cannot even open the process.
The only way to get past the driver blocking the process from being opened for memory reading is to dump the entirety of the physical memory to a file. I have no idea how to do this, other than having to set windows to dump all of the physical memory on a blue screen, and then forcing my computer to shutdown with a blue screen. This is obviously quite inconvenient as I will want to analyse the application's memory quite frequently.
Is there any way to dump all of the physical memory without using this method on Windows? I know virtually nothing about the driver or how it works so it would be almost impossible to work out another way of bypassing it.
You are trying to access the "0th" memory position, that is not possible (SO does not allow you to do it):
char *base = (char *) 0;
You should set correcly the address where you wanna read, and that address must be a readable address. Check the ReadProcessMemory doc here
lpBaseAddress [in]: A pointer to the base address in the specified
process from which to read. Before any data transfer occurs, the
system verifies that all data in the base address and memory of the
specified size is accessible for read access, and if it is not
accessible the function fails.
Check also the examples in this post
here

Access Violation while calculating a pointer

I'm quite afraid the question is really, really simple, but even thou I'm starting to grip the idea of pointers, hints from experienced users shorten the time I need to spend on it to understand everything. Ive got a simple example, I won't go into details what its supposed to do later on, because I think my mistake is something very basic. I'm getting:
Exception thrown: read access violation.
_First was 0x815110.
When executing this code:
#include <Windows.h>
#include <iostream>
#include "Header.h"
#pragma comment(linker, "/SECTION:.data,RWE")
using std::cout;
using std::endl;
int main() {
DWORD dwProcessID = 0;
cout << "Looking for game process..." << endl;
while (dwProcessID == 0) {
dwProcessID = GetProcessID(L"PathOfExile.exe");
Sleep(100);
}
std::cout << "Game Client found" << std::endl;
printf("dwProcessID = %p\n", dwProcessID);
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessID);
MODULEENTRY32 module;
module.dwSize = sizeof(MODULEENTRY32);
Module32First(snapshot, &module);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, dwProcessID);
HANDLE hToken = NULL;
if (!OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken))
printf("Failed to open access token\n");
if (!SetPrivilege(hToken, SE_DEBUG_NAME, TRUE))
printf("Failed to set debug privilege\n");
printf("PoE base address = %p\n", module.modBaseAddr);
BYTE jmp[] = "\xBA\x00\x00\x80\x3F\x89\x10\x89\x16\xE9\x00\x00\x00\x00";
BYTE *dwMaphack = (BYTE*)(module.modBaseAddr + 0x4D5110);
cout << dwMaphack << endl;
*(DWORD*)&jmp[10] = (DWORD)(dwMaphack - jmp) - 6;
DWORD dwOldProt;
VirtualProtectEx(hProcess, (LPVOID)dwMaphack, 8, PAGE_EXECUTE_READWRITE, &dwOldProt);
// tbc
while (1) {
}
return 0;
}
The open process methods and other basic stuff are in the header and they do work fine, what I don't get is why when I change the byte pointer BYTE *dwMaphack to DWORD *dwMaphack, there's no longer an access violation error?
I'm trying to base my code on an outdated code of someones that no longer works, so the reason for doing these operations is only partially known for me, I know what it's supposed to do in programming terms, but I don't know the effect in the game, yet. I don't think it's important in terms of the error I'm getting anyway. Thanks in advance for the answers!
BYTE is an alias for unsigned char.
std::cout has an overloaded operator<< that accepts an unsigned char* pointer as input and prints it as a character string (as stated by Harry Johnston, https://stackoverflow.com/a/41538200/7376565). So it crashes when it tries to access memory it does not have access to.
std::cout does not have an operator<< overload for DWORD* (aka unsigned long*), but it does have one for void*, so any non-character pointer will print just the value of the pointer itself. When you change dwMaphack to DWORD*, operator<< doesn't try to access the memory that dwMaphack points to, so no access violation occurs.
Here's your problem:
cout << dwMaphack << endl;
This is attempting to print the value that dwMaphack points to, not the value of the pointer. Since the pointer is only valid in the remote process, attempting to dereference it results in an access violation.
This works:
cout << (DWORD_PTR)dwMaphack << endl;

Can I use ReadProcessMemory to read program memory of a process in windows?

I have this thread running within my program's process. The thread is supposed to read this process' program memory to detect, if any forbidden code injections have occurred. Now how do I get access to the program memory of the process? Can I use the
ReadProcessMemory();
function, to read the program memory if I get the process handle with ALL_ACCESS flags?
Also is there a way to search this program memory in such way that I could limit this memory scanning to few specific method of interest or detect the base address and length for particular method?
Yes, if you get process handle with READ permissions (included in PROCESS_ALL_ACCESS) you can use ReadProcessMemory() to read the memory of the target process.
What you are looking to do is called pattern scanning. First you would use VirtualQueryEx() to find memory regions which have MEM_COMMIT as the state and do not have PAGE_NOACCESS or PAGE_GUARD as the protection type.
You loop through these memory regions using a pattern scan function to find specific signatures which you want to blacklist.
Here is the basic idea to looping through the memory
int main()
{
DWORD procid = GetProcId("whatever.exe");
MEMORY_BASIC_INFORMATION meminfo;
unsigned char* addr = 0;
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procid);
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);
}
You can find many different pattern scanning functions to complete the job from here.

Exception writing data into a new file

My task is to read a yuv file and to each component(Y,Cb,Cr) of it, I'm appending some data and storing it into another file. I have tried the below code:
#include <stdio.h>
#include <stdlib.h>
void main()
{
FILE *fp=fopen("traffic_1920x1080.yuv","rb");
FILE *myYUV=fopen("traffic_1920x1088.yuv","ab");
int count=0;
unsigned char *y=(unsigned char*)malloc(sizeof(unsigned char)*1920*1080);
unsigned char *u=(unsigned char*)malloc(sizeof(unsigned char)*(1920/2)*(1080/2));
unsigned char *v=(unsigned char*)malloc(sizeof(unsigned char)*(1920/2)*(1080/2));
unsigned char ypad[1920*8];
unsigned char upad[(1920/2)*4];
unsigned char vpad[(1920/2)*4];
for(int i=0;i<(1920/2)*4;i++)
{
ypad[i]=255;
upad[i]=128;
vpad[i]=128;
}
for(int i=(1920/2)*4;i<1920*8;i++)
ypad[i]=255;
while (!feof(fp))
{
fread(y,sizeof(unsigned char),1920*1080,fp);
fread(u,sizeof(unsigned char),1920/2*1080/2,fp);
fread(v,sizeof(unsigned char),1920/2*1080/2,fp);
fwrite(y, sizeof(unsigned char),1920*1080,myYUV);
fwrite(ypad,sizeof(unsigned char),1920*8,myYUV);
fwrite(u,sizeof(unsigned char),1920/2*1080/2,myYUV);
fwrite(upad,sizeof(unsigned char),1920/2*4,myYUV);
fwrite(v,sizeof(unsigned char),1920/2*1080/2,myYUV);
fwrite(vpad,sizeof(unsigned char),1920/2*4,myYUV);
printf("Frame %d created\r",count);
y+=1920*1080;
u+=1920/2*1080/2;
v+=1920/2*1080/2;
count ++;
}
free(y);
free(u);
free(v);
fclose(fp);
fclose(myYUV);
}
Howevr the above code works fine for the first loop, but in the second loop i get an exception
Access violation writing location 0x0092f000.
at line fwrite(y, sizeof(unsigned char),1920*1080,myYUV);
Is this a problem in pointer increment? or it is something else? Please reply. Thanks in advance.
These increments:
y+=1920*1080;
u+=1920/2*1080/2;
v+=1920/2*1080/2;
will increment the pointers past the end of the allocated memory. For example, y points to the start of 1920*1080 bytes of allocated memory. Increasing it by that much makes it point past the end of that memory. This results in reading/writing to/from unallocated memory. That's why you get an access violation.
I don't actually see a reason for those pointers to be incremented at all.
Other than that, your code should check for error conditions (did fopen() succeed, etc.)