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;
Related
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.
I had written a program that enumerates all the memory regions of a process with the following attributes: MEM_COMMIT and PAGE_READWRITE, and that at the end of the program prints the total size of all the regions found, everything seems to work well, then I tried it on programs at 64 bits and it turned out that the total regions size was greater than the RAM available on my PC.
On my PC there are 15.9GB of RAM available while one of the scans that I made was 18.363.846.656 Byte (18.3 GB).
I wonder, how is it possible? is it a mistake in my code, or are they using some memory management methods that I am not aware of?
#include <iostream>
#include <Windows.h>
int main()
{
// Get an handle to the process
HWND hWnd = FindWindowA(NULL, "WindowName");
DWORD pid; GetWindowThreadProcessId(hWnd, &pid);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
// Declaration of some variables
char* Ptr(0);
MEMORY_BASIC_INFORMATION Mem;
size_t totalSize = 0;
// Start querying
while (VirtualQueryEx(hProcess, Ptr, &Mem, sizeof(MEMORY_BASIC_INFORMATION)))
{
if (Mem.State == MEM_COMMIT && Mem.Protect == PAGE_READWRITE)
{
totalSize += Mem.RegionSize;
std::cout << std::hex << Mem.BaseAddress << " - " << (LPVOID)(Mem.RegionSize + (INT64)Mem.BaseAddress) << " - size:(" << std::dec << Mem.RegionSize << ")\n";
}
Ptr += Mem.RegionSize;
}
std::cout << "[" << totalSize << "]";
CloseHandle(hProcess);
return 0;
}
You cannot query physical memory using any normal documented Windows API functions. Virtual Memory is intended to be an abstraction, the Operating System is meant to handle all this in the background for you.
There is RAMMap from SysInternals which can display information regarding physical memory but the source code is not public. RAMMap is explained in this video from Microsoft
To learn more about how the system works you can look up "physical memory" in the Windows Internals book.
There is some code in this answer which claims to be able to query physical memory from usermode here using NtOpenSection and NtMapViewOfSection.
To interact with physical memory from a kernel driver you can read this source code
Blackbone is located here:
https://github.com/DarthTon/Blackbone
Now what I would like to try to achieve is to read process memory using the aforementioned library.
I have used the pattern scan method to obtain an address in memory which I will later use in the reading process, however I'm getting a bit stuck on whether how I should read the data stored at the Output buffer that the read method is using.
The Read method is structured here:
https://github.com/DarthTon/Blackbone/blob/master/src/BlackBone/Process/ProcessMemory.h#L57
And I'm following exactly the same approach taken in the patternscan example provided at:
https://github.com/DarthTon/Blackbone/blob/master/src/TestApp/PatternTest.cpp
Just with a little slightly difference:
void FindKeys()
{
Process p;
std::vector<DWORD> procs;
std::vector<ptr_t> results;
ptr_t dwAddress;
size_t dwSize;
PVOID pResult;
bool handleHoles = true;
Process::EnumByName(L"Notepad++.exe", procs);
if (!procs.empty())
{
p.Attach(procs.front());
auto pMainMod = p.modules().GetMainModule();
// Initialize patterns
PatternSearch ps1{ 0x33, 0xC5, 0x89 };
// Scan all allocated process memory
std::wcout << L"[+] Searching for Pattern Scan...\n";
ps1.SearchRemoteWhole(p, false, 0, results);
std::wcout << L"[+] Found at Address: [0x";
std::wcout << std::hex << results[0];
std::wcout << L"]!\n";
dwAddress = results[0];
dwSize = 0x10;
p.memory().Read(dwAddress, dwSize, pResult, handleHoles);
results.clear();
}
else
std::wcout << L"Can't find Notepad++.exe, aborting\n\n";
}
My question comes from failing to read pResult, how could I successfully read from it, specifically, I would like to read it as an array of bytes.
Thanks in advance for any further help you guys provide me, it will be deeply appreciated!
Alright guys, here is it, fairly simple! and I was over complicating myself.
What I did was to create another variable type BYTE (unsigned char byte) named pResultBytes and then use memcpy(&pResultBytes, pResult, dwSize); where pResult is the output buffer from the Read() method and dwSize is the number of bytes to copy to the new variable.
Next I just started iterating through the pResultBytes variable byte by byte and doing the relative conversions to make a hex string and ultimately read it.
Woops almost for got to mention, I also initialized pResult to a new UCHAR[dwSize]; as well, so it eventually has the proper space required for the memcpy.
That's it!
Cheers!
In some code I use the Win32 RegGetValue() API to read a string from the registry.
I call the aforementioned API twice:
The purpose of the first call is to get the proper size to allocate a destination buffer for the string.
The second call reads the string from the registry into that buffer.
What is odd is that I found that RegGetValue() returns different size values between the two calls.
In particular, the size value returned in the second call is two bytes (equivalent to one wchar_t) less than the first call.
It's worth noting that the size value compatible with the actual string length is the value returned by the second call (this corresponds to the actual string length, including the terminating NUL).
But I don't understand why the first call returns a size two bytes (one wchar_t) bigger than that.
A screenshot of program output and Win32 C++ compilable repro code are attached.
Repro Source Code
#include <windows.h>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void PrintSize(const char* const message, const DWORD sizeBytes)
{
cout << message << ": " << sizeBytes << " bytes ("
<< (sizeBytes/sizeof(wchar_t)) << " wchar_t's)\n";
}
int main()
{
const HKEY key = HKEY_LOCAL_MACHINE;
const wchar_t* const subKey = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion";
const wchar_t* const valueName = L"CommonFilesDir";
//
// Get string size
//
DWORD keyType = 0;
DWORD dataSize = 0;
const DWORD flags = RRF_RT_REG_SZ;
LONG result = ::RegGetValue(
key,
subKey,
valueName,
flags,
&keyType,
nullptr,
&dataSize);
if (result != ERROR_SUCCESS)
{
cout << "Error: " << result << '\n';
return 1;
}
PrintSize("1st call size", dataSize);
const DWORD dataSize1 = dataSize; // store for later use
//
// Allocate buffer and read string into it
//
vector<wchar_t> buffer(dataSize / sizeof(wchar_t));
result = ::RegGetValue(
key,
subKey,
valueName,
flags,
nullptr,
&buffer[0],
&dataSize);
if (result != ERROR_SUCCESS)
{
cout << "Error: " << result << '\n';
return 1;
}
PrintSize("2nd call size", dataSize);
const wstring text(buffer.data());
cout << "Read string:\n";
wcout << text << '\n';
wcout << wstring(dataSize/sizeof(wchar_t), L'*') << " <-- 2nd call size\n";
wcout << wstring(dataSize1/sizeof(wchar_t), L'-') << " <-- 1st call size\n";
}
Operating System: Windows 7 64-bit with SP1
EDIT
Some confusion seems to be arisen by the particular registry key I happened to read in the sample repro code.
So, let me clarify that I read that key from the registry just as a test. This is not production code, and I'm not interested in that particular key. Feel free to add a simple test key to the registry with some test string value.
Sorry for the confusion.
RegGetValue() is safer than RegQueryValueEx() because it artificially adds a null terminator to the output of a string value if it does not already have a null terminator.
The first call returns the data size plus room for an extra null terminator in case the actual data is not already null terminated. I suspect RegGetValue() does not look at the real data at this stage, it just does an unconditional data size + sizeof(wchar_t) to be safe.
(36 * sizeof(wchar_t)) + (1 * sizeof(wchar_t)) = 74
The second call returns the real size of the actual data that was read. That size would include the extra null terminator only if one had to be artificially added. In this case, your data has 35 characters in the path, and a real null terminator present (which well-behaved apps are supposed to do), thus the extra null terminator did not need to be added.
((35+1) * sizeof(wchar_t)) + (0 * sizeof(wchar_t)) = 72
Now, with that said, you really should not be reading from the Registry directly to get the CommonFilesDir path (or any other system path) in the first place. You should be using SHGetFolderPath(CSIDL_PROGRAM_FILES_COMMON) or SHGetKnownFolderPath(FOLDERID_ProgramFilesCommon) instead. Let the Shell deal with the Registry for you. This is consistent across Windows versions, as Registry settings are subject to be moved around from one version to another, as well as accounting for per-user paths vs system-global paths. These are the main reasons why the CSIDL API was introduced in the first place.
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.