1

This is my code that works only on Xcode (version 4.5):

#include <stdio.h>
#include <mach/mach_init.h>
#include <mach/mach_vm.h>
#include <sys/types.h>
#include <mach/mach.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <Security/Authorization.h>

int main(int argc, const char * argv[]) {

    char test[14]   = "Hello World! "; //0x7fff5fbff82a

    char value[14]  = "Hello Hacker!";

    char test1[14];

    pointer_t buf;
    uint32_t sz;

    task_t task;

    task_for_pid(current_task(), getpid(), &task);

    if (vm_write(current_task(), 0x7fff5fbff82a, (pointer_t)value, 14) == KERN_SUCCESS) {

        printf("%s\n", test);
        //getchar();
    }

    if (vm_read(task, 0x7fff5fbff82a, sizeof(char) * 14, &buf, &sz) == KERN_SUCCESS) {

        memcpy(test1, (const void *)buf, sz);
        printf("%s", test1);
    }

    return 0;
}

I was trying also ptrace and other things, this is why I include other libraries too.

The first problem is that this works only on Xcode, I can find with the debugger the position (memory address) of a variable (in this case of test), so I change the string with the one on value and then I copy the new value on test on test1.

I actually don't understand how vm_write works (not completely) and the same for task_for_pid(), the 2° problem is that I need to read and write on another process, this is only a test for see if the functions works on the same process, and it works (only on Xcode).

How I can do that on other processes? I need to read a position (how I can find the address of "something"?), this is the first goal.

ymn
  • 2,175
  • 2
  • 21
  • 39
genesisxyz
  • 778
  • 3
  • 14
  • 29

2 Answers2

5

For your problems, there are solutions:

  • The first problem: OS X has address space layout randomization. If you want to make your memory images fixed and predictable, you have to compile your code with NOPIE setting. This setting (PIE = Position Independent Executable), is responsible for allowing ASLR, which "slides" the memory by some random value, which changes on every instance.

  • I actually don't understand how vm_write works (not completely) and the same for task_for_pid():

    The Mach APIs operate on the lower level abstractions of "task" and "Thread" which correspond roughly to that of the BSD "process" and "(u)thread" (there are some exceptions, e.g. kernel_task, which does not have a PID, but let's ignore that for now). task_for_pid obtains the task port (think of it as a "handle"), and if you get the port - you are free to do whatever you wish. Basically, the vm_* functions operate on any task port - you can use it on your own process (mach_task_self(), that is), or a port obtained from task_for_pid.

    Task for PID actually doesn't necessarily require root (i.e. "sudo"). It requires getting past taskgated on OSX, which traditionally verified membership in procmod or procview groups. You can configure taskgated ( /System/Library/LaunchDaemons/com.apple.taskgated.plist) for debugging purposes. Ultimately, btw, getting the task port will require an entitlement (the same as it now does on iOS). That said, the easiest way, rather than mucking around with system authorizations, etc, is to simply become root.

Technologeeks
  • 7,674
  • 25
  • 36
0

Did you try to run your app with "sudo"? You can't read/write other app's memory without sudo.

silvansky
  • 2,426
  • 2
  • 19
  • 20