I have a program. I want it to be able to mmap a particular region of memory over different runs.
I have the source code of the program. C/C++
I control how the program is compiled. gcc
I control how the program is linked. gcc
I control how the program is run (Linux).
I just want to have this particular region of memory, say 0xabcdabcd to 0xdeadbeef that I mmap to a particular file. Is there anyway to guarantee this? (I have to somehow make sure that other things aren't loaded into this particular region).
EDIT:
How do I make sure that nothing else takes this particular region in memory?
You need to do two things:
Specify the starting address as the first argument to mmap.
Include the MAP_FIXED flag.
For the starting address, you need to make sure it's a multiple of the pagesize. To get the pagesize, use the call sysconf(_SC_PAGESIZE) (that's the appropriate call on Linux, other platforms may be different).
Pass the address to map in addr. Try to get it on a 8KB boundary. You could try mlock() instead though.
You cannot make sure that nothing else takes that area of memory - first come, first served. However, as you need a particular part of the memory, I'm guessing that you have a pretty specialized environment, so you simply need to make sure that you are first (using start scripts)
Related
Can I allocate a block on the heap, set its bytes to values that correspond to a function call and its parameters, then use the function call and dereference operators to execute that sequence?
So if I read you right you want to dynamically create CPU assembly instructions on the heap and execute them. A bit like self-modifying code. In theory that's possible, but in practice maybe not.
The problem is that the heap is in a data segment, and CPU's/operating systems nowadays have measures to prevent exactly this kind of behavior (it's called the NX bit, or No-eXecute bit for x86 CPUs). If a segement is marked as NX, you can't execute code from it. This was invented to stop computer virusses from using buffer overflows to place exectuable code in data/heap/stack memory and then try the calling program to execute such code.
Note that DLL's and libraries are loaded in the code segment, which of course allows code execution.
Yes. How else could Dynamic loading and Linking work? Remembering that some (most?) Operating Systems, and some (most?) Linkers are also written in C/C++. For example,
#include <dlfcn.h>
void* initializer = dlsym(sdl_library,"SDL_Init");
if (initializer == NULL) {
// report error ...
} else {
// cast initializer to its proper type and use
}
Also, I believe that a JIT (e.g. GNU lightning and others) in general performs those operations.
In windows, for example, this is now very hard to do when it was once very easy. I used to be able to take an array of bytes in C and then cast it to a function pointer type to execute it... but not any more.
Now, you can do this if you can call Global or VirtualAlloc functions and specifically ask for executable memory. On most platforms its either completely open or massively locked down. Doing this sort of thing on iOS, for example, is a massive headache and it will cause a submission fail on the app store if discovered.
here is some fantastically out of date and crusty code where i did the original thing you described:
https://code.google.com/p/fridgescript/source/browse/trunk/src/w32/Code/Platform_FSCompiledCode.cpp
using bytes from https://code.google.com/p/fsassembler
you may notice in there that i need to provide platform (windows) specific allocation functions to get some executable memory:
https://code.google.com/p/fridgescript/source/browse/trunk/src/w32/Core/Platform_FSExecutableAlloc.cpp
Yes, but you must ensure that the memory is marked executable. How you do that depends on the architecture.
I'm trying to understand something about HGLOBALs, because I just found out that what I thought is simply wrong.
In app A I GlobalAlloc() data (with GMEM_SHARE|GMEM_MOVABLE) and place the string "Test" in it. Now, what can I give to another application to get to that data?
I though (wrongfully!) that HGLOBALs are valid in all the processes, which is obviously wrong, because HGLOBAL is a HANDLE to the global data, and not a pointer to the global data (that's where I said "OHHHH!").
So how can I pass the HGLOBAL to another application?
Notice: I want to pass just a "pointer" to the data, not the data itself, like in the clipboard.
Thanks a lot! :-)
(This is just a very long comment as others have already explained that Win32 takes different approach to memory sharing.)
I would say that you are reading into books (or tutorials) on Windows programming which are quite old and obsolete as Win16 is virtually dead for quite some time.
16-bit Windows (3.x) didn't have the concept of memory isolation (or virtual /flat/ address space) that 32-bit (and later) Windows versions provide. Memory there used to be divided into local (to the process) and global sections, both living in the same global address space. Descriptors like HGLOBAL were used to allow memory blocks to be moved around in physical memory and still accessed correctly despite their new location in the address space (after proper fixation with LocalLock()/GlobalLock()). Win32 uses pointers instead since physical memory pages can be moved without affecting their location in the virtual address space. It still provides all of the Global* and Local* API functions for compatibility reasons but they should not be used anymore and usual heap management should be used instead (e.g. malloc() in C or the new operator in C++). Also several different kind of pointers existed on Win16 in order to reflect on the several different addressing modes available on x86 - near (same segment), far (segment:offset) and huge (normalised segment:offset). You can still see things like FARPTR in legacy Win16 code that got ported to Win32 but they are defined to be empty strings as in flat mode only near pointers are used.
Read the documentation. With the introduction of 32-bit processing, GlobalAlloc() does not actually allocate global memory anymore.
To share a memory block with another process, you could allocate the block with GlobalAlloc() and put it on the clipboard, then have the other process retreive it. Or you can allocate a block of shared memory using CreateFileMapping() and MapViewOfFile() instead.
Each process "thinks" that it owns the full memory space available on the computer. No process can "see" the memory space of another process. As such, normally, nothing a process stores can be seen by another process.
Because it can be necessary to pass information between processess, certain mechanisms exists to provide this functionality.
One approach is message passing; one process issues a message to another, for example over a pipe, or a socket, or by a Windows message.
Another is shared memory, where a given block of memory is made available to two or more processes, such that whatever one process writes can be seen by the others.
Don't be confused with GMEM_SHARE flag. It does not work the way you possibly supposed. From MSDN:
The following values are obsolete, but are provided for compatibility
with 16-bit Windows. They are ignored.
GMEM_SHARE
GMEM_SHARE flag explained by Raymond Chen:
In 16-bit Windows, the GMEM_SHARE flag controlled whether the memory
should outlive the process that allocated it.
To share memory with another process/application you instead should take a look at File Mappings: Memory-mapped files and how they work.
I have been looking for a way to dynamically load functions into c++ for some time now, and I think I have finally figure it out. Here is the plan:
Pass the function as a string into C++ (via a socket connection, a file, or something).
Write the string into file.
Have the C++ program compile the file and execute it. If there are any errors, catch them and return it.
Have the newly executed program with the new function pass the memory location of the function to the currently running program.
Save the location of the function to a function pointer variable (the function will always have the same return type and arguments, so
this simplifies the declaration of the pointer).
Run the new function with the function pointer.
The issue is that after step 4, I do not want to keep the new program running since if I do this very often, many running programs will suck up threads. Is there some way to close the new program, but preserve the memory location where the new function is stored? I do not want it being overwritten or made available to other programs while it is still in use.
If you guys have any suggestions for the other steps as well, that would be appreciated as well. There might be other libraries that do things similar to this, and it is fine to recommend them, but this is the approach I want to look into — if not for the accomplishment of it, then for the knowledge of knowing how to do so.
Edit: I am aware of dynamically linked libraries. This is something I am largely looking into to gain a better understanding of how things work in C++.
I can't see how this can work. When you run the new program it'll be a separate process and so any addresses in its process space have no meaning in the original process.
And not just that, but the code you want to call doesn't even exist in the original process, so there's no way to call it in the original process.
As Nick says in his answer, you need either a DLL/shared library or you have to set up some form of interprocess communication so the original process can send data to the new process to be operated on by the function in question and then sent back to the original process.
How about a Dynamic Link Library?
These can be linked/unlinked/replaced at runtime.
Or, if you really want to communicated between processes, you could use a named pipe.
edit- you can also create named shared memory.
for the step 4. we can't directly pass the memory location(address) from one process to another process because the two process use the different virtual memory space. One process can't use memory in other process.
So you need create a shared memory through two processes. and copy your function to this memory, then you can close the newly process.
for shared memory, if in windows, looks Creating Named Shared Memory
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366551(v=vs.85).aspx
after that, you still create another memory space to copy function to it again.
The idea is that the normal memory allocated only has read/write properties, if execute the programmer on it, the CPU will generate the exception.
So, if in windows, you need use VirtualAlloc to allocate the memory with the flag,PAGE_EXECUTE_READWRITE (http://msdn.microsoft.com/en-us/library/windows/desktop/aa366887(v=vs.85).aspx)
void* address = NULL;
address= VirtualAlloc(NULL,
sizeof(emitcode),
MEM_COMMIT|MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
After copy the function to address, you can call the function in address, but need be very careful to keep the stack balance.
Dynamic library are best suited for your problem. Also forget about launching a different process, it's another problem by itself, but in addition to the post above, provided that you did the virtual alloc correctly, just call your function within the same "loadder", then you shouldn't have to worry since you will be running the same RAM size bound stack.
The real problems are:
1 - Compiling the function you want to load, offline from the main program.
2 - Extract the relevant code from the binary produced by the compiler.
3 - Load the string.
1 and 2 require deep understanding of the entire compiler suite, including compiler flag options, linker, etc ... not just the IDE's push buttons ...
If you are OK, with 1 and 2, you should know why using a std::string or anything but pure char *, is an harmfull.
I could continue the entire story but it definitely deserve it's book, since this is Hacker/Cracker way of doing things I strongly recommand to the normal user the use of dynamic library, this is why they exists.
Usually we call this code injection ...
Basically it is forbidden by any modern operating system to access something for exceution after the initial loading has been done for sake of security, so we must fall back to OS wide validated dynamic libraries.
That's said, one you have valid compiled code, if you realy want to achieve that effect you must load your function into memory then define it as executable ( clear the NX bit ) in a system specific way.
But let's be clear, your function must be code position independant and you have no help from the dynamic linker in order to resolve symbol ... that's the hard part of the job.
I was wondering if it was possible to access a direct block of memory using C/C++ and grab the value. For example:
int i = 15;
int *p = &i;
cout << &i;
If I took the printed value here, that would give me the address of the variable i, which contains the value 15. I will just say it printed out 0x0ff9c1 for this example. If I have a separate program which declares a pointer like so...
int *p = 0x0ff9c1;
cout << *p;
Would it be possible to print out that 15 that the other application placed in the memory block 0x0ff9c1? I know my pointer declaration with the memory address is incorrect, I am unsure how to do it otherwise. I have tried using memcopy but I have not been able to get that to work either. I know this is possible somehow as I have a program called Cheat Engine which modifies game memory address values to gain unfair advantages. I have been successful in placing the printed memory location and obtaining the value (15) though Cheat Engine. My goal is to do this using C++.
If this is too confusing, basically I would like to access a variable that another application stored using its memory address and print out the value. I am using Windows 7 x64 with MinGW compiler if that matters. Thanks!
PS: I'll post a picture of what Cheat Engine does to give a better idea.
The two processes have separate address spaces. One process cannot access another processses memory unless it is explicily shared memory.
You can't do it in a platform-agnostic way in C++. While I haven't used this "cheat engine" specifically, it almost certainly is using the same special API that a debugger uses. The code will be specific to Windows, and you will require a certain privilege level on the running process.
(For instance, if you are using Visual Studio and execute a program from it in a Debug Mode, Visual Studio can look at and modify values in that program.)
I haven't written a debugger in a while, so I don't know where a good place to get started on the Debug API is, but you can search around the web for things like this article:
http://www.woodmann.com/fravia/iceman1.htm
If you want to change the memory used by another process, one way would be to inject your code into the other process. From that point, you can do whatever you want to the other program's memory as if it were your owns.
Search around for remote thread creation or hooking. There are more than a few questions about it here (and here, for starters).
In general, it's not usually possible for one program to modify the memory of another. The system goes to great lengths to ensure this. If it did not, no program would be safe. This is particularly true in all the Unix variants I've worked on, though not on all proprietary OSes I've seen.
Note that none of these rules apply to the kernel ...
There is also a programming paradigm called shared memory, but you have to explicitly set that up.
Short answer: you can't usually do that. I believe you mentioned windows. I know nothing about Windows, so your mileage may vary.
A bit late, but you still could this through a DLL injection. Here is a link to a tutorial: http://resources.infosecinstitute.com/using-createremotethread-for-dll-injection-on-windows/
I have a pointer to a function (which i get from a vtable) and I want to edit the function by changing the assembler code (changing a few bytes) at runtime. I tried using memset and also tried assigning the new value directly (something like mPtr[0] = X, mPtr[1] = Y etc.) but I keep getting segmentation fault.
How can I change the code?
(I'm using C++)
OS is windows.
In generally: if memory is allocated with API call VirtualAlloc than you can change the memory attributes with API call VirtualProtect.
Check first memory attributes with API call VirtualQuery
Depending on Operating System and/or architecture you may or may not write to executable pages.
Check documentation about marking pages as executable or read-only in the Intel (IA-32e) manuals. The code may be located in a read only section, therefore, you may not write to it.
You may mark the code not to reside in read only pages, but it's compiler specific (JIT compilers do this).
Under MSVC, you can use the #pragma section to create a read-write section and use #pragma alloc_text to put functions in it.
In general, you are trying to write to the code segment, something new operating systems will prevent you to do. This is the way some viruses worked.
There are APIs to remove that protection, but they are operating system dependent.
Memory sections where your code reside are usually marked as readonly. That's why you get segmentation failure. You can try to remove this flag from section by either special keys for compiler (not sure about that) or by modifying binary file (again, not 100% that it is possible)