Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

xArtx

macrumors 6502a
Original poster
Mar 30, 2012
764
1
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

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
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

macrumors 68040
Aug 14, 2007
3,605
3,643
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!
 

KnightWRX

macrumors Pentium
Jan 28, 2009
15,046
4
Quebec, Canada
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 :

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 :

Code:
$ ./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 :

Code:
$ ./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

macrumors 6502a
Jan 21, 2008
853
0
Northern Virginia
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

macrumors 6502a
Original poster
Mar 30, 2012
764
1
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

macrumors 68040
Sep 2, 2008
3,114
93
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

macrumors 6502a
Jan 21, 2008
853
0
Northern Virginia
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

macrumors 6502a
Original poster
Mar 30, 2012
764
1
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:

Code:
 // 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:

Code:
 // 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

macrumors G3
Jul 29, 2003
8,107
1,345
Silicon Valley
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

Moderator
Staff member
Aug 9, 2009
10,740
8,416
A sea of green
One App I have working writes to a bitmap image and displays it for every frame:

Code:
 // 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:

Code:
 // 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

macrumors 6502a
Jan 21, 2008
853
0
Northern Virginia
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

macrumors 6502a
Original poster
Mar 30, 2012
764
1
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

macrumors G3
Jul 29, 2003
8,107
1,345
Silicon Valley
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

macrumors 6502a
Original poster
Mar 30, 2012
764
1
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.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.