我正在尝试获取osx中加载的dylib的基址

时间:2016-11-24 11:40:15

标签: c++ macos reverse-engineering mach-o base-address

好吧,我想在很长一段时间内在运行时运行Proccesses来获取Loaded OSX Dylibs的baseadresses。

在使用task_info之后,我使用dyld_all_image_infos在运行时转储了所有附加的Dylibs,得到了名称和ImageLoadADDRESS,mach_header和segment_command。

但我无法在运行时使用Baseaddress ..

一切都很好,除了我对如何在运行时获取所请求图像的实际Baseaddress感到困惑! 另外我使用imageLoadAddress获取mach_header之后获得的Magic数字是“feedfacf”。它不应该是“feedface”吗?

搜索后我发现“segment_command”中的“fileoff”应该引导我进入数据部分。这也不起作用。

我的输出看起来很棒但是当我尝试在Cheat引擎中查看这个Memory Region时它是空的!

我的调试输出:

mach object header
magic number	feedfacf
cputype		01000007 - x86_64
subcputype	00000003
filetype	00000006
ncmds		00000015
sizeofcmds	00000988
flags		00118085
Segment
File Off	45545f5f
DYLIB: client.dylib

我的代码如下:

               // mach_header
                mach_msg_type_number_t size4 = sizeof(mach_header);
                uint8_t* info_addr2 =
                readProcessMemory(this->task, (mach_vm_address_t) info[i].imageLoadAddress, &size4);
                
                mach_header *info2 = (mach_header*) info_addr2;

                // segment
                mach_msg_type_number_t size5 = sizeof(segment_command);
                uint8_t* info_addr3 =
                readProcessMemory(this->task, (mach_vm_address_t) info[i].imageLoadAddress + sizeof(info2), &size5);
                
                segment_command *info3 = (segment_command*) info_addr3;
                tmp_str = tmp_str.substr(tmp_str.find_last_of("/") + 1, tmp_str.length());
                //printf("%i Debug: %s\n", i, tmp_str.c_str());
                this->dylibs[cc].Name = tmp_str;
                this->dylibs[cc].imgHead = info2;
               // this->dylibs[i].tSize = this->size_of_image((mach_header*)info[i].imageLoadAddress);
                if(strcmp(tmp_str.c_str(), "client.dylib") == 0){
                    this->client = cc;
                     printf("mach object header\n");
                    printf("magic number\t%08x\n", info2->magic);
                    printf("cputype\t\t%08x - %s\n", info2->cputype,cpu_type_name(info2->cputype));//cputype_to_string(info2->filetype)
                    printf("subcputype\t%08x\n",  info2->cpusubtype);
                    printf("filetype\t%08x\n",  info2->filetype);// filetype_to_string(info2->filetype)
                    printf("ncmds\t\t%08x\n",  info2->ncmds);
                    printf("sizeofcmds\t%08x\n",  info2->sizeofcmds);
                    printf("flags\t\t%08x\n",  info2->flags);
                    printf("Segment\n");
                    printf("File Off\t%x\n", info3->fileoff );

有人可以帮助我吗? 会很感激的! (p.s:代码有点让人困惑,但是我几天都在努力工作,无法让它工作,所以我现在不想用尼尔风格写它!)

1 个答案:

答案 0 :(得分:0)

vmaddr结构的

segment_command字段(或64位OS X的segment_command_64)是虚拟内存中段的地址。

mach-o图像标题的结构(dylib作为特定示例)如下:

| mach_header | load_command | load_command | ...... | load_command |

load_command结构的计数存储在ncmds的{​​{1}}字段中。其中一些是mach_header结构,您可以使用segment_command cmd字段进行检查。对于64位,如果load_commandcmdLC_SEGMENT,则64位为LC_SEGMENT_64segment_command。只需将segment_command_64投射到load_command

通常,segment_command存储在dylib的第一个段的第一个字节中。所以,如果我理解你的问题,mach_header就是你在找什么。

其他事情,你提到过魔法值info[i].imageLoadAddressfeedfacf。实际上,feedfacefeedface,而MH_MAGICfeedfacf。所有现代macbook,iMac和mac mini都是64位。