I am thinking about a problem I have been having for some time now.. I would like to write a C/C++ program (under windows first) that can access(read/change values) the memory(stack, heap, everything) of other running programs. (Not like shared memory but any memory the computer has..) Without having to start the application from my own application..
I have seen something like this before but I just can't figure out how it's done.. If I were to access the memory of any running program I would get errors from the OS right?
Any help is appreciated!
As #sharptooth said, this requires support from the OS. Different OS does it differently. Since you are on Windows, there are a few steps you could follow:
Call OpenProcess, or CreateProcess to access, or launch a new process. In this call, you must request PROCESS_VM_READ access.
Call ReadProcessMemory to read a chunk of memory in that opened process.
If you want to change memory of another process, you then need PROCESS_VM_WRITE access and use WriteProcessMemory to achieve that.
In Linux, for example, you'd use ptrace to attach to a process and peek, poke its memory.
You can start a process (another program) from your own application, and access some of its information (especially shared memory). The contrary is very difficult, the CPU fakes the memory addresses so each process believes that it has the whole memory available...
You might be interested in taking a look at the Toolhelp32ReadProcessMemory function.
Related
Memory editors such as Cheat Engine are able to read the memory of other processes and modify it.
How do they do it?(a code snippet would be interesting!) A process does typically not have the ability to access the memory of another one, the only cases that I've heard of are in sub-processes/threading, but memory editors are typically not related to the target process in any way.
Why do they work? In what scenario is this ability useful aside from using it to hack other processes, why wouldn't the operating system simply disallow unrelated processes from reading the memory of each other?
On Windows, the function typically used to alter the memory of another process is called WriteProcessMemory:
https://learn.microsoft.com/en-in/windows/win32/api/memoryapi/nf-memoryapi-writeprocessmemory
If you search the Cheat Engine source code for WriteProcessMemory you can find it both in their Pascal code and the C kernel code. It needs PROCESS_VM_WRITE and PROCESS_VM_OPERATION access to the process which basically means you need to run Cheat Engine as admin.
WriteProcessMemory is used any time you want to alter the runtime behavior of another process. There are legitimate uses, such as with Cheat Engine or ModOrganizer, and of course lots of illegitimate ones. It's worth mentioning that anti-virus software is typically trained to look for this API call (among others) so unless your application has been whitelisted it might get flagged because of it.
Operating systems typically expose system calls that allow a userspace program to inspect a target process's memory using said system calls.
For instance, the linux kernel supports the ptrace system call. This system call is primarily used by the well known debugger gdb and by popular system call tracing utilities such as strace.
The ptrace system call allows for the inspection of memory contents of the target process, code injection, register manipulation and much more. I would suggest this as a resource if you are interested in learning more.
On Linux, you can either run a binary from within gdb, or attach to a process. In case of the latter, you need elevated privileges. There are other protections that try to limit what you can do with ptrace, such as the one mentioned here.
On Windows you can achieve the same effect by using the following functions in order : OpenProcess, GetProcAddress, VirtualAllocEx, WriteProcessMemory and CreateRemoteThread. I would suggest this as a resource if you are interested in knowing more. You might need elevated privileges to do this on newer Windows versions.
Is it's possible to get access to memory that located outside current application? For example I need to check how App2 is using it's memory (check memory fragmentation). afaik every app have own virtual memory, but I need to check memory that located outside it.
Yes, that's how debuggers work, and you can allocate shared memory if the two program will cooperate on it. You can also request access to the raw system memory through the kernel if your program is running with sufficient administrator powers and the system is configured for it.
On Windows, there is a function called ReadProcessMemory that will make a copy for you. On Linux, you can open /proc/[pid]/mem and access it through that. You can also look up tutorials on how to write a debugger and attach to a process that way.
However, I wouldn't attempt this yourself unless you're already experienced... It is so much harder than you realize to get anything useful. Instead, try using existing programs like debuggers and memory analyzers, or instrument your App2 to report on itself.
I'm developing application for an embedded system with limited memory (Tegra 2) in C++. I'm handling NULL results of new and new[] throughout the code which sometimes occurs but application is able to handle this.
The problem is that the system kills the process by SIGKILL if the memory runs out completely. Can I somehow tell that new should just return NULL instead of killing the process?
I am not sure what kind of OS You are using, but You should check if
it supports opportunistic memory allocation like Linux does.
If it is enabled, the following may happen (details/solution are specific to the Linux kernel):
Your new or malloc gets a valid address from the kernel. Even if there is not enough memory, because ...
The kernel does not really allocate the memory until the very moment of the first access.
If all of the "overcommitted" memory is used, the operating system has no chance but killing one of the involved processes. (It is too late to tell the program that there is not enough memory.) In Linux, this is called Out Of Memory Kill (OOM Kill). Such kills get logged in the kernel message buffer.
Solution: Disable overcommitting of memory:
echo 2 > /proc/sys/vm/overcommit_memory
Two ideas come to mind.
Write your own memory allocation function rather than depending on new directly. You mentioned you're on an embedded system, where special allocators are quite common in applications. Are you running your application directly on the hardware or are you running in a process under an executive/OS layer? If the latter, is there a system API provided for allocating memory?
Check out C++ set_new_handler and see if it can help you. You can request that a special function is invoked when a new allocation fails. Perhaps in that function you can take action to prevent whatever is killing the process from executing. Reference: http://www.cplusplus.com/reference/std/new/set_new_handler/
I'm using Windows 8 64 bit. I know C++ and basics of assembly. If I were to write an anti-virus program, it should be able to access any process's memory, right? I have managed to write a program that is able to read most process's memory, using VirtualQueryEx and ReadProcessMemory. However, I've come across an application that doesn't let me use VirtualQueryEx. Even with debug privileges it fails with Access Denied error.
Is there anything I can do to enable myself the access to the process's memory using VirtualQueryEx? Or should I take other approach to access such hard accessible processes?
I've already done some research and wonder which approach should I follow:
I've come across an information that it's possible to read any memory in kernel mode without any restrictions. Is that true? But in kernel mode there is no functions such us VirtualQueryEx or ReadProcessMemory. I guess I need to implement them by myself? But I've seen opinions that such functions are very unstable and in the future I might get a BSOD or sth... Some say I shouldn't even use kernel mode for reading memory purposes. Could somebody give me an answer how it actually is with this kernel mode?
I heard that applications might hook some APIs so that it prevents other apps from using these functions. Might VirtualQueryEx be hooked in that process? and that's the reason I get access denied all the time? If that's the case how could I unhook this?
Anti-viruses are not likely to do this probably, but would simple DLL injection work? I mean, if I were able to inject dll to that process then inside my dll I would already be withing that process's virtual address space so reading its memory shouldn't be a problem then?
Another approach?
I would be really grateful for any tips and help in this matter!
Yes it's possible, but it will be very tedious and error prone. It will not be as easy as VirtualQueryEx/RPM. I would actually just ensure my user-mode application has enough rights to do the API calls and not read the memory in the kernel. Also you can't easily load a self made driver on a 64-bit Windows. You either need to sign your driver (costs money) or find some security hole in Windows (or start your machine in an unsafe mode).
Yes, that's possible. One way to hook APIs globally would be to write a driver that redirects the API calls. Another way would be global or targeted dll injection to hook the API calls. The latter you can check with a debugger. If the kernel redirects the calls, you can only detect that by being in the kernel yourself.
I doubt that this would work, because you'd need way more process rights to inject a dll than to query/read some memory. If you want to read a specific known application you could try to get the target to load your dll by writing a wrapper for some dll it loads and replace the original.
Are you sure you need to read memory from this process? Is it any of the System Process, Idle Process, CSRSS that cannot be opened from user mode? Have you lowered your requested rights as much as possible? It think you only need PROCESS_QUERY_INFORMATION and PROCESS_VM_READ.
How does one create and launch process (i.e. launch an .exe file) with RAM limitation using c++ and the win32 API?
Which error code will be returned, if the proccess goes beyond the limit?
Job Objects are the right way to go.
As for an error code, there really isn't one. You create the process (with CreateProcess) and the job (with CreateJobObject), then associate the process with the job object (with AssignProcessToJobObject).
The parent process won't get an error message if the child allocates more than the allowed amount of memory. In fact, the limit will be enforced even if the parent process exits. If the child process tries to allocate more than the allowed amount of memory, the allocation will simply fail.
You can use CreateProcess() to spawn a process.
Once you have done that, you can use SetProcessWorkingSetSize() to attempt to control how much physical memory it uses, but this is more of a really strong suggestion to the VMM than some actual edict that will cause malloc() and new to start failing.
There is no way to say "this process will take 4mb of memory and after that all allocations fail". I mean, you're going to link to win32 dlls and you have no idea what sort of memory usage those things require. If you want your app to only take some certain amount of memory, don't allocate more than that. And don't do things that allocate memory.
Your question regarding the error code makes no sense at all.
NT Job objects ( SetInformationJobObject & JOBOBJECT_BASIC_LIMIT_INFORMATION )
By my knowledge there is no such possibility on windows. It would be very useful to have though, for testing and other things.
You have this on java as a JVM uses only a predefined amount of memory, but there its not a feature, but rather a problem ;-)
If you launch a process, you lose control over this process. Just the operating system can control its behavior (memory footprint i.e.) but even in that case I can't imagine how this could be achieved, as jeffamaphone stated, any limitation is at best a suggestion, not a instruction. A process can call external static libraries, COM instances, etc, so I don't imagine how this limit could be verified/enforced.