How to get a specific memory address using C

For my bachelor's thesis, I want to visualize the residual data memory and how it is saved after a system reboot.

I had a simple idea: moisten the picture in memory, turn off the computer, wait x seconds, boot the computer and see if the image is still there.

  int mmap_lena (void)
 {
     FILE * fd = NULL;
     size_t lena_size;
     void * addr = NULL;

     fd = fopen ("lena.png", "r");

     fseek (fd, 0, SEEK_END);
     lena_size = ftell (fd);

     addr = mmap ((void *) 0x12345678, (size_t) lena_size, (int) PROT_READ, (int) MAP_SHARED, (int) fileno (fd), (off_t) 0);
     fprintf (stdout, "Addr =% p \ n", addr);
     munmap ((void *) addr, (size_t) lena_size);
     fclose (fd);
     fclose (fd_log);
     return EXIT_SUCCESS;
 }

I skipped checking the return values ​​for clarity.

So, after mmap, I tried to somehow get the address, but I usually end up with a segmentation error, since I understand that the memory is protected by my operating system.

  int fetch_lena (void)
 {
     FILE * fd = NULL;
     FILE * fd_out = NULL;
     size_t lenna_size;
     FILE * addr = (FILE *) 0x12346000;

     fd = fopen ("lena.png", "r");
     fd_out = fopen ("lena_out.png", "rw");

     fseek (fd, 0, SEEK_END);
     lenna_size = ftell (fd);

     // Segfault 
     fwrite ((FILE *) addr, (size_t) 1, (size_t) lenna_size, (FILE *) fd_out);

     fclose (fd);
     fclose (fd_out);

     return 0;

 }

Also note that I hardcoded the addresses in this example, so whenever you run mmap_lena, the value I use in fetch_lena may be wrong, since the operating system only accepts the first parameter in mmap as a hint (on my system, this always defaults to 0x12346000).

If there is any trivial coding error, I regret that my C skills were not fully developed.

I would like now if there is any way to access the data I want without implementing any malloc interceptors or memory hackers.

Thanks in advance, David

+6
c memory-management linux memory
source share
6 answers

One of the problems is that you are returning the virtual address, not the physical address where the memory is located. The next time you boot, the display is likely to be different.

This can be done as part of the kernel module in Linux, but I don’t think you can use any kind of API in user space.

If you have permission (and I assume that you can be root on this computer if you reboot it), you can look in / dev / mem to see the actual phyiscal layout. Perhaps you should try sampling the values, rebooting, and see how many of these values ​​have been preserved.

+18
source share

There is a similar project where an attack with a cold boot is demonstrated. source code is available, maybe you can get some inspiration there.

However, AFAIR they read memory without loading the OS in the first place and, therefore, should not be associated with OS memory protection. You might want to try this to avoid rebooting or clearing the OS memory after loading.

(Also check out the video on the site, this is pretty impressive;)

+10
source share

In the Linux Direct Memory Access issue, we have developed most of the basics necessary to achieve this. Note that mmap () is not an answer to this for reasons that others have claimed. You need a real address, not a virtual one, which you can only get inside the kernel (or by writing a driver to transfer one to user space).

The easiest way is to write a character device driver that you can read or write using ioctl to give you a valid start or end address. Again, if you want pointers to memory management functions to be used in the kernel, see the Question I'm Related to. Most of them were developed in the comments in the first (and accepted) answer.

+4
source share

Your test code looks odd

FILE * addr = (FILE *) 0x12346000;
fwrite ((FILE *) fd_out, (size_t) 1, (size_t) lenna_size, (FILE *) addr);

You cannot just distinguish an integer with a FILE pointer and expect to get something sane. Have you also switched the first and last arguments to fwrite? The final argument must be FILE * for the record.

+2
source share

You will probably need as little OS as possible for this purpose; the more software is downloaded, the more likely it is to rewrite what you want to learn.

DOS may be a good bet; he uses <640 thousand. Memory. If you do not load HIMEM and instead write your own (necessary assembly) procedure for switching to pmode, copy the block with high memory to low memory, and then return to real mode, you can write a program in main real mode, it can unload physical RAM (minus, however, the use of BIOS, DOS and your application). He can flush it to a flash drive or something like that.

Of course, the real problem may be that the BIOS clears the memory during POST.

+2
source share

I am not familiar with Linux, but you will most likely have to write a device driver. Device drivers must have some way of converting virtual memory addresses to physical memory addresses for DMA purposes (DMA controllers deal only with physical memory addresses). You should be able to use these interfaces to interact directly with physical memory.

+1
source share

All Articles