PDA

View Full Version : Accessing RAM directly




xArtx
Aug 19, 2012, 08:05 AM
Hi Guys,
The desire to alter RAM directly arose from the need to cheat in a commercial game Action Replay style :D

I have printed some content to screen in ASCII by declaring a C char
array, and accessing elements outside of it.
By incrementing or decrementing the array index variable I think I am
seeing the RAM space the program is running in.
A lot of it is Human readable.
I can't recognise words relating to any program running in the background
(ie. the aforementioned commercial game).
The program that reads the RAM crashes after a while looking in each direction
of whatever memory vector where the C array was declared (bad access)

Any thoughts? Is this part of the program sandboxing?



robbieduncan
Aug 19, 2012, 08:23 AM
You are not seeing the current values of another program (or it's code). When your application starts it is allocated a certain sized slice of RAM. This is will be larger than the amount of RAM you really need right now. This RAM will almost certainly have been used by another program before you. The OS does not bother zeroing out RAM before giving it to you. So if you do not zero it out you will see old values form another program. You will crash as soon as you try and access memory outside of that allocated to you.

Reason077
Aug 19, 2012, 10:42 AM
This RAM will almost certainly have been used by another program before you. The OS does not bother zeroing out RAM before giving it to you. So if you do not zero it out you will see old values form another program.

Err, no.

iOS, like most other modern OS's, is a protected virtual memory system. Each application's address space is completely isolated from those of other applications. If your app could see old "values from another program" then that would be a serious security hole!

firewood
Aug 19, 2012, 10:51 AM
Read up on virtual memory systems and TLBs. All the addresses get changed before using them to access physical RAM locations.

KnightWRX
Aug 19, 2012, 11:43 AM
The OS does not bother zeroing out RAM before giving it to you.

False. The OS does zero pages out on first allocation. It actually allocates a new page for you based on the zero page. The virtual memory management then makes the page available in system memory by copying its contents to system memory the first time you access it (read/write/execute).

That means the page will definately be zeroes the first time you malloc it. However, free'ing memory inside your own virtual process space and allocating it again might not result in getting zero'ed out pages. It's highly OS/libc dependent. Take the following code :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char ** argv)
{
char * a;
int i = -1;
do
{
a = malloc(sizeof(char) * 51);
a[50] = '\0';
printf("a string: %s\na pointer: %p\n", a, a);
memset(a, 'b', 50);
printf("a string: %s\na pointer: %p\n", a, a);
free(a);
i++;
} while (!i);
return EXIT_SUCCESS;
}


On Linux with glibc, you get the following result :

$ ./test
a string:
a pointer: 0x8ea9008
a string: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
a pointer: 0x8ea9008
a string:
a pointer: 0x8ea9008
a string: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
a pointer: 0x8ea9008


free() or malloc() definately have zero'ed out the pages here. On OS X however :

$ ./test
a string:
a pointer: 0x7fc9c9403980
a string: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
a pointer: 0x7fc9c9403980
a string: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
a pointer: 0x7fc9c9403980
a string: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
a pointer: 0x7fc9c9403980


But this is simply your own pages you're reusing, there is no way to read/write/execute from system memory in a page that was used by another process at an earlier time.

Duncan C
Aug 19, 2012, 01:08 PM
Hi Guys,
The desire to alter RAM directly arose from the need to cheat in a commercial game Action Replay style :D

I have printed some content to screen in ASCII by declaring a C char
array, and accessing elements outside of it.
By incrementing or decrementing the array index variable I think I am
seeing the RAM space the program is running in.
A lot of it is Human readable.
I can't recognise words relating to any program running in the background
(ie. the aforementioned commercial game).
The program that reads the RAM crashes after a while looking in each direction
of whatever memory vector where the C array was declared (bad access)

Any thoughts? Is this part of the program sandboxing?

Unless you have a jailbroken phone, and run your app in Kernel mode, you can't access memory outside of your application. iOS is based on UNIX, which is a protected virtual operating system. Each application gets a memory space assigned to it by the OS, and can only read/write to that memory space. Any attempt to read/write an address outside your address space will result in a bad access crash.

xArtx
Feb 20, 2013, 08:52 AM
Old thread, but you could access your own RAM this way right?
So for example, loading one wav file, and then changing it's contents by
searching for the header, maintaining it, but altering the pcm data?
Or more simply, looking for the string in a UIlabel,
and replacing it with a string of the same length?

I don't know if this passes Analyse, or Validation for App Store,
for writing an array out of bounds, but I ran it on my iPhone 4
(an ASCII RAM reader).

The gain for me, is it might be a better/quicker way to deal with a bitmap image.

PhoneyDeveloper
Feb 20, 2013, 05:15 PM
Your code shouldn't read or write outside blocks of memory that it allocated (by malloc or other APIs). Reading and writing bytes, ints, whatever inside these blocks of memory should work fine, for bitmaps for example.

Be aware that errors in pointer arithmetic are a very common cause of bugs and you should stay away from it if you can.

Duncan C
Feb 20, 2013, 07:00 PM
Old thread, but you could access your own RAM this way right?
So for example, loading one wav file, and then changing it's contents by
searching for the header, maintaining it, but altering the pcm data?
Or more simply, looking for the string in a UIlabel,
and replacing it with a string of the same length?

I don't know if this passes Analyse, or Validation for App Store,
for writing an array out of bounds, but I ran it on my iPhone 4
(an ASCII RAM reader).

The gain for me, is it might be a better/quicker way to deal with a bitmap image.

Sure, you can load a file as raw bytes, modify it, and write it back. That's not the same thing as the other poster was talking about, which is deliberately overstepping the bounds of a pointer to try to access other parts of your program. That's a really bad idea.

xArtx
Feb 20, 2013, 07:16 PM
Sure, you can load a file as raw bytes, modify it, and write it back. That's not the same thing as the other poster was talking about, which is deliberately overstepping the bounds of a pointer to try to access other parts of your program. That's a really bad idea.

My original post was about "overstepping the bounds", but different ideas since then ;)

One App I have working writes to a bitmap image and displays it for every frame:


// make changes to the bitmap array data here

myData = [NSData dataWithBytes:(const void *)imgfile length:sizeof(char)*imgfilelength];
myImage = [UIImage imageWithData: myData];


This should be able to be reduced to:


// make changes to the bitmap data where it actually exists in memory


But so far, I've only read outside of array bounds to access RAM.
Writing to the array out of bounds might not even get past the compiler.

firewood
Feb 21, 2013, 02:15 PM
Most of the data for an image is in the GPUs memory, which is in a completely different address space, not accessible from your app. Every pointer in your app is re-mapped by the OS and CPU TLB to point to a small limited sandbox of real memory.

chown33
Feb 21, 2013, 06:31 PM
One App I have working writes to a bitmap image and displays it for every frame:


// make changes to the bitmap array data here

myData = [NSData dataWithBytes:(const void *)imgfile length:sizeof(char)*imgfilelength];
myImage = [UIImage imageWithData: myData];


This should be able to be reduced to:


// make changes to the bitmap data where it actually exists in memory


But so far, I've only read outside of array bounds to access RAM.
Writing to the array out of bounds might not even get past the compiler.

What format is the image data? Exactly what type is the "bitmap image"? When you say "writes a bitmap image", do you mean it writes a file, or makes an NSData? In short, what is the complete image production path, with all the intervening types and data formats?

The data format is important, because some formats aren't easily or quickly writable. For example, JPEG. PNG isn't necessarily quick, either, but it's probably better than JPEG. Still, both of those are formats for external use, i.e. for files intended for storage or interchange. Neither one is an efficient in-memory bitmap representation.

In general, the way to get fast images on iOS is to use a CGImageRef; don't even bother with UIImages. If you're fiddling with bitmaps by breaking into the UIImage encapsulation, then you probably haven't looked at CGImage yet.

Duncan C
Feb 21, 2013, 06:55 PM
What format is the image data? Exactly what type is the "bitmap image"? When you say "writes a bitmap image", do you mean it writes a file, or makes an NSData? In short, what is the complete image production path, with all the intervening types and data formats?

The data format is important, because some formats aren't easily or quickly writable. For example, JPEG. PNG isn't necessarily quick, either, but it's probably better than JPEG. Still, both of those are formats for external use, i.e. for files intended for storage or interchange. Neither one is an efficient in-memory bitmap representation.

In general, the way to get fast images on iOS is to use a CGImageRef; don't even bother with UIImages. If you're fiddling with bitmaps by breaking into the UIImage encapsulation, then you probably haven't looked at CGImage yet.



I agree with everything you say, but if you want fast image manipulation, the best way to do it is in OpenGL, not Core Graphics at all. The underlying graphics hardware uses OpenGL, so you can work directly with the rendering engine.

Sadly, there's no OpenCL exposed in iOS, so you're left using shader language, but it's possible to manipulate images and render them to the screen at 30 FPS - something that's not possible with CPU-based rendering.

xArtx
Feb 21, 2013, 07:35 PM
Windows bitmap that exists in a c array with the header intact
so it can be emailed out.
I'm modifying the c array, then using the code above to display it.

firewood
Feb 22, 2013, 01:16 PM
Creating an image (or uploading a 2D texture) is the only way to get a modified bitmap into the GPU and from there to the display.

From an iOS app's point of view, you might as well assume the GPU and its memory are on on another separate system or device. No way to access that image memory directly. It's also in an opaque and device/OS dependent internal GPU format.

xArtx
Feb 22, 2013, 05:43 PM
Guess I have to stick to what I'm doing then.
I haven't bothered trying reading what's in RAM where a program
has images, etc. in it because it's not the current project.