Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在macosx中获取进程基址_Macos - Fatal编程技术网

在macosx中获取进程基址

在macosx中获取进程基址,macos,Macos,我正在尝试使用task\u for\u pid/vm\u 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个字节 当我知道进程的基址(我

我正在尝试使用
task\u for\u pid
/
vm\u 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查看它)?

回答我自己的问题。我可以使用下面的
mach\u vm\u region\u 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");
    }
#包括
#包括
#包括
#包括
...
机器端口名称任务;
vm_map_offset_t vmoffset;
虚拟机地图大小虚拟机大小;
uint32嵌套深度=0;
结构虚拟机区域子映射信息64 vbr;
马赫数、型号、vbrcount=16;
kern_return_t kr;
如果((kr=mach_vm_region_)递归(task,&vmoffset,&vmsize,
&嵌套深度,
(虚拟机区域递归信息)和vbr,
&vbrcount)!=KERN_成功)
{
printf(“失败”);
}

既然您正在调用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;
}
#导入
#包括
#包括
#包括
#包括
uint64\u t静态基址(无效)
{
const struct segment_command_64*command=getsegbyname(“u TEXT”);
uint64_t addr=命令->vmaddr;
返回地址;
}
intptr\u t图像幻灯片(无效)
{
字符路径[1024];
uint32_t size=sizeof(路径);
if(\NSGetExecutablePath(路径和大小)!=0)返回-1;
对于(uint32_t i=0;i<\u dyld_image_count();i++)
{
if(strcmp(\u dyld\u get\u image\u name(i),path)==0)
返回"动态"获取"图像"添加"幻灯片(i);;
}
返回0;
}
uint64\u t动态数据库地址(无效)
{
返回StaticBaseAddress()+ImageSlide();
}
int main(int argc,const char*argv[]
{
printf(“动态基址(%0llx)=静态基址(%0llx)+图像幻灯片(%0lx)\n”、DynamicBaseAddress()、StaticBaseAddress()、ImageSlide();
while(1){};//您现在可以通过gdb/lldb附加到此进程以查看基址:)
返回0;
}

希望有帮助

非常有用的代码段,用于一个非常没有文档记录的函数。在命令行中,这可能非常有用:示例$pid 12>/dev/null | grep“Load Address”Hi,我为NoOB问题道歉-我尝试把这个代码添加到一个新的C文件中,我添加到一个DyLIB文件中,我创建了一个附加到一个应用程序,但是我不能在控制台中得到任何输出——而应该是C++文件吗?我尝试了这两种方法,但出现了一些构建错误。这会以这种方式在动态库中工作吗?任何提示都将不胜感激!