I am just curious to know if I can read any value in memory by providing it's address (in my case random). I knew it won't work but I tried:
int e = 10;
int* p = &e;
p = 0x220202;
This won't even compile. So, is there a way to read something in my computer's memory in C++ or any other programming language.
So, is there a way to read something in my computers memory
If you refer to your computer's entire memory: No, you cannot - at least not on modern desktop/mainstream operating systems. You can only read memory from your process' address space.
Have a look at virtual memory. In a nutshell: Your pointers refer to "virtual" addresses, not real ones. Special hardware in your computer translates these addresses into real addresses. The operating system defines how the mapping has to be done. This way, each process has it's own unique address space. Whenever the OS's scheduler switches to another process, it tells the hardware to switch to the corresponding translation table. Thanks to this mechanism, you get isolation between processes, which is a very good thing: If a poorly programmed application accesses invalid memory, only the process in question will crash, whereas the rest of your system is not affected.
Think about it: Without this isolation, you would potentially need to restart your computer every time you're testing some pointer arithmetic..
You can read any value that operating system allocated to your process.
In case of your example you need to typecast an integer to a pointer before assigning it:
p = (int*) 0x220202; // now p points to address 0x220202
int value = *p; // read an integer at 0x220202 into 'value'
Note that not addresses will be accessible -- some areas are read-only, on some platforms the pointer must also be properly aligned (i.e. pointers to 32-bit integers should be aligned on 4-byte boundary).
You code will compile if you replace p = 0x220202 with p = (int *)0x220202. You will not be able to access ANY memory just by providing an address. You can access only the memory within the address space of this process. Meaning your OS will simply prevent you from accessing another exe's memory.
You must cast 0x220202 to int*
Write :
p = (int*)0x220202 ;
This will compile, but it will most likely crash when you run the program.
You will get a runtime error since this memory is outside the scope of your program
#include <iostream>
using namespace std;
int main() {
int * p = (int *) 0x220202;
int i = *p;
cout << i;
return 0;
}
Related
This is bit of a strange one...I've written a very short bit of code to allocate some memory for an integer, save a value to it and print out the memory address where it is saved:
#include <iostream>
using namespace std;
int main (void) {
int * b = new int;
*b = 12345;
cout << " -> *b = " << *b << endl;
cout << " -> b = " << b << endl;
return 0;
}
Lets say this returns the following:
-> *b = 123456
-> b = 0x7f9429c04bf0
So far as I know there is no reason why this value is not still chilling in memory as I didn't actively remove it - so, just for fun, I try and run the following:
#include <iostream>
using namespace std;
int main (void) {
int * b = reinterpret_cast <int*> (0x7f9429c04bf0);
cout << " -> *b = " << *b << endl;
cout << " -> b = " << b << endl;
return 0;
}
which throws a segfault - does anyone know why this isn't allowed? I mean...it clearly isn't a good idea and I have no plans to use it in practise but I am curious.
Cheers!
Jack
Each process has its own virtual memory space separate from other processes. When the process terminates, its memory is reclaimed by the operating system.
The reason it's throwing a segfault is because the OS is unhappy with your program trying to access memory that does not belong to it.
The whole idea behind having protected memory is to isolate processes so that they can't mess with each other's memory and cause nastiness to happen. And even if you could access random memory locations, you wouldn't really find anything interesting there. It's basically the same kind of stuff you get when accessing an uninitialized pointer.
Each Process runs in its own address space, the address ur passing to reinterpret_cast should be accessible in the address space of the current process, which it isn't as the second process has a different address space layout. Also, each iteration of even the first program will give u different addresses, which is the whole point of ASLR(Address Space Layout Randomization), that is, to randomize key parts of the process memory on each new instance. Having static addresses, as used to be the case pre-ASLR, would cause havoc, leading to easy exploitation of vulnerable programs.
Read More about ASLR: http://en.wikipedia.org/wiki/Address_space_layout_randomization
Virtual Memory:
http://en.wikipedia.org/wiki/Virtual_memory
Even if you ran both programs at once I would hope you got kicked for that, in stead of getting the right answer. The implication that you think I should be able to access another programs data by guessing addresses is scary, although if you want some history, there used to be a game called "core wars" which involved doing exactly that to try to make each other crash ...
I suppose the real answer is that this has "undefined behaviour" and you should be grateful it didn't just implode.
Most modern C++ platforms work with virtual memory provided by the underlying OS. Virtual memory is not a trivial physical form of storage you seem to believe it is. Virtual memory is just an imaginary conceptual storage that exists only as long as the process runs. It simulates "memory-like" behavior every time you access your process address space.
Your access to 0x7f9429c04bf0 is not access to physical memory address, it is access to the process virtual address space, which will be redirected to some physical location that you cannot predict.
And when your process ends, its virtual memory disappears forever. It was simulated anyway, fake in a sense. When you start another process, it gets its own virtual memory that has no connection to the old one whatsoever. In that new process access to 0x7f9429c04bf0 will lead to some other physical location you cannot predict (or, as in your case, crash, if 0x7f9429c04bf0 is not even valid).
To expect that your value is "still chilling in memory" would be rather naive. In fact, your value has never really been in any "memory" suitable for any kind of "chilling".
I have made following code in main()
int (*Addition)(int x, int y) = FuncAdd;
cout<<endl<<"Address of Addition is: "<<Addition<<endl;
Now every-time I execute it. I get values like this:
Address of Addition is: 01161450
Address of Addition is: 001B1450
Address of Addition is: 00F91450
and so on..
As we can see, address is different every time, though there is lower word (1450-H) common among all of them. So whats the reason behind it?
The address of the function was defined by the compiler and linker relative to the start of the program space. However the OS is free to load the program starting anywhere it desires, and due to Address Space Layout Randomization it will change with every run. It appears your OS uses a starting address that is a multiple of 0x10000.
The OS divides the memory into several partitions. If every partition starts from xxxx0000 H,
it appears that your FuncAdd() segment is allocated after 1450 H memory positions. It may vary due to change in length of other functions and other declarations, because the segments allocated previously determine the starting segment address of FuncAdd().
The reason is, the OS is allocating your program a different memory location from a flat memory model. So, FuncAdd()'s address can change each time. The previously allocated space will eventually be reclaimed/reused by the loader. If you try this in an OS such as Linux/Unix where memory model is virtual, you should always get a same value for FuncAdd()
I also added another function FuncAdd2() for illustration.
try this on a linux:
int FuncAdd (int x, int y){ return 0;}
int FuncAdd2 (int x, int y){return 0;}
typedef int (*fp)(int, int);
fp Addition[2];
int main()
{
Addition[0] = FuncAdd;
Addition[1] = FuncAdd2;
printf("\nAddress of *addition is %X " , Addition[0] );
printf("\nAddress of *addition1 is %X\n ", Addition[1]);
}
You will get this SAME (in Linux like OS)
Address of *addition is 80483E4 << This is a relative address to the proc and remains same
Address of *addition1 is 80483EE <
I am working with the debug information. I am trying to write kind of like a "debug information parser", I am using DWARF and ELF libraries to do this, but they do not offer anything besides information of the memory space, I am trying to get the data in that memory space. I am hooked to the program. I am using a tool called Pin, so I am actually running the code inside the other program.. That is why I have access to its variables.
Assuming I have a pointer to an address, I want to get all the data that is stored in that address and the next 4 bytes (for example).
As an example, let's say I have an address 0xDEADBEEF and I want to go through the next 4 bytes starting from that address and read the data (dereference the pointer on each byte)
I am relatively new to C, and what I am attempting to do is:
char * address = "0xDEADBEEF";
unsigned int bytesize = 4;
ptr = (void *) address;
ptr_limit = ptr + bytesize;
for(ptr; ptr < ptr_limit; ptr++)
cout << ptr;
I know this might be completely wrong, and I am getting a lot of compiling errors, but it is just to show a bit of the logic I am trying to use...
OK, C and C++ are low level, but they aren't the wild west. You aren't allowed to just make up an address and access it. You aren't allowed to do that in assembly on most OSs; this is where SegFaults come from.
The way you get memory is to allocate it. This process involves telling the OS that you want a piece of memory of some size. At which point, the OS does its stuff so that you can access a certain range of virtual memory. Attempts to access memory outside of this range (or any range that the OS has allowed you to access) will cause the OS to terminate your program.
In C, you generally use malloc/calloc/realloc to allocate memory and free to tell the OS that you're done with it. C++ uses new to allocate objects and delete to deallocate them.
I am trying to write kind of like a "debug information parser", I am using DWARF and ELF libraries to do this, but they do not offer anything besides information of the memory space, I am trying to get the data in that memory space
It'd be great if you put things like that in your question.
In any case, you're talking about accessing someone else's memory, which is not done. Well, it's not permitted by the rules of standard C and C++. The various OSs have calls that can allow you to map some address space of another processes onto yours. But that's much more complex and OS-specific.
A memory address is an integer type (read number).
In your example, you have a char * (read string).
The following code:
char * address = "0xDEADBEEF";
void * ptr = ( void * )address;
will just put the address of that char * variable, as a void *, into p.
It won't set the pointer to memory address 0xDEADBEEF.
If you want to access that specific memory location (assuming you know what you are doing), you'll need something like:
void * ptr = ( void * )0xDEADBEEF;
I said "assuming you know what you are doing", because accessing such a specific address will eventually result in a segfault, since you basically don't know such an address is in your address space, unless you're doing stuff in ring 0 (read kernel), for instance, with DMA.
But then I would assume you know a pointer is a number, not a string...
The code can be pretty simple:
char *address, *limit;
for(address = (char *)0xdeadbeef, limit = address+4; address < limit; address++)
cout << *address;
Note, however, that while converting an arbitrary integer to an address is allowed, the result of using the resulting pointer isn't (even close to) portable. Based on your comment (that you're getting addresses via debug information) so the addresses you're getting should be valid, the result should normally work (there's just no guarantee of it being portable).
store your address as DWORD => DWORD address = 0xDEADBEEF
then cast this address to pointer => void *ptr = (void *)address
here is a example:
char *pointer = "FOO";
DWORD address = (DWORD)pointer;
printf("0x%u\n", address);
printf("%s\n", (char *)address); // prints FOO
address++; //move 1 byte
printf("%s\n", (char *)address); // prints OO
I am coding in C/C++. What are the possible ways to corrupt a static variable that is stored in the data segment? Is this considered a memory leak?
#include <stdio.h>
int aaa[5];
int bbb;
int main()
{
int i;
bbb=41;
for (i = 0; i < 6; ++i)
aaa[i] = 42;
printf("%d\n", bbb);
return 0;
}
the code above prints bbb=42 and not 41. this is a possible cause. another way is to modify
static data accessed via multiple threads.
Any other ways?
No, this is not a memory leak. A memory leak is when you allocate on the free store (with malloc/new) and then never free/delete the allocated block.
Note that this is undefined behaviour and is not guaranteed:
int bbb;
int aaa[5];
int main()
{
int i;
bbb=41;
for (i = 0; i < 6; ++i)
aaa[i] = 42;
printf("%d\n", bbb);
return 0;
}
g++ -o test test.cpp && ./test
41
In this particular case bbb is stored after aaa, but you shouldn't be relying on this at all cause it could be somewhere else.
Yes, there is more than one method to destroy the contents of global variables (your variables are not static in the example you posted).
Pointers are a good tool to corrupt memory and write where your program should not. Casting can also add some excitement:
#include <iostream>
using namespace std;
int aaa[5];
int bbb;
int main(void) // Do *your* main() functions always return a value????
{
double * ptr_double = 0;
// Assign the pointer to double to point to the last integer.
// Treat the last integer in the array as a double.
aaa[4] = 45;
cout << "aaa[4] = " << aaa[4] << endl;
ptr_double = (double *)(&aaa[4]);
*ptr_double = 3.14159267;
cout << "aaa[4] = " << aaa[4] << endl;
return -1;
}
With multiple threads, you can have each thread write to the global variable, then have them read back the value. Placing random delays, before writing, and after writing, can show you in more detail how it works.
Another method is to assign the address of your variable to destination register of an I/O hardware device, like a UART. When the UART receives data, it will place that data in that variable, with no regards to the purpose of the variable.
In general values are corrupted by code writing to a location it should not. The primary cause is buffer overrun: Writing more data than is allocated for the variable. Overruns can also occur from hardware devices such as DMA controllers and USB controllers. Another cause is via pointers: the pointer is pointing to an invalid location.
Variables can become corrupted by Stack Overflows and Heap Overflows. On many architectures these structures expand towards each other. Too many variables on the stack, or function recursions (or calling depth) can make the stack overwrite into the heap. Likewise, allocating too much memory from the heap can make the heap overwrite the stack.
Rather than exploring how to damage variables, I believe you should work on improving code safety: design and write your code so it has no buffer overruns, writes to correct locations and shared variables are protected from simultaneous writes by multiple tasks and threads.
All global variables, static or otherwise are initialized to the value specified in their declaration (or zero if not specified) by the loader prior to the execution of any code in the process. The default values will only be modified by code executed within the process (barring any outside interferrence from a debugger).
If you're seeing a "corrupted" value at the beginning of your program's main() function, it's most likely due to a bad action preformed from within the constructor of a global C++ object. The constructors for all global C++ objects are run prior to the invocation of main().
The easiest way to track down the source of this kind of corruption is probably to run the process under a debugger and set a watchpoint on the address of the global variable. The debugger will break when the data is modified. Odds are you have an array overrun or errant pointer problem. They can be a bitch to track down manually.
This is a typical programming error.
You define 5 items of an array of aaa while using 6 aaa's, which means you can only use aaa[0], aaa[1], aaa[2], aaa[3], and aaa[4]. aaa[5] is undefined.
This is a bug, a programming error, and nothing else. Period.
Recently I've time off of school for a few days and wanted to do a small program(s) experiment in C++ dealing with memory address.
I wanted to see is that if a currently running program (Let call it Program A) that created a pointer to an int object in the heap, can be seen by another program and be modified (Program B).
So for Program A, this is my basic code:
// Program A
#include <iostream>
using namespace std;
int main()
{
// Pointer to an int object in the heap
int *pint = new int(15);
// Display the address of the memory in heap
cout << pint << endl;
// Display the value stored in that address
cout << *pint << endl;
return 0;
}
Output for Program A:
0x641030
15
For Program B, I looked at how to assigned a specific memory address through this link:
http://www.devx.com/tips/Tip/14104
The code for Program B is:
// Program B
#include <iostream>
using namespace std;
int main()
{
// assign address 0x641030 to p
int *p = reinterpret_cast< int* > (0x641030);
cout << p << endl;
cout << *p << endl;
return 0;
}
Output for Program B:
0x641030
... "Crash"
I don't quite understand it. I was expecting a display of 15 from *p, but it did something i didn't expect.
I also tried to assign *p to a number like *p = 2000 but it crashed when I attempted that as well.
Also when I display the address of the pointers and Program A (cout << &pint;) and for Program B (cout << &p;), they both showed the same memory address.
Does anyone know what is going on exactly? I'm interested yet confused of what is happening. Also, is it possible for me to do what I am attempt in C++/C ?
** EDIT **
Sorry to not mention my platform, but I am currently using Window 7 Professional
The short answer is that different processes use completely different address spaces. Without doing a lot more work, process B can't read or write the memory from process A.
It is possible to do this, in a platform-specific way. Win32 offers functions such as WriteProcessMemory where you can directly poke values into the memory space of another process. Most operating systems offer a shared memory function, with Win32 you can use memory mapped files and Unix flavours typically have some kind of equivalent "mmap" or "shmem" feature.
I think that most operating systems are designed to make it impossible (or very difficult) to do what you are trying to do -- have one running program (or process) interfere with the contents of the address space of another running program (or process). Since you don't tell us your platform it's difficult to be categorical about this, but I suspect that the o/s is saving you from yourself. This rigid separation of processes is a safety feature on single-user machines, a safety and security feature on multi-user machines.
There are, of course, many techniques for running concurrent processes which can share memory or which exchange information by message-passing. Take some more time off school and study those!
Take a look at either Memory Mapped Files or Shared Memory.
http://msdn.microsoft.com/en-us/library/aa366551(VS.85).aspx