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
Related
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.
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
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.
Following is the code that I am using for mmaping a file in ubuntu with hugepages, but this call is failing with error "invalid argument". However, when I do pass
MAP_ANON flag with no file descriptor parameter in mmap, then it works. I am not being able to understand the possible reason behind this.
Secondly, I am not able to understand why file mmaping is allowed with MAP_PRIVATE when this flag itself means that no change will be written back to file. This can always be accomplished using MAP_ANON, or is there something I am missing ?
Can someone help me with these ?
int32_t main(int32_t argc, char** argv) {
int32_t map_length = 16*1024*1024; // 16 MB , huge page size is 2 MB
int32_t protection = PROT_READ | PROT_WRITE;
int32_t flags = MAP_SHARED | MAP_HUGETLB;
int32_t file__ = open("test",O_RDWR|O_CREAT | O_LARGEFILE,s_IRWXU | S_IRGRP | S_IROTH);
if(file__ < 0 ) {
std::cerr << "Unable to open file\n";
return -1;
}
if (ftruncate(file__, map_length) < 0) {
std::cerr
<< "main :: unable to truncate the file\n"
<< "main :: " << strerror(errno) << "\n"
<< "main :: error number is " << errno << "\n";
return -1;
}
void *addr= mmap(NULL, map_length, protection, flags, file__, 0);
if (addr == MAP_FAILED) {
perror("mmap");
return -1;
}
const char* msg = "Hello World\n";
int32_t len = strlen(msg);
memcpy(addr,msg,len);
munmap(addr, map_length);
close(file__);
return 0;
}
Both your questions come down to the same point: Using mmap() you can obtain two kinds of mappings: anonymous memory and files.
Anonymous memory is (as stated in the man page) not backed by any file in the file system. Instead the memory you get back from an MAP_ANON call to mmap() is plain system memory. The main user of this interface is the C library which uses it to obtain backing storage for malloc/free. So, using MAP_ANON is explicitly saying that you don't want to map a file.
File-backed memory kind of blends in a file (or portions of it) into the address space of your application. In this case, the memory content is actually backed by the file's content. Think of the MAP_PRIVATE flag as first allocating memory for the file and then copying the content into this memory. In truth this will not be what the kernel is doing, but let's just pretend.
HUGE_TLB is a feature the kernel provides for anonymous memory (see Documentation/vm/hugetlb‐page.txt as referenced in the mmap() man page). This should be the reason for your mmap() call failing when using HUGETLB for a file. *Edit: not completely correct. There is a RAM file system (hugetlbfs) that does support huge pages. However, huge_tlb mappings won't work on arbitrary files, as I understand the docs.*
For details on how to use HUGE_TLB and the corresponding in-memory file system (hugetlbfs), you might want to consider the following articles on LWN:
Huge Pages, Part 1 (Intro)
Huge Pages, Part 2 (Interfaces)
Huge Pages, Part 3 (Administration)
Huge Pages, Part 4 (Benchmarking)
Huge Pages, Part 5 (TLB costs)
Adding MAP_PRIVATE to the flags fixed this for me.
I've a bad problem. I'm trying to write to a file via filedescriptor and memalign. I can write to it but only something like an wrong encoded char is written to a file.
Here's my code:
fdOutputFile = open(outputFile, O_CREAT | O_WRONLY | O_APPEND | O_DIRECT, 0644)
void writeThis(char* text) {
while (*text != '\0') {
// if my internal buffer is full -> write to disk
if (buffPositionOutput == outputbuf.st_blksize) {
posix_memalign((void **)&bufferO, outputbuf.st_blksize, outputbuf.st_blksize);
cout << "wrote " << pwrite(fdOutputFile, bufferO, outputbuf.st_blksize, outputOffset*outputbuf.st_blksize) << " Bytes to disk." << endl;
buffPositionOutput = 0;
++outputOffset;
}
// buffer the incoming text...
bufferO[buffPositionOutput] = *text;
++text;
++buffPositionOutput;
}
}
I think it's the alignment - can someone help me?
It writes to the file but not the correct text, just a bunch of '[]'-chars.
Thanks in advance for your help!
Looking at your program, here is what happens:
You fill the memory initially pointed to by buffer0+buffPositionOutput (Which is where, precisely? I don't know based on the code you give.) up to buffer0+outputbuf.st_blksize with data.
You pass the address of the buffer0 pointer to posix_memalign, which ignores its current value and overwrites it with a pointer to outputbuf.st_blksize bytes of newly-allocated memory.
You write data from the newly-allocated block to disk; this might be anything, since you just allocated memory and haven't written anything there yet.
This won't work, obviously. You probably want to initialize your buffer via posix_memalign at the top of your function, and then just overwrite the block's worth of data in it as you use your aligned buffer to repeatedly write data into the file. (Reset buffpositionoutput to zero after each time you write data, but don't re-allocate.) Make sure you free your buffer when you are done.
Also, why are you using pwrite instead of write?
Here's how I would implement writeThis (keeping your variable names so you can match it up with your version):
void writeThis(char *text) {
char *buffer0;
size_t buffPositionOutput = 0;
posix_memalign(&buffer0, outputbuf.st_blksize, outputbuf.st_blksize);
while (*text != 0) {
++text; ++buffPositionOutput;
if (buffPositionOutput == outputbuf.st_blksize) {
write(fdOutputFile, buffer0, outputbuf.st_blksize);
buffPositionOuput = 0;
}
}
if (buffPositionOutput != 0) {
// what do you want to do with a partial block of data? Not sure.
}
}
(For speed, you might consider using memcpy calls instead of a loop. You would need to know the length of the data to write ahead of time though. Worry about that after you have a working solution that does not leak memory.)
You're re-allocating buffer0 every time you try to output it, and not freeing it. That's really not efficient (and leaks memory). I'd suggest you refactor your code a bit, because it's quite hard to follow whether your bounds checking on that buffer is correct or not.
Allocate buffer0 only once somewhere (form that snippet, storing it in outputbuf sounds like a good idea). Also store buffPositionOutput in that struct (or in another struct, but close to that buffer).
// in setup code
int rc = posix_memalign(&(outputbuf.data), outputbuf.st_blksize,
outputbuf.st_blksize);
// check rc!
outputbuf.writePosition = 0;
// in cleanup code
free(outputbuf.data);
Then you can rewrite your function like this:
void writeThis(char *text) {
while (*text != 0) {
outputbuf.data[outputbuf.writePosition] = *text;
outputbuf.writePosition++;
text++;
if (outputbuf.writePosition == outputbuf.block_size) {
int rc = pwrite(...);
// check rc!
std::cout << ...;
outputbuf.writePosition = 0;
}
}
I don't think C/C++ has encodings. ASCII only.
Unless you use wchar http://en.wikipedia.org/wiki/Wide_character