9

task_for_pid/を使用してプロセスのメモリを読み取ろうとしていますvm_read

uint32_t sz;
pointer_t buf;
task_t task;
pid_t pid = 9484;
kern_return_t error = task_for_pid(current_task(), pid, &task);
vm_read(task, 0x10e448000, 2048, &buf, &sz);

この場合、最初の 2048 バイトを読み取ります。

これは、プロセスのベースアドレスがわかっている場合に機能します(gdb「info shared」を使用して見つけることができます-この場合0x10e448000)が、実行時にベースアドレスを見つける方法(gdbで見ずに)?

4

2 に答える 2

8

私自身の質問に答えます。以下のようにベースアドレスを取得することができましたmach_vm_region_recurse。オフセットはに着陸しvmoffsetます。より「正しい」別の方法がある場合は、遠慮なくコメントしてください。

#include <stdio.h>
#include <mach/mach_init.h>
#include <sys/sysctl.h>
#include <mach/mach_vm.h>

 ...

    mach_port_name_t task;
    vm_map_offset_t vmoffset;
    vm_map_size_t vmsize;
    uint32_t nesting_depth = 0;
    struct vm_region_submap_info_64 vbr;
    mach_msg_type_number_t vbrcount = 16;
    kern_return_t kr;

    if ((kr = mach_vm_region_recurse(task, &vmoffset, &vmsize,
                 &nesting_depth,
                 (vm_region_recurse_info_t)&vbr,
                 &vbrcount)) != KERN_SUCCESS) 
    {
        printf("FAIL");
    }
于 2012-04-24T19:30:53.260 に答える
5

current_task() を呼び出しているので、実行時に独自のプロセスを目指していると思います。つまり、あなたが言及したベース アドレスは動的ベース アドレス、つまり静的ベース アドレス + ASLR による画像スライドである必要がありますね。この仮定に基づいて、「セクションおよびセグメント アクセサー」を使用してプロセスの静的ベース アドレスを取得し、dyld 関数を使用して画像スライドを取得できます。ここにスニペットがあります:

#import <Foundation/Foundation.h>
#include </usr/include/mach-o/getsect.h>
#include <stdio.h>
#include </usr/include/mach-o/dyld.h>
#include <string.h>

uint64_t StaticBaseAddress(void)
{
    const struct segment_command_64* command = getsegbyname("__TEXT");
    uint64_t addr = command->vmaddr;
    return addr;
}

intptr_t ImageSlide(void)
{
    char path[1024];
    uint32_t size = sizeof(path);
    if (_NSGetExecutablePath(path, &size) != 0) return -1;
    for (uint32_t i = 0; i < _dyld_image_count(); i++)
    {
        if (strcmp(_dyld_get_image_name(i), path) == 0)
            return _dyld_get_image_vmaddr_slide(i);
    }
    return 0;
}

uint64_t DynamicBaseAddress(void)
{
    return StaticBaseAddress() + ImageSlide();
}

int main (int argc, const char *argv[])
{
    printf("dynamic base address (%0llx) = static base address (%0llx) + image slide (%0lx)\n", DynamicBaseAddress(), StaticBaseAddress(), ImageSlide());
    while (1) {}; // you can attach to this process via gdb/lldb to view the base address now :)
    return 0;
}

それが役に立てば幸い!

于 2014-03-25T04:04:07.370 に答える