1

Well, i am trying to get the baseadresses for Loaded OSX Dylibs in running Proccesses on run time since a longtime now.

Ive dumped all attached Dylibs on runtime using dyld_all_image_infos after using task_info, got there name and ImageLoadADDRESS,mach_header and segment_command.

But i can't get there Baseaddress On runtime..

Everything works great except that i'm confused on how to get the actual Baseaddress of the requested Image in runtime! Also my Magic number which i got after Getting the mach_header using my imageLoadAddress is "feedfacf" . Shouldn't it be "feedface"?

After searching i found that "fileoff" in "segment_command" should lead me to the data section. This isn't working either.

My output is Looking great but when i try to view this Memory Region in Cheat engine for example it is empty!

My Debug output:

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

My Code is the following:

               // 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 );

could anyone may help me? Would appreciate it! ( p.s: Code is a bit confusing, but i am working around since days and can't get it to work, so i didn't want to write it in an Nicer style right now! )

  • Overchecked it and realized that my problem is just at getting the segment_command struct ! Please help! – Stefan Kerschbaumer Nov 24 '16 at 18:08
  • I beleive info2 is mach_header here, so you need iterate over loading commands ```struct load_command *cmd = (struct load_command *) ((char *)info2 + sizeof(struct mach_header)); size_t k = 0; while (k++ < info-> ncmds) { if (cmd.cmd == LC_SEGMENT) { struct segment_command *segment = (struct segment_command *)cmd; // do something useful } // next load_command cmd = (struct load_command *)((char *)cmd + cmd. cmdsize); } ``` – re_things Nov 24 '16 at 18:41

1 Answers1

0

vmaddr field of the segment_command structure (or segment_command_64 for 64-bit OS X) is address of segment in the virtual memory.

Structure of mach-o image header (dylib as particular example) is following:

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

Count of load_command structures is stored in the ncmds field of the mach_header. Some of them are segment_command structures, you can check it with cmd field of load_command. If cmd is LC_SEGMENT or LC_SEGMENT_64 for 64 bit - it's segment_command and segment_command_64 for 64 bit. Just cast load_command to the segment_command.

Usually, mach_header is stored in the first bytes of first segment of dylib. So, info[i].imageLoadAddress is what are you looking for if I understand your question right.

Other thing, you mentioned about magic values feedfacf and feedface. Actually, feedface is MH_MAGIC, while feedfacf is MH_MAGIC_64. All modern macbooks, iMacs and mac mini are 64 bit.

re_things
  • 679
  • 1
  • 8
  • 29
  • I'm really thankful for your answer ! I'm going to check your provided Information out when i am at home later that day. But 1 question is left right now. Your told me that "imageLoadAddress" should be my BaseAddress of the loaded dylib, right? Why is it then empty when i try to view this region in an Memory viewer? That's what's confusing me. I mean, i am in general new a t Mac Osx.. Getting the Baseaddresses of Modules was much easier on Windows! – Stefan Kerschbaumer Nov 25 '16 at 10:28
  • Are you sure that you looking for memory in the right process? Look, you read a memory using your readProcessMemory function with `info[i].imageLoadAddress` address and the memory is readable, right? Otherwise you will get empty `info2`. And what do you mean with 'Memory viewer'? I don't know such tool. Link or any additional information about it will be great to understand your problem. – re_things Nov 25 '16 at 21:17
  • Yeah, i'm looking in the right Process ! WIth memory viewer i mean viewing the binary of this address in Cheat engine for example. I'm currently trying to test writing game cheats on osx. But yeah... i seem to fail at the very beginning. – Stefan Kerschbaumer Nov 28 '16 at 14:49
  • Do you know about ASLR feature (Address space layout randomization)? Also, could you add `printf("memory address %08x\n", info[i].imageLoadAddress);` to your code and update output log please? – re_things Nov 29 '16 at 16:59