Accessing RAM directly

Discussion in 'iPhone/iPad Programming' started by xArtx, Aug 19, 2012.

  1. macrumors 6502a

    Joined:
    Mar 30, 2012
    #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?
     
  2. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    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.
     
  3. macrumors 68000

    Reason077

    Joined:
    Aug 14, 2007
    #3
    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!
     
  4. macrumors 603

    Joined:
    Jul 29, 2003
    Location:
    Silicon Valley
    #4
    Read up on virtual memory systems and TLBs. All the addresses get changed before using them to access physical RAM locations.
     
  5. macrumors Pentium

    KnightWRX

    Joined:
    Jan 28, 2009
    Location:
    Quebec, Canada
    #5
    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.
     
  6. macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #6
    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.
     
  7. thread starter macrumors 6502a

    Joined:
    Mar 30, 2012
    #7
    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.
     
  8. macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #8
    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.
     
  9. macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #9
    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.
     
  10. thread starter macrumors 6502a

    Joined:
    Mar 30, 2012
    #10
    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.
     
  11. macrumors 603

    Joined:
    Jul 29, 2003
    Location:
    Silicon Valley
    #11
    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.
     
  12. macrumors 603

    Joined:
    Aug 9, 2009
    #12
    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.
     
  13. macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #13


    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.
     
  14. thread starter macrumors 6502a

    Joined:
    Mar 30, 2012
    #14
    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.
     
  15. macrumors 603

    Joined:
    Jul 29, 2003
    Location:
    Silicon Valley
    #15
    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.
     
  16. thread starter macrumors 6502a

    Joined:
    Mar 30, 2012
    #16
    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.
     

Share This Page