At runtime, either the assembler or machine code (which is it?) should be somewhere in RAM. Can I somehow get access to it, and read or even write to it?
This is just for educational purposes.
So, I just could compile this code. Am I really reading myself here?
#include <stdio.h>
#include <sys/mman.h>
int main() {
void *p = (void *)main;
mprotect(p, 4098, PROT_READ | PROT_WRITE | PROT_EXEC);
printf("Main: %p\n Content: %i", p, *(int *)(p+2));
unsigned int size = 16;
for (unsigned int i = 0; i < size; ++i) {
printf("%i ", *((int *)(p+i)) );
}
}
Though, if I add
*(int*)p =4;
then it's a segmentation fault.
From the answers, I could construct the following code which modifies itself during runtime:
#include <stdio.h>
#include <sys/mman.h>
#include <errno.h>
#include <string.h>
#include <stdint.h>
void * alignptr(void * ptr, uintptr_t alignment) {
return (void *)((uintptr_t)ptr & ~(alignment - 1));
}
// pattern is a 0-terminated string
char* find(char *string, unsigned int stringLen, char *pattern) {
unsigned int iString = 0;
unsigned int iPattern;
for (unsigned int iString = 0; iString < stringLen; ++iString) {
for (iPattern = 0;
pattern[iPattern] != 0
&& string[iString+iPattern] == pattern[iPattern];
++iPattern);
if (pattern[iPattern] == 0) { return string+iString; }
}
return NULL;
}
int main() {
void *p = alignptr(main, 4096);
int result = mprotect(p, 4096, PROT_READ | PROT_WRITE | PROT_EXEC);
if (result == -1) {
printf("Error: %s\n", strerror(errno));
}
// Correct a part of THIS program directly in RAM
char programSubcode[12] = {'H','e','l','l','o',
' ','W','o','r','l','t',0};
char *programCode = (char *)main;
char *helloWorlt = find(programCode, 1024, programSubcode);
if (helloWorlt != NULL) {
helloWorlt[10] = 'd';
}
printf("Hello Worlt\n");
return 0;
}
This is amazing! Thank you all!
In principle it is possible, in practice your operating system will protect itself from your dangerous code!
Self-modifying code may have been regarded as a "neat-trick" in the days when computers had very tiny memories (in the 1950's). It later (when it was no longer necessary) came to be regarded as bad practice - resulting in code that was hard to maintain and debug.
In more modern systems (at the end of the 20th Century) it became a behaviour indicative of viruses and malware. As a consequence all modern desktop operating systems disallow modification of the code space of a program and also prevent execution of code injected into data space. Modern systems with an MMU can mark memory regions as read-only, and not-executable for example.
The simpler question of how to obtain the address of the code space - that is simple. A function pointer value for example is generally the address of the function:
int main()
{
printf( "Address of main() = %p\n", (void*)main ) ;
}
Note also that on a modern system this address will be a virtual rather then physical address.
Machine code is loaded into memory. In theory you can read and write it just like any other part of memory your program as access to.
There can be some roadblocks to doing this in practice. Modern OSes try and limit the data sections of memory to read/write operations but no execution, and machine code sections of memory to read/execute but no writing. This is to try and limit potential security vulnerabilities that come with allowing executing what ever the program feels like putting into memory (like random stuff it might pull down from the Internet).
Linux provides the mprotect system call to allow some amount of customization for memory protection. Windows provides the SetProcessDEPPolicy system call.
Edit for updated question
It looks like you're trying this on Linux, and using mprotect. The code you posted is not checking the return value from mprotect, so you don't know if the call is succeeding or failing. Here is an updated version that checks the return value:
#include <stdio.h>
#include <sys/mman.h>
#include <errno.h>
#include <string.h>
#include <stdint.h>
void * alignptr(void * ptr, uintptr_t alignment)
{
return (void *)((uintptr_t)ptr & ~(alignment - 1));
}
int main() {
void *p = alignptr(main, 4096);
int result = mprotect(p, 4096, PROT_READ | PROT_WRITE | PROT_EXEC);
if (result == -1) {
printf("Error: %s\n", strerror(errno));
}
printf("Main: %p\n Content: %i", main, *(int *)(main+2));
unsigned int size = 16;
for (unsigned int i = 0; i < size; ++i) {
printf("%i ", *((int *)(main+i)) );
}
}
Note the changes to the length parameter passed to mprotect and the function aligning the pointer to a system page boundary. You'll need to investigate on your specific system. My system has an alignment of 4096 bytes (determined by running getconf PAGE_SIZE) and after aligning the pointer and changing the length parameter to mprotect to the page size this works, and lets you write over your pointer to main.
As others have said, this is a bad way to dynamically load code. Dynamic libraries, or plugins, are the preferred method.
On most operating systems (Linux, Windows, Android, MacOSX, etc...), a program don't execute (directly) in RAM but has its virtual address space and runs in it (stricto sensu, the code is not -always or necessarily- in RAM; you can have code which is not in RAM and which gets executed, after some page fault bring it transparently in RAM). The RAM is (directly) managed by the OS, but your process only sees its virtual address space (initialized at execve(2) time and modified with mmap(2), munmap, mprotect, mlock(2)...). Use proc(5) and try cat /proc/$$/maps in a Linux shell to understand more the virtual address space of your shell process. On Linux, you could query the virtual address space of your process by reading the /proc/self/maps file (sequentially, it is a textual pseudo-file).
Read Operating Systems: Thee Easy Pieces to learn more about OSes.
In practice, if you want to augment the code inside your program (running on some common OS) you'll better use plugins and the dynamic loading facilities. On Linux and POSIX systems you'll use dlopen(3) (which uses mmap etc...) then with dlsym(3) you'll obtain the (virtual) address of some new function and you could call it (by storing it in some function pointer of your C code).
You don't really define what a program is. I claim that a program is not only an executable, but also made of other resources (such as specific libraries, perhaps fonts or configuration files, etc...) and that is why when you install some program, quite often much more than the executable is moved or copied (look into what make install does for most free software programs even as simple as GNU coreutils). Therefore, a program (on Linux) which generates some C code (e.g. in some temporary file /tmp/genecode.c), compiles that C code into a plugin /tmp/geneplug.so (by running gcc -Wall -O -fPIC /tmp/genecode.c -o /tmp/geneplug.so), then dlopen that /tmp/geneplug.so plugin is genuinely modifying itself. And if you code in C exclusively that is a sane way of writing self-modifying programs.
Generally, your machine code sits in the code segment, and that code segment is read-only (and sometimes even execute-only; read about the NX bit). If you really want to overwrite code (and not to extend it), you'll need to use facilities (perhaps mprotect(2) on Linux) to change that permissions and enable rewriting inside the code segment.
Once some part of your code segment is writable, you could overwrite it.
Consider also some JIT-compiling libraries, such as libgccjit or asmjit (and others), to generate machine code in memory.
When you execve a new fresh executable, most of its code does not (yet) sit in RAM. But (from the point view of user code in the application) you can run it (and the kernel will transparently, but lazily, bring code pages into RAM, thru demand paging). That is what I try to explain by saying that your program run in its virtual address space (not directly in RAM). An entire book is needed to explain that further.
For example, if you have a huge executable (for simplicity, assume it is statically linked) of one gigabyte. When you start that executable (with execve) the entire gigabyte is not brought into RAM. If your program exits quickly, most of the gigabyte have not been brought into RAM and stays on the disk. Even if your program runs for a long time, but never calls a huge routine of a hundred megabyte of code, that code part (the 100Mbyte of the never used routine) won't be in RAM.
BTW, stricto sensu, self modifying code is rarely used these days (and current processors don't even handle that efficiently, e.g. because of caches and branch predictors). So in practice, you don't modify exactly your machine code (even if that would be possible).
And malware don't have to modify the currently executed code. It could (and often does) inject new code in memory and jumps somehow to it (more precisely, call it thru some function pointer). So in general you don't overwrite existing "actively used" code, you create new code elsewhere and you call it or jump to it.
If you want to create new code elsewhere in C, plugin facilities (e.g. dlopen and dlsym on Linux), or JIT libraries, are more than enough.
Notice that the mention of "changing your program" or "writing code" is very ambiguous in your question.
You might just want to extend the code of your program (and then using plugin techniques, or JIT-compilation libraries, is relevant). Notice that some programs (e.g. SBCL) are able to generate machine code at every user interaction.
You could change the existing code of your program, but then you should explain what that exactly means (what does "code" mean for you exactly ? Is it only the currently executed machine instruction or is it the entire code segment of your program?). Do you think of self-modifying code, of generating new code, of dynamic software updating?
Can I somehow get access to it, and read or even write to it?
Of course yes. You need to change protection in your virtual address space for your code (e.g. with mprotect) and then to write many bytes on some "old code" part. Why would you want to do that is a different story (and you have not explained why). I don't see any educational purposes in doing that -you are likely to crash your program quite quickly (unless you take a lot of precautions to write good enough machine code in memory).
I am a great fan of metaprogramming but I generally generate some new code and jump into it. On our current machines, I see no value in overwriting existing code. And (on Linux), my manydl.c program demonstrates that you could generate C code, compile, and dynamically link more than a million plugins (and dlopen all of them) in a single program. In practice, on current laptop or desktop computers, you can generate a lot of new code (before being concerned by limits). And C is fast enough (both in compilation time and in run time) that you could generate a thousands of C lines at every user interaction (so several times per second), compile and dynamically load it (I did that ten years ago in my defunct GCC MELT project).
If you want to overwrite executable files on disk (I see no value in doing that, it is much simpler to create fresh executables), you need to understand deeply their structure. For Linux, dive into the specifications of ELF.
In the edited question, you forgot to test against failure of mprotect. It is probably failing (because 4098 is not a power of 2 and a page multiple). So please at least code:
int c = mprotect(p, 4096, PROT_READ | PROT_WRITE | PROT_EXEC);
if (c) { perror("mprotect"); exit(EXIT_FAILURE); };
Even with the 4096 (instead of 4098) that mprotect is likely to fail with EINVAL, because main is probably not aligned to a 4K page. (Don't forget that your executable also contains crt0 code).
BTW, for educational purposes, you should add the following code near the start of your main:
char cmdbuf[80];
snprintf (cmdbuf, sizeof(cmdbuf), "/bin/cat /proc/%d/maps", (int)getpid());
fflush(NULL);
if (system(cmdbuf))
{ fprintf(stderr, "failed to run %s\n", cmdbuf); exit(EXIT_FAILURE));
and you could add a similar code chunk near the end. You might replace the snprintf format string for cmdbuf with "pmap %d".
The most straightforward and practical way to accomplish this is to use function pointers. You can declare a pointer such as:
void (*contextual_proc)(void) = default_proc;
Then call it with the syntax contextual_proc();. You can also assign a different function with the same signature to contextual_proc, say contextual_proc = proc_that_logs;, and any code that calls contextual_proc() will then (modulo thread-safety) call the new code instead.
This is a lot like self-modifying code in effect, but it is easier to understand, portable, and actually works on modern CPUs where executable memory is not writable and instructions are cached.
In C++, you would use subclasses for this; static dispatch will implement it the same way under the hood.
Related
I'm trying to understand basics of C, volatile keyword exactly.
It doesn't seem to work as I thought.
I read somewhere:
volatile specifies that value associated with the var can be modified by action
other than those in the nearby code.
When a var is declared volatile, the compiler reloads the value from
memory each time it is accessed by the program.
This prevents optimization by optimizing compilers.
It's mainly used to ensure predictable program behavior.
I've got two programs, compiled from two different .c files.
start_loop has global int variable called done with 0 as initial value and infinite loop which should test if done value have been changed to 1. Also it outputs address of the done variable to stdout.
start_loop program:
#include <stdio.h>
#include <time.h>
volatile int done = 0;
void delay(int seconds){
// some logic for time delay here
}
void main() {
while (done !=1){
delay(4);
printf("adress of `done`: %p\nvalue: %d\n", &done, done);
}
}
And change_done_var_value program which should get the address of the done variable as main argument and change it from 0 to 1.
Thus infinite loop in start_loop program should check value of done and exit the program.
change_done_var_value:
#include <stdio.h>
#include <stdlib.h>
void main(int argc, char *argv[])
{
char *str_arg_done = argv[1];
long int done_addr = (int)strtol(str_arg_done, NULL, 16);
long int *done = (long int *)done_addr; // converting str to pointer
printf("got the address as first arg(str): %s -> address/value %p/%li\n", argv[1], done, *done);
printf("change `done` to 1?\n");
char answer = fgetc(stdin);
if (answer == 'y')
{
*done = 1;
printf("changed\nnew value: %li", *done);
}
else
{
printf("canceled\n");
}
As i've started the start_loop program in first terminal tab i got:
4 seconds delay passed
#1
adress of `done`: 0x601048
value: 0
4 seconds delay passed
#2
adress of `done`: 0x601048
value: 0
...
In the second terminal tab i started the change_done_var_value and passed 0x601048 to it:
got the address as first arg(str): 0x601048 -> adress/value 0x601048/0
change `done` to 1?
y
changed
new value: 1
But start_loop program still runs:
4 seconds delay passed
#46
adress of `done`: 0x601048
value: 0
It seems that the change_done_var_value program got the right address value cause it shows right 0 value while dereferencing pointer to done variable..
What do i need to do to make things work(to change value of done from change_done_var_value and stop the executing of thestart_loop program)?
Or it doesn't work like this..
action other than those in the nearby code
Yes; this means things that are able to modify the corresponding chunk of memory. Most often, this will be a different thread within the same program. In some very specific platform-specific circumstances, you might arrange for a variable to be in a specific location that has a special meaning to the OS (or to the hardware); for example, on an old handheld or console you could read from a virtual memory location that represents an I/O register, in order to learn what button was pressed on the keypad. By using volatile, the compiler will understand that the value has to be checked, because the hardware may have written to that memory and your program depends on knowing about the change.
On a modern desktop computer, programs have memory protection and memory space virtualization. They cannot easily look at each others' data, and will typically need some special arrangement/permission to do so. But even when it is possible, you cannot simply check on the other program's variable by using its name - the name is only meaningful to the compiler; it is not an actual part of the compiled program (although a debug-mode compilation might try to make it behave that way a little bit).
If I understand right, you try to use memory from one program in another program? "It doesn't work like this" on any modern operating system because programs (or better: "processes") are encapsulated purposefully this way that they can't access the memory of other processes without operating-system-specific interprocess communication library functions. You can read more about them and how to use them in C in a Linux-based operating system on this website:
Linux Interprocess Communications
I'm sorry that I can't elaborate further since I never used internal interprocess communication on a common Desktop Operating System yet.
There is also a more heavy-weight option to use the socket API (which generally can be used even accross a network of distinct PCs all over the world). Using the socket API is not difficult and is taught in network lecture courses in university. You then get "server" and "client" programs and you have to take care about some "primitives" which must be called in a specific order.
A common source of tutorials seems to be the Beej Guide .
This protection mechanism is called memory virtualization. It makes that every process uses its very own virtual address space which is not equal to the one of other processes. Or brief: the same addresses in different programs will lead to separate physical addresses in the real memory.
In my opinion the design mistake here is to compile two different programs to achieve the task. The usual appraoch would be to compile only one single program which uses multi-threading (that means multiple threads of execution) because multi-threading is more light-weight than interprocess communication and maybe easier to use (at least I know how to do it). For multi-threading, you can use the pthread library in Linux-based systemes which can be included into your program with the -pthread command line option when I remember correctly).
Happy coding!
so, i was making this program that let people know the number of contiguous subarray which sum is equal to a certain value.
i have written the code , but when i try to run this code in vcexpress 2010, it says these error
Unhandled exception at 0x010018e7 in test 9.exe: 0xC00000FD: Stack overflow.
i have tried to search for the solution in this website and other webisites, but i can't seem to find any solution which could help me fix the error in this code(they are using recursion while i'm not).
i would be really grateful if you would kindly explain what cause this error in my code, and how to fix this error. any help would be appreciated. Thank you.
here is my code :
#include <stdio.h>
int main ()
{
int n,k,a=0,t=0;
unsigned long int i[1000000];
int v1,v2=0,v3;
scanf("%d %d",&n,&k);
for(v3=0;v3<n;v3++)
{
scanf("%d",&i[v3]);
}
do
{
for(v1=v2;v1<n;v1++)
{
t=i[v1]+t;
if(t==k)
{
a++;
break;
}
}
t=0;
v2++;
}while(v2!=n);
printf("%lu",a);
return 0;
}
Either move
unsigned long int i[1000000];
outside of main, thus making it a global variable (not an automatic one), or better yet, use some C dynamic heap allocation:
// inside main
unsigned long int *i = calloc(1000000, sizeof(unsigned long int));
if (!i) { perror("calloc"); exit(EXIT_FAILURE); };
BTW, for such a pointer, I would use (for readability reasons) some other name than i. And near the end of main you'll better free(i); to avoid memory leaks.
Also, you could move these 2 lines after the read of n and use calloc(n, sizeof(unsigned long int)) instead of calloc(1000000, sizeof(unsigned long int)) ; then you can handle arrays bigger than a million elements if your computer and system provides enough resources for that.
Your initial code is declaring an automatic variable which goes into the call frame of main on your call stack (which has a limited size, typically a megabyte or a few of them). On some operating systems there is a way to increase the size of that call stack (in an OS-specific way). BTW each thread has its own call stack.
As a rule of thumb, your C functions (including main) should avoid having call frames bigger than a few kilobytes. With the GCC compiler, you could invoke it with gcc -Wall -Wextra -Wframe-larger-than=1024 -g to get useful warnings and debug information.
Read the virtual address space wikipage. It has a nice picture worth many words. Later, find the way to query, on your operating system, the virtual address space of your process (on Linux, use proc(5) like cat /proc/$$/maps etc...). In practice, your virtual address space is likely to contain many segments (perhaps a dozen, sometimes thousands). Often, the dynamic linker or some other part of your program (or of your C standard library) uses memory-mapped files. The standard C heap (managed by malloc etc) may be organized in several segments.
If you want to understand more about virtual address space, take time to read a good book, like: Operating systems, three easy pieces (freely downloadable).
If you want to query the organization of the virtual address space in some process, you need to find an operating-system specific way to do that (on Linux, for a process of pid 1234, use /proc/1234/maps or /proc/self/maps from inside the process).
Memory is laid out much more differently than simply 4 segments(which was done long ago). The answer to the question can be generalized this way - the global or dynamically allocated memory space is handled differently than that of local variables by the system, where as the memory for local variable is limited in size, memory for dynamic allocation or global variables doesn't put a lower constraint like this.
In modern system the concept of virtual address space is there. The process from your program gets a chunk of it. That portion of memory is now responsible for holding the required memory.
Now for dynamic allocation and so on, the process can request more memory and depending on the other processes and so on, new memory request is serviced. For dynamic or global array there is no limit process wise (of course system wise there is- it cant haverequest all memory). That's why dynamic allocation or using global variable won't cause the process to run out of it's allocated memory unlike the automatic lifetime memory that it originally had for local variables.
Basically you can check your stack size
for example in Linux : ulimit -s (Kbytes)
and then decide how you manipulate your code regarding that.
As a concept I would never allocate big piece of memory on the stack because unless you know exactly the depth of your function call and the stack use, it's hard to control the precised allocated memory on stack during run time
I'm implementing a compiler which compiles a simulated processor's instruction set to code in x86 instructions. No physical processor exists which runs on the to be simulated instruction set; there is just the simulation on x86. When executing the compiled machine code (the simulation), I want to make sure that only memory designated for the simulation is read or written. This serves two purposes: 1) An access outside of the designated memory area could mean that I have a bug in my compiler. I want to find such bugs. 2) An access outside of the designated memory area can also mean that the source instructions that I compiled have a logical error and therefor try to access a memory address which does not exist in my simulation, thus an error should be raised.
In a simpler form, you can imagine my code to look like this:
void simulate(char* designated_memory, size_t len) {
// code intended to access *designated_memory till *(designated_memory + len - 1) only
}
Is there a way on x86-64 and/or in linux to enforce that simulate() can only access its own stack and designated_memory, and any other access would generate an error. E.g. the code could look like this:
restrict_access_to(designated_memory, designated_memory + len - 1);
simulate(designated_memory, len);
remove_access_restriction();
A solution in C would be nice; asm is fine, too.
UPDATE:
Following Jester's comments, I came to try out this:
#include <stdio.h>
#include <unistd.h>
#include <malloc.h>
#include <sys/mman.h>
int main() {
size_t pagesize = sysconf(_SC_PAGESIZE);
printf("pagesize...........: %lu\n", pagesize);
char* m;
size_t len = 12345;
len = (len + pagesize - 1) / pagesize * pagesize;
posix_memalign(&m, pagesize, len);
printf("page aligned memory: %lx - %lx\n", (unsigned long) m, (unsigned long) m + len);
printf("protecting 0 till m..."); fflush(stdout);
mprotect(0, (size_t) m, PROT_NONE);
printf("done\n");
printf("protecting (m + len) till ?..."); fflush(stdout);
mprotect(m + len, 0x7fffffff, PROT_NONE);
printf("done\n");
printf("trying to modify memory..."); fflush(stdout);
*(m - 1000) = 5;
printf("done: %i\n", *(m - 1000));
free(m);
}
Which outputs:
pagesize...........: 4096
page aligned memory: 9ac000 - 9b0000
protecting 0 till m...done
protecting (m + len) till ?...done
trying to modify memory...done: 5
Segmentation fault (core dumped)
I think that this shows that modifying data outside of the allowed area still works, but that should not happen.
i do not use an interpreter. i use a compiler to compile the simulated >instructions to x86 instructions. i do not want to include all the range checking >in the compilation to x86 instructions for performance reasons.
So your task is very similar to what does qemu, when it does emulation for example ARM on x86, it convert arm instructions to x86 instructions,
so I suggest you look at source code of qemu: http://wiki.qemu.org/Main_Page
The next very similar to your project is valrgrind,
the way how valgrind works is very similar to what you do:
it execute program on some kind of virtual cpu to check memory accesses,
and to speedup things it uses jit (http://valgrind.org/).
And the last opensource project, that solve similar problems to your is
https://github.com/google/sanitizers/tree/master/address-sanitizer
Yes, it is instrumented code, but the result works much faster then valgrind,
the idea how to instrument generated code, but leave performance on suitable level you can find in this video about asan internals:
https://www.youtube.com/watch?v=Q2C2lP8_tNE
If you are executing arbitrary assembly instructions in user-space code, there isn't really a way to enforce protection of the memory -- memory protection generally requires having the ability to activate kernel-mode flags on the CPU.
However, since you are writing a simulator, and compiling another language to a set of assembly instructions of your choosing, you have a different option: control the instructions being emmitted. Instead of emitting raw memory access instructions for simulated memory accesses, have the simulation compiler replace instructions which would access memory with instructions which call a memory-access function of your own design, and implement memory access protection in that function. This could also be done as Lorehead states by having the memory region be something like a std::vector.
Note that just replacing normal move instructions with your own move function isn't really sufficient to protect your own wrapper code from being hacked by "simulated" code. If your simulation emits raw jump commands, then it can be broken by simulated code which jumps outside of the simulation. Or by carefully planned push/pop instructions which cause the wrapper code to return to other simulator code later, after you should have left the simulation.
To actually be (somewhat) safe (this is by no means exhaustive, or guaranteed to be sufficient to make the simulated code safe), you would need to make sure that your simulation compiler generates safe code; things which affect what memory may be accessed, including mov, jump, push, pop, call, and ret would need to be replaced with function calls that perform equivalent actions safely, rather than just executing assembly code that you can't trust.
You would also need to make sure to wrap this in code which saves your registers for your outer program, since the inner code may arbitrarily change their contents.
You write that you don’t want to add runtime bounds checking for performance reasons. I suggest you look closely at the actual runtime cost and reconsider: it’s literally a single instruction if you use indirect addressing (ja) which even the simplest branch predictors can get right if you put the exception handler last. If you can recognize and optimize (some) loops, you can do one bounds check before the loop, instead of one before every access inside the loop.
If you really can’t afford this overhead, one option you can try is to compile the executable and fork off a process that has no other memory in its address space. If you’re going to run in a process that uses the stack, though, it’s theoretically possible that native code could clobber the stack. You can also make it impossible to access memory outside the address space if you make the size of the address space exactly 2^16 or 2^32 bytes and have the compiled code access it with that size register. Otherwise, you’re stuck trying to poison every single other page of the address space.
I found a C code that looks like this:
#include <stdio.h>
char code[] =
"\x31\xd2\xb2\x30\x64\x8b\x12\x8b\x52\x0c\x8b\x52\x1c\x8b\x42"
"\x08\x8b\x72\x20\x8b\x12\x80\x7e\x0c\x33\x75\xf2\x89\xc7\x03"
"\x78\x3c\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01\xc7\x31\xed\x8b"
"\x34\xaf\x01\xc6\x45\x81\x3e\x46\x61\x74\x61\x75\xf2\x81\x7e"
"\x08\x45\x78\x69\x74\x75\xe9\x8b\x7a\x24\x01\xc7\x66\x8b\x2c"
"\x6f\x8b\x7a\x1c\x01\xc7\x8b\x7c\xaf\xfc\x01\xc7\x68\x72\x6c"
"\x64\x01\x68\x6c\x6f\x57\x6f\x68\x20\x48\x65\x6c\x89\xe1\xfe"
"\x49\x0b\x31\xc0\x51\x50\xff\xd7";
int main(void)
{
int (*func)();
func = (int(*)()) code;
(int)(*func)();
return 0;
}
For the given HEX CODE this program runs well and printing ("HelloWorld"). I was thinking that the HEX CODE is some machine instructions and by calling a function pointer that's pointing to that CODE we are executing that CODE.
Was my thought right? is there something to improve it?
How this HEX CODE gets generated?
Tanks for advance.
You are correct that by forcing a function pointer like this you are calling into machine instructions written as a hexadecimal string variable.
I doubt that a program like this would work on any CPU since about 2005.
On most RISC CPUs (like ARM) and on all Intel and AMD CPUs that support 64-bit, memory pages have a No Execute bit. Or in reverse an Execute bit.
On memory pages that do not have an Execute bit, the CPU will not run code. Compilers do not put variables into executable memory pages.
In order to run injected shell codes, attackers now have to use "return into libc" or function pointer overwrite attacks which set things up to call mprotect or VirtualProtect to set the execute bit on their shell code. Either that or get it injected into a executable space such as the Java, .NET, or Javascript JIT compiler uses.
Security hardened kernels will deny the ability to call mprotect. Once the program's address space is set by the dynamic library loader, it sets a security flag and no new executable pages can be created.
In order to make it always work you could assign some executable_readwrite space with malloc or the like and put the code in there and then execute it. Then there won't be any access violation faults.
void main(int argc, char** argv)
{
void* PointerToNewMemoryRegion=0;
void (*FunctionPointer) ();
PointerToNewMemoryRegion=VirtualAlloc(RandomPointer,113,MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);
if (PointerToNewMemoryRegion == NULL)
{
std::cout<<"Failed to Allocate Memory region Error code: "<<GetLastError();
return;
}
memcpy(PointerToNewMemoryRegion, code,113);
FunctionPointer = (void(*)()) PointerToNewMemoryRegion;
(void)(*FunctionPointer) ();
VirtualFree(PointerToNewMemoryRegion,113,MEM_DECOMMIT)
}
but the code never returns to my code to execute so my last line is pointless. So my code has a memory leak.
To ask this question from a "general C" point of view isn't all that meaningful.
First of all, your code has many major problems:
The literal "\xFF\xFF\xFF" equals 0xFFFFFF00, not 0x00FFFFFF as may or may not have been the intention.
What this hex code means and if it is at all meaningful, is endian-dependent and also depends on the address bus width of the given CPU.
As others have mentioned, casts between function pointers and regular pointers isn't supported or well-defined by C, the C standard lists it as a "common extension".
That being said, code like this has about one single purpose, and that is various forms of boot loaders and self-updating software used in embedded systems.
Suppose for example that you have a boot loader program that is tasked with re-programming something in the very same segment of flash memory where said program itself is executed from. That is impossible because of the way the memory hardware works. So in order to do so, you would have to execute the actual flash programming routine from RAM. Since the array of hex gibberish is stored in RAM, the program can execute from there with the function pointer trick, assuming that the C compiler has a non-standard extension that allows the cast.
As for how to generate the code, you either write it all in assembler and then translate the assembler instructions to op codes manually (very tedious). Or more likely, you write the function in C and then disassemble it and copy/paste the op codes from the disassembly.
The latter is more dangerous though, as the critical part of getting code like this to work is calling convention: you must be absolutely sure that the function stacks/unstacks things properly when it is called and when it is done, restoring the contents of any CPU registers used etc. Which may force you to write part of the function in assembler anyhow. Needless to say, the code will be completely non-portable.
I'm a new C programmer, still learning the language itself.
Anyway -
I'm trying to access a specific memory address.
I've written this code:
#include <stdio.h>
int main()
{
int* p = (int*) 0x4e0f68;
*p = 12;
getchar();
}
When I try to access a specific memory address like that, the program crashes.
I don't know if this information is relevant, but I'm using Windows 7 and Linux Ubuntu.
(I've tried this code only on Windows 7).
Any explanations why the program crashes?
How can I access a specific memory address (an address which is known at compile-time, I don't mean to dynamic memory allocation)?
Thanks.
That's memory you don't own and accessing it is undefined behavior. Anything can happen, including crashing.
On most systems, you'd be able to inspect the memory (although technically still undefined behavior), but writing to it is a whole different story.
Strictly speaking you cannot create a valid pointer like this. Valid pointers must point to valid objects (either on your stack or obtained from malloc).
For most modern operating systems you have a virtual memory space that only your process can see. As you request more memory from the system (malloc, VirtualAlloc, mmap, etc) this virtual memory is mapped into real usable memory that you can safely read and write to. So you can't just take an arbitrary address and try to use it without OS cooperation.
An example for windows:
#include <windows.h>
#include <stdio.h>
int main(void)
{
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
unsigned pageSize = sysinfo.dwPageSize;
printf("page size: %d\n", pageSize);
void* target = (void*)0x4e0f68;
printf("trying to allocate exactly one page containing 0x%p...\n", target);
void* ptr = VirtualAlloc(target, pageSize, MEM_COMMIT, PAGE_READWRITE);
if (ptr)
printf("got: 0x%p\n", ptr); // ptr <= target < ptr+pageSize
else
printf("failed! OS wont let us use that address.\n");
return 0;
}
Note that this will give you different results on different runs. Try it more than once.
Just to clrify one phrase the OP wrote: strictly speaking, no address associated to a program (code or data) is known at compile time. Programs usually are loaded at whatever address the OS determines. The final address a program sees (for example, to read a global variable) is patched by the OS in the very program code, using some sort of relocation table. DLL functions called by a program have a similar mechanism, where the IDATA section of the executable is converted into a jump table to jump to the actual address of a function in a DLL, taking the actual addresses from the DLL in memory.
That said, it is indeed possible to know by advance where a variable will be placed, if the program is linked with no relocation information. This is possible in Windows, where you can tell the linker to load the program to an absolute virtual address. The OS loader will try to load your program to that address, if possible.
However, this feature is not recommended because it can lead to easily exploiting possible security holes. If an attacker discovers a security hole in a program and try to inject code into it, it will be easier for him if the program has all its variables and functions in specific addresses, so the malicious code will know where to make patches to gain control of that program.
What you're getting is a segfault - when you're trying to access memory you don't have permission to access. Pointers, at least for userspace, must point to some variable, object, function, etc. You can set a pointer to a variable with the & operator - int* somePtr = &variableToPointTo, or to another pointer - int* someNewPtr = somePtr. In kernel mode (ring 0) or for OS development, you can do that, BUT IT IS NOT ADVISED TO DO SO. In MS-DOS, you could destroy your machine because there was no protection against that.