1/* 2 * Copyright © 2009 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 15 * contributors may be used to endorse or promote products derived from this 16 * software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * @APPLE_LICENSE_HEADER_END@ 30 */ 31#include "stdio.h" 32#include "stddef.h" 33#include "string.h" 34#include "mach-o/loader.h" 35#include "stuff/allocate.h" 36#include "stuff/bytesex.h" 37#include "stuff/symbol.h" 38#include "stuff/reloc.h" 39#include "ofile_print.h" 40 41extern char *oname; 42 43/* 44 * Here we need structures that have the same memory layout and size as the 45 * 64-bit Objective-C meta data structures that can be used in this 32-bit 46 * program. 47 * 48 * The real structure definitions come from the objc4 project in the private 49 * header file runtime/objc-runtime-new.h in that project. 50 */ 51 52struct class_t { 53 uint64_t isa; /* class_t * (64-bit pointer) */ 54 uint64_t superclass; /* class_t * (64-bit pointer) */ 55 uint64_t cache; /* Cache (64-bit pointer) */ 56 uint64_t vtable; /* IMP * (64-bit pointer) */ 57 uint64_t data; /* class_ro_t * (64-bit pointer) */ 58}; 59 60static 61void 62swap_class_t( 63struct class_t *c, 64enum byte_sex target_byte_sex) 65{ 66 c->isa = SWAP_LONG_LONG(c->isa); 67 c->superclass = SWAP_LONG_LONG(c->superclass); 68 c->cache = SWAP_LONG_LONG(c->cache); 69 c->vtable = SWAP_LONG_LONG(c->vtable); 70 c->data = SWAP_LONG_LONG(c->data); 71} 72 73struct class_ro_t { 74 uint32_t flags; 75 uint32_t instanceStart; 76 uint32_t instanceSize; 77 uint32_t reserved; 78 uint64_t ivarLayout; /* const uint8_t * (64-bit pointer) */ 79 uint64_t name; /* const char * (64-bit pointer) */ 80 uint64_t baseMethods; /* const method_list_t * (64-bit pointer) */ 81 uint64_t baseProtocols; /* const protocol_list_t * (64-bit pointer) */ 82 uint64_t ivars; /* const ivar_list_t * (64-bit pointer) */ 83 uint64_t weakIvarLayout; /* const uint8_t * (64-bit pointer) */ 84 uint64_t baseProperties; /* const struct objc_property_list * 85 (64-bit pointer) */ 86}; 87 88/* Values for class_ro_t->flags */ 89#define RO_META (1<<0) 90#define RO_ROOT (1<<1) 91#define RO_HAS_CXX_STRUCTORS (1<<2) 92 93 94static 95void 96swap_class_ro_t( 97struct class_ro_t *cro, 98enum byte_sex target_byte_sex) 99{ 100 cro->flags = SWAP_INT(cro->flags); 101 cro->instanceStart = SWAP_INT(cro->instanceStart); 102 cro->instanceSize = SWAP_INT(cro->instanceSize); 103 cro->reserved = SWAP_INT(cro->reserved); 104 cro->ivarLayout = SWAP_LONG_LONG(cro->ivarLayout); 105 cro->name = SWAP_LONG_LONG(cro->name); 106 cro->baseMethods = SWAP_LONG_LONG(cro->baseMethods); 107 cro->baseProtocols = SWAP_LONG_LONG(cro->baseProtocols); 108 cro->ivars = SWAP_LONG_LONG(cro->ivars); 109 cro->weakIvarLayout = SWAP_LONG_LONG(cro->weakIvarLayout); 110 cro->baseProperties = SWAP_LONG_LONG(cro->baseProperties); 111} 112 113struct method_list_t { 114 uint32_t entsize; 115 uint32_t count; 116 /* struct method_t first; These structures follow inline */ 117}; 118 119static 120void 121swap_method_list_t( 122struct method_list_t *ml, 123enum byte_sex target_byte_sex) 124{ 125 ml->entsize = SWAP_INT(ml->entsize); 126 ml->count = SWAP_INT(ml->count); 127} 128 129struct method_t { 130 uint64_t name; /* SEL (64-bit pointer) */ 131 uint64_t types; /* const char * (64-bit pointer) */ 132 uint64_t imp; /* IMP (64-bit pointer) */ 133}; 134 135static 136void 137swap_method_t( 138struct method_t *m, 139enum byte_sex target_byte_sex) 140{ 141 m->name = SWAP_LONG_LONG(m->name); 142 m->types = SWAP_LONG_LONG(m->types); 143 m->imp = SWAP_LONG_LONG(m->imp); 144} 145 146struct ivar_list_t { 147 uint32_t entsize; 148 uint32_t count; 149 /* struct ivar_t first; These structures follow inline */ 150}; 151 152static 153void 154swap_ivar_list_t( 155struct ivar_list_t *il, 156enum byte_sex target_byte_sex) 157{ 158 il->entsize = SWAP_INT(il->entsize); 159 il->count = SWAP_INT(il->count); 160} 161 162struct ivar_t { 163 uint64_t offset; /* uintptr_t * (64-bit pointer) */ 164 uint64_t name; /* const char * (64-bit pointer) */ 165 uint64_t type; /* const char * (64-bit pointer) */ 166 uint32_t alignment; 167 uint32_t size; 168}; 169 170static 171void 172swap_ivar_t( 173struct ivar_t *i, 174enum byte_sex target_byte_sex) 175{ 176 i->offset = SWAP_LONG_LONG(i->offset); 177 i->name = SWAP_LONG_LONG(i->name); 178 i->type = SWAP_LONG_LONG(i->type); 179 i->alignment = SWAP_INT(i->alignment); 180 i->size = SWAP_INT(i->size); 181} 182 183struct protocol_list_t { 184 uint64_t count; /* uintptr_t (a 64-bit value) */ 185 /* struct protocol_t * list[0]; These pointers follow inline */ 186}; 187 188static 189void 190swap_protocol_list_t( 191struct protocol_list_t *pl, 192enum byte_sex target_byte_sex) 193{ 194 pl->count = SWAP_LONG_LONG(pl->count); 195} 196 197struct protocol_t { 198 uint64_t isa; /* id * (64-bit pointer) */ 199 uint64_t name; /* const char * (64-bit pointer) */ 200 uint64_t protocols; /* struct protocol_list_t * 201 (64-bit pointer) */ 202 uint64_t instanceMethods; /* method_list_t * (64-bit pointer) */ 203 uint64_t classMethods; /* method_list_t * (64-bit pointer) */ 204 uint64_t optionalInstanceMethods; /* method_list_t * (64-bit pointer) */ 205 uint64_t optionalClassMethods; /* method_list_t * (64-bit pointer) */ 206 uint64_t instanceProperties; /* struct objc_property_list * 207 (64-bit pointer) */ 208}; 209 210static 211void 212swap_protocol_t( 213struct protocol_t *p, 214enum byte_sex target_byte_sex) 215{ 216 p->isa = SWAP_LONG_LONG(p->isa); 217 p->name = SWAP_LONG_LONG(p->name); 218 p->protocols = SWAP_LONG_LONG(p->protocols); 219 p->instanceMethods = SWAP_LONG_LONG(p->instanceMethods); 220 p->classMethods = SWAP_LONG_LONG(p->classMethods); 221 p->optionalInstanceMethods = SWAP_LONG_LONG(p->optionalInstanceMethods); 222 p->optionalClassMethods = SWAP_LONG_LONG(p->optionalClassMethods); 223 p->instanceProperties = SWAP_LONG_LONG(p->instanceProperties); 224} 225 226struct objc_property_list { 227 uint32_t entsize; 228 uint32_t count; 229 /* struct objc_property first; These structures follow inline */ 230}; 231 232static 233void 234swap_objc_property_list( 235struct objc_property_list *pl, 236enum byte_sex target_byte_sex) 237{ 238 pl->entsize = SWAP_INT(pl->entsize); 239 pl->count = SWAP_INT(pl->count); 240} 241 242struct objc_property { 243 uint64_t name; /* const char * (64-bit pointer) */ 244 uint64_t attributes; /* const char * (64-bit pointer) */ 245}; 246 247static 248void 249swap_objc_property( 250struct objc_property *op, 251enum byte_sex target_byte_sex) 252{ 253 op->name = SWAP_LONG_LONG(op->name); 254 op->attributes = SWAP_LONG_LONG(op->attributes); 255} 256 257struct category_t { 258 uint64_t name; /* const char * (64-bit pointer) */ 259 uint64_t cls; /* struct class_t * (64-bit pointer) */ 260 uint64_t instanceMethods; /* struct method_list_t * (64-bit pointer) */ 261 uint64_t classMethods; /* struct method_list_t * (64-bit pointer) */ 262 uint64_t protocols; /* struct protocol_list_t * (64-bit pointer) */ 263 uint64_t instanceProperties; /* struct objc_property_list * 264 (64-bit pointer) */ 265}; 266 267static 268void 269swap_category_t( 270struct category_t *c, 271enum byte_sex target_byte_sex) 272{ 273 c->name = SWAP_LONG_LONG(c->name); 274 c->cls = SWAP_LONG_LONG(c->cls); 275 c->instanceMethods = SWAP_LONG_LONG(c->instanceMethods); 276 c->classMethods = SWAP_LONG_LONG(c->classMethods); 277 c->protocols = SWAP_LONG_LONG(c->protocols); 278 c->instanceProperties = SWAP_LONG_LONG(c->instanceProperties); 279} 280 281struct message_ref { 282 uint64_t imp; /* IMP (64-bit pointer) */ 283 uint64_t sel; /* SEL (64-bit pointer) */ 284}; 285 286static 287void 288swap_message_ref( 289struct message_ref *mr, 290enum byte_sex target_byte_sex) 291{ 292 mr->imp = SWAP_LONG_LONG(mr->imp); 293 mr->sel = SWAP_LONG_LONG(mr->sel); 294} 295 296struct objc_image_info { 297 uint32_t version; 298 uint32_t flags; 299}; 300/* masks for objc_image_info.flags */ 301#define OBJC_IMAGE_IS_REPLACEMENT (1<<0) 302#define OBJC_IMAGE_SUPPORTS_GC (1<<1) 303 304 305static 306void 307swap_objc_image_info( 308struct objc_image_info *o, 309enum byte_sex target_byte_sex) 310{ 311 o->version = SWAP_INT(o->version); 312 o->flags = SWAP_INT(o->flags); 313} 314 315struct objc_string_object_64 { 316 uint64_t isa; /* class_t * (64-bit pointer) */ 317 uint64_t characters; /* char * (64-bit pointer) */ 318 uint32_t _length; /* number of non-NULL characters in above */ 319 uint32_t _pad; /* unused padding, compiler uses .space 4 */ 320}; 321 322static 323void 324swap_string_object_64( 325struct objc_string_object_64 *string_object, 326enum byte_sex target_byte_sex) 327{ 328 string_object->isa = SWAP_LONG_LONG(string_object->isa); 329 string_object->characters = SWAP_LONG_LONG(string_object->characters); 330 string_object->_length = SWAP_INT(string_object->_length); 331 string_object->_pad = SWAP_INT(string_object->_pad); 332} 333 334struct info { 335 enum bool swapped; 336 enum byte_sex host_byte_sex; 337 struct section_info_64 *sections; 338 uint32_t nsections; 339 cpu_type_t cputype; 340 struct nlist_64 *symbols64; 341 uint32_t nsymbols; 342 char *strings; 343 uint32_t strings_size; 344 struct symbol *sorted_symbols; 345 uint32_t nsorted_symbols; 346 uint64_t database; 347 struct relocation_info *ext_relocs; 348 uint32_t next_relocs; 349 struct relocation_info *loc_relocs; 350 uint32_t nloc_relocs; 351 enum bool verbose; 352 enum bool Vflag; 353}; 354 355struct section_info_64 { 356 char segname[16]; 357 char sectname[16]; 358 char *contents; 359 uint64_t addr; 360 uint64_t size; 361 uint32_t offset; 362 struct relocation_info *relocs; 363 uint32_t nrelocs; 364 enum bool cstring; 365 enum bool protected; 366 enum bool zerofill; 367}; 368 369static void walk_pointer_list( 370 char *listname, 371 struct section_info_64 *s, 372 struct info *info, 373 void (*func)(uint64_t, struct info *)); 374 375static void print_class_t( 376 uint64_t p, 377 struct info *info); 378 379static void print_class_ro_t( 380 uint64_t p, 381 struct info *info, 382 enum bool *is_meta_class); 383 384static void print_layout_map( 385 uint64_t p, 386 struct info *info); 387 388static void print_method_list_t( 389 uint64_t p, 390 struct info *info, 391 char *indent); 392 393static void print_ivar_list_t( 394 uint64_t p, 395 struct info *info); 396 397static void print_protocol_list_t( 398 uint64_t p, 399 struct info *info); 400 401static void print_objc_property_list( 402 uint64_t p, 403 struct info *info); 404 405static void print_category_t( 406 uint64_t p, 407 struct info *info); 408 409static void print_message_refs( 410 struct section_info_64 *s, 411 struct info *info); 412 413static void print_image_info( 414 struct section_info_64 *s, 415 struct info *info); 416 417static void get_sections_64( 418 struct load_command *load_commands, 419 uint32_t ncmds, 420 uint32_t sizeofcmds, 421 enum byte_sex object_byte_sex, 422 char *object_addr, 423 uint32_t object_size, 424 struct section_info_64 **sections, 425 uint32_t *nsections, 426 uint64_t *database); 427 428static struct section_info_64 *get_section_64( 429 struct section_info_64 *sections, 430 uint32_t nsections, 431 char *segname, 432 char *sectname); 433 434static void get_cstring_section_64( 435 struct load_command *load_commands, 436 uint32_t ncmds, 437 uint32_t sizeofcmds, 438 enum byte_sex object_byte_sex, 439 char *object_addr, 440 uint32_t object_size, 441 struct section_info_64 *cstring_section_ptr); 442 443static void *get_pointer_64( 444 uint64_t p, 445 uint32_t *offset, 446 uint32_t *left, 447 struct section_info_64 **s, 448 struct section_info_64 *sections, 449 uint32_t nsections); 450 451static const char *get_symbol_64( 452 uint32_t sect_offset, 453 uint64_t database_offset, 454 uint64_t value, 455 struct relocation_info *relocs, 456 uint32_t nrelocs, 457 struct info *info, 458 uint64_t *n_value); 459 460/* 461 * Print the objc2 meta data in 64-bit Mach-O files. 462 */ 463void 464print_objc2_64bit( 465cpu_type_t cputype, 466struct load_command *load_commands, 467uint32_t ncmds, 468uint32_t sizeofcmds, 469enum byte_sex object_byte_sex, 470char *object_addr, 471uint32_t object_size, 472struct nlist_64 *symbols64, 473uint32_t nsymbols, 474char *strings, 475uint32_t strings_size, 476struct symbol *sorted_symbols, 477uint32_t nsorted_symbols, 478struct relocation_info *ext_relocs, 479uint32_t next_relocs, 480struct relocation_info *loc_relocs, 481uint32_t nloc_relocs, 482enum bool verbose, 483enum bool Vflag) 484{ 485 struct section_info_64 *s; 486 struct info info; 487 488 info.host_byte_sex = get_host_byte_sex(); 489 info.swapped = info.host_byte_sex != object_byte_sex; 490 info.cputype = cputype; 491 info.symbols64 = symbols64; 492 info.nsymbols = nsymbols; 493 info.strings = strings; 494 info.strings_size = strings_size; 495 info.sorted_symbols = sorted_symbols; 496 info.nsorted_symbols = nsorted_symbols; 497 info.ext_relocs = ext_relocs; 498 info.next_relocs = next_relocs; 499 info.loc_relocs = loc_relocs; 500 info.nloc_relocs = nloc_relocs; 501 info.verbose = verbose; 502 info.Vflag = Vflag; 503 get_sections_64(load_commands, ncmds, sizeofcmds, object_byte_sex, 504 object_addr, object_size, &info.sections, 505 &info.nsections, &info.database); 506 507 s = get_section_64(info.sections, info.nsections, 508 "__OBJC2", "__class_list"); 509 if(s == NULL) 510 s = get_section_64(info.sections, info.nsections, 511 "__DATA", "__objc_classlist"); 512 walk_pointer_list("class", s, &info, print_class_t); 513 514 s = get_section_64(info.sections, info.nsections, 515 "__OBJC2", "__class_refs"); 516 if(s == NULL) 517 s = get_section_64(info.sections, info.nsections, 518 "__DATA", "__objc_classrefs"); 519 walk_pointer_list("class refs", s, &info, NULL); 520 521 s = get_section_64(info.sections, info.nsections, 522 "__OBJC2", "__super_refs"); 523 if(s == NULL) 524 s = get_section_64(info.sections, info.nsections, 525 "__DATA", "__objc_superrefs"); 526 walk_pointer_list("super refs", s, &info, NULL); 527 528 s = get_section_64(info.sections, info.nsections, 529 "__OBJC2", "__category_list"); 530 if(s == NULL) 531 s = get_section_64(info.sections, info.nsections, 532 "__DATA", "__objc_catlist"); 533 walk_pointer_list("category", s, &info, print_category_t); 534 535 s = get_section_64(info.sections, info.nsections, 536 "__OBJC2", "__protocol_list"); 537 if(s == NULL) 538 s = get_section_64(info.sections, info.nsections, 539 "__DATA", "__objc_protolist"); 540 walk_pointer_list("protocol", s, &info, NULL); 541 542 s = get_section_64(info.sections, info.nsections, 543 "__OBJC2", "__message_refs"); 544 if(s == NULL) 545 s = get_section_64(info.sections, info.nsections, 546 "__DATA", "__objc_msgrefs"); 547 print_message_refs(s, &info); 548 549 s = get_section_64(info.sections, info.nsections, 550 "__OBJC", "__image_info"); 551 if(s == NULL) 552 s = get_section_64(info.sections, info.nsections, 553 "__DATA", "__objc_imageinfo"); 554 print_image_info(s, &info); 555} 556 557static 558void 559walk_pointer_list( 560char *listname, 561struct section_info_64 *s, 562struct info *info, 563void (*func)(uint64_t, struct info *)) 564{ 565 uint32_t i, size, left; 566 uint64_t p, n_value; 567 const char *name; 568 569 if(s == NULL) 570 return; 571 572 printf("Contents of (%.16s,%.16s) section\n", s->segname, s->sectname); 573 for(i = 0; i < s->size; i += sizeof(uint64_t)){ 574 575 memset(&p, '\0', sizeof(uint64_t)); 576 left = s->size - i; 577 size = left < sizeof(uint64_t) ? 578 left : sizeof(uint64_t); 579 memcpy(&p, s->contents + i, size); 580 581 if(i + sizeof(uint64_t) > s->size) 582 printf("%s list pointer extends past end of (%s,%s) " 583 "section\n", listname, s->segname, s->sectname); 584 printf("%016llx ", s->addr + i); 585 586 if(info->swapped) 587 p = SWAP_LONG_LONG(p); 588 589 name = get_symbol_64(i, s->addr - info->database, p, 590 s->relocs, s->nrelocs, info, &n_value); 591 if(n_value != 0){ 592 printf("0x%llx", n_value); 593 if(p != 0) 594 printf(" + 0x%llx", p); 595 } 596 else 597 printf("0x%llx", p); 598 if(name != NULL) 599 printf(" %s", name); 600 printf("\n"); 601 602 p += n_value; 603 if(func != NULL) 604 func(p, info); 605 } 606} 607 608static 609void 610print_class_t( 611uint64_t p, 612struct info *info) 613{ 614 struct class_t c; 615 void *r; 616 uint32_t offset, left; 617 struct section_info_64 *s; 618 const char *name; 619 enum bool is_meta_class; 620 uint64_t n_value, isa_n_value; 621 622 is_meta_class = FALSE; 623 r = get_pointer_64(p, &offset, &left, &s, 624 info->sections, info->nsections); 625 if(r == NULL) 626 return; 627 memset(&c, '\0', sizeof(struct class_t)); 628 if(left < sizeof(struct class_t)){ 629 memcpy(&c, r, left); 630 printf(" (class_t entends past the end of the section)\n"); 631 } 632 else 633 memcpy(&c, r, sizeof(struct class_t)); 634 if(info->swapped) 635 swap_class_t(&c, info->host_byte_sex); 636 printf(" isa 0x%llx", c.isa); 637 name = get_symbol_64(offset + offsetof(struct class_t, isa), 638 s->addr - info->database, c.isa, s->relocs, 639 s->nrelocs, info, &isa_n_value); 640 if(name != NULL) 641 printf(" %s\n", name); 642 else 643 printf("\n"); 644 printf(" superclass 0x%llx", c.superclass); 645 name = get_symbol_64(offset + offsetof(struct class_t, superclass), 646 s->addr - info->database, c.superclass, s->relocs, 647 s->nrelocs, info, NULL); 648 if(name != NULL) 649 printf(" %s\n", name); 650 else 651 printf("\n"); 652 printf(" cache 0x%llx", c.cache); 653 name = get_symbol_64(offset + offsetof(struct class_t, cache), 654 s->addr - info->database, c.cache, s->relocs, 655 s->nrelocs, info, NULL); 656 if(name != NULL) 657 printf(" %s\n", name); 658 else 659 printf("\n"); 660 printf(" vtable 0x%llx", c.vtable); 661 name = get_symbol_64(offset + offsetof(struct class_t, vtable), 662 s->addr - info->database, c.vtable, s->relocs, 663 s->nrelocs, info, NULL); 664 if(name != NULL) 665 printf(" %s\n", name); 666 else 667 printf("\n"); 668 669 name = get_symbol_64(offset + offsetof(struct class_t, data), 670 s->addr - info->database, c.data, s->relocs, 671 s->nrelocs, info, &n_value); 672 printf(" data "); 673 if(n_value != 0){ 674 if(info->Vflag && name != NULL) 675 printf("%s", name); 676 else 677 printf("0x%llx", n_value); 678 if(c.data != 0) 679 printf(" + 0x%llx", c.data); 680 } 681 else{ 682 printf("0x%llx", c.data); 683 } 684 printf(" (struct class_ro_t *)"); 685 printf("\n"); 686 print_class_ro_t(c.data + n_value, info, &is_meta_class); 687 688 if(is_meta_class == FALSE){ 689 printf("Meta Class\n"); 690 print_class_t(c.isa + isa_n_value, info); 691 } 692} 693 694static 695void 696print_class_ro_t( 697uint64_t p, 698struct info *info, 699enum bool *is_meta_class) 700{ 701 struct class_ro_t cro; 702 void *r; 703 uint32_t offset, left; 704 struct section_info_64 *s; 705 const char *name, *sym_name; 706 uint64_t n_value; 707 708 r = get_pointer_64(p, &offset, &left, &s, info->sections, 709 info->nsections); 710 if(r == NULL) 711 return; 712 memset(&cro, '\0', sizeof(struct class_ro_t)); 713 if(left < sizeof(struct class_ro_t)){ 714 memcpy(&cro, r, left); 715 printf(" (class_ro_t entends past the end of the section)\n"); 716 } 717 else 718 memcpy(&cro, r, sizeof(struct class_ro_t)); 719 if(info->swapped) 720 swap_class_ro_t(&cro, info->host_byte_sex); 721 printf(" flags 0x%x", cro.flags); 722 if(cro.flags & RO_META) 723 printf(" RO_META"); 724 if(cro.flags & RO_ROOT) 725 printf(" RO_ROOT"); 726 if(cro.flags & RO_HAS_CXX_STRUCTORS) 727 printf(" RO_HAS_CXX_STRUCTORS"); 728 printf("\n"); 729 printf(" instanceStart %u\n", cro.instanceStart); 730 printf(" instanceSize %u\n", cro.instanceSize); 731 printf(" reserved 0x%x\n", cro.reserved); 732 printf(" ivarLayout 0x%llx\n", cro.ivarLayout); 733 print_layout_map(cro.ivarLayout, info); 734 735 printf(" name "); 736 sym_name = get_symbol_64(offset + offsetof(struct class_ro_t, name), 737 s->addr - info->database, cro.name, s->relocs, 738 s->nrelocs, info, &n_value); 739 if(n_value != 0){ 740 if(info->Vflag && sym_name != NULL) 741 printf("%s", sym_name); 742 else 743 printf("0x%llx", n_value); 744 if(cro.name != 0) 745 printf(" + 0x%llx", cro.name); 746 } 747 else 748 printf("0x%llx", cro.name); 749 name = get_pointer_64(cro.name + n_value, NULL, &left, NULL, 750 info->sections, info->nsections); 751 if(name != NULL) 752 printf(" %.*s", (int)left, name); 753 printf("\n"); 754 755 printf(" baseMethods "); 756 sym_name = get_symbol_64(offset + 757 offsetof(struct class_ro_t, baseMethods), 758 s->addr - info->database, cro.baseMethods, 759 s->relocs, s->nrelocs, info, &n_value); 760 if(n_value != 0){ 761 if(info->Vflag && sym_name != NULL) 762 printf("%s", sym_name); 763 else 764 printf("0x%llx", n_value); 765 if(cro.baseMethods != 0) 766 printf(" + 0x%llx", cro.baseMethods); 767 } 768 else 769 printf("0x%llx", cro.baseMethods); 770 printf(" (struct method_list_t *)\n"); 771 if(cro.baseMethods + n_value != 0) 772 print_method_list_t(cro.baseMethods + n_value, info, ""); 773 774 printf(" baseProtocols "); 775 sym_name = get_symbol_64(offset + 776 offsetof(struct class_ro_t, baseProtocols), 777 s->addr - info->database, cro.baseProtocols, 778 s->relocs, s->nrelocs, info, &n_value); 779 if(n_value != 0){ 780 if(info->Vflag && sym_name != NULL) 781 printf("%s", sym_name); 782 else 783 printf("0x%llx", n_value); 784 if(cro.baseProtocols != 0) 785 printf(" + 0x%llx", cro.baseProtocols); 786 } 787 else 788 printf("0x%llx", cro.baseProtocols); 789 printf("\n"); 790 if(cro.baseProtocols + n_value != 0) 791 print_protocol_list_t(cro.baseProtocols + n_value, info); 792 793 printf(" ivars "); 794 sym_name = get_symbol_64(offset + 795 offsetof(struct class_ro_t, ivars), 796 s->addr - info->database, cro.ivars, 797 s->relocs, s->nrelocs, info, &n_value); 798 if(n_value != 0){ 799 if(info->Vflag && sym_name != NULL) 800 printf("%s", sym_name); 801 else 802 printf("0x%llx", n_value); 803 if(cro.ivars != 0) 804 printf(" + 0x%llx", cro.ivars); 805 } 806 else 807 printf("0x%llx", cro.ivars); 808 printf("\n"); 809 if(cro.ivars + n_value != 0) 810 print_ivar_list_t(cro.ivars + n_value, info); 811 812 printf(" weakIvarLayout "); 813 sym_name = get_symbol_64(offset + 814 offsetof(struct class_ro_t, weakIvarLayout), 815 s->addr - info->database, cro.weakIvarLayout, 816 s->relocs, s->nrelocs, info, &n_value); 817 if(n_value != 0){ 818 if(info->Vflag && sym_name != NULL) 819 printf("%s", sym_name); 820 else 821 printf("0x%llx", n_value); 822 if(cro.weakIvarLayout != 0) 823 printf(" + 0x%llx", cro.weakIvarLayout); 824 } 825 else 826 printf("0x%llx", cro.weakIvarLayout); 827 printf("\n"); 828 print_layout_map(cro.weakIvarLayout + n_value, info); 829 830 printf(" baseProperties "); 831 sym_name = get_symbol_64(offset + 832 offsetof(struct class_ro_t, baseProperties), 833 s->addr - info->database, cro.baseProperties, 834 s->relocs, s->nrelocs, info, &n_value); 835 if(n_value != 0){ 836 if(info->Vflag && sym_name != NULL) 837 printf("%s", sym_name); 838 else 839 printf("0x%llx", n_value); 840 if(cro.baseProperties != 0) 841 printf(" + 0x%llx", cro.baseProperties); 842 } 843 else 844 printf("0x%llx", cro.baseProperties); 845 printf("\n"); 846 if(cro.baseProperties + n_value != 0) 847 print_objc_property_list(cro.baseProperties + n_value, info); 848 849 if(is_meta_class) 850 *is_meta_class = (cro.flags & RO_META) ? TRUE : FALSE; 851} 852 853static 854void 855print_layout_map( 856uint64_t p, 857struct info *info) 858{ 859 uint32_t offset, left; 860 struct section_info_64 *s; 861 char *layout_map; 862 863 if(p == 0) 864 return; 865 layout_map = get_pointer_64(p, &offset, &left, &s, 866 info->sections, info->nsections); 867 if(layout_map != NULL){ 868 printf(" layout map: "); 869 do{ 870 printf("0x%02x ", (*layout_map) & 0xff); 871 left--; 872 layout_map++; 873 }while(*layout_map != '\0' && left != 0); 874 printf("\n"); 875 } 876} 877 878static 879void 880print_method_list_t( 881uint64_t p, 882struct info *info, 883char *indent) 884{ 885 struct method_list_t ml; 886 struct method_t m; 887 void *r; 888 uint32_t offset, left, i; 889 struct section_info_64 *s; 890 const char *name, *sym_name; 891 uint64_t n_value; 892 893 r = get_pointer_64(p, &offset, &left, &s, info->sections, 894 info->nsections); 895 if(r == NULL) 896 return; 897 memset(&ml, '\0', sizeof(struct method_list_t)); 898 if(left < sizeof(struct method_list_t)){ 899 memcpy(&ml, r, left); 900 printf("%s (method_list_t entends past the end of the " 901 "section)\n", indent); 902 } 903 else 904 memcpy(&ml, r, sizeof(struct method_list_t)); 905 if(info->swapped) 906 swap_method_list_t(&ml, info->host_byte_sex); 907 printf("%s\t\t entsize %u\n", indent, ml.entsize); 908 printf("%s\t\t count %u\n", indent, ml.count); 909 910 p += sizeof(struct method_list_t); 911 offset += sizeof(struct method_list_t); 912 for(i = 0; i < ml.count; i++){ 913 r = get_pointer_64(p, &offset, &left, &s, info->sections, 914 info->nsections); 915 if(r == NULL) 916 return; 917 memset(&m, '\0', sizeof(struct method_t)); 918 if(left < sizeof(struct method_t)){ 919 memcpy(&ml, r, left); 920 printf("%s (method_t entends past the end of the " 921 "section)\n", indent); 922 } 923 else 924 memcpy(&m, r, sizeof(struct method_t)); 925 if(info->swapped) 926 swap_method_t(&m, info->host_byte_sex); 927 928 printf("%s\t\t name ", indent); 929 sym_name = get_symbol_64(offset + offsetof(struct method_t, name), 930 s->addr - info->database, m.name, 931 s->relocs, s->nrelocs, info, &n_value); 932 if(n_value != 0){ 933 if(info->Vflag && sym_name != NULL) 934 printf("%s", sym_name); 935 else 936 printf("0x%llx", n_value); 937 if(m.name != 0) 938 printf(" + 0x%llx", m.name); 939 } 940 else 941 printf("0x%llx", m.name); 942 name = get_pointer_64(m.name + n_value, NULL, &left, NULL, 943 info->sections, info->nsections); 944 if(name != NULL) 945 printf(" %.*s", (int)left, name); 946 printf("\n"); 947 948 printf("%s\t\t types ", indent); 949 sym_name = get_symbol_64(offset + offsetof(struct method_t, types), 950 s->addr - info->database, m.types, 951 s->relocs, s->nrelocs, info, &n_value); 952 if(n_value != 0){ 953 if(info->Vflag && sym_name != NULL) 954 printf("%s", sym_name); 955 else 956 printf("0x%llx", n_value); 957 if(m.name != 0) 958 printf(" + 0x%llx", m.types); 959 } 960 else 961 printf("0x%llx", m.types); 962 name = get_pointer_64(m.types + n_value, NULL, &left, NULL, 963 info->sections, info->nsections); 964 if(name != NULL) 965 printf(" %.*s", (int)left, name); 966 printf("\n"); 967 968 printf("%s\t\t imp ", indent); 969 name = get_symbol_64(offset + offsetof(struct method_t, imp), 970 s->addr - info->database, m.imp, s->relocs, 971 s->nrelocs, info, &n_value); 972 if(info->Vflag == FALSE || name == NULL){ 973 if(n_value != 0){ 974 printf("0x%llx ", n_value); 975 if(m.imp != 0) 976 printf("+ 0x%llx ", m.imp); 977 } 978 else 979 printf("0x%llx ", m.imp); 980 } 981 if(name != NULL) 982 printf("%s", name); 983 printf("\n"); 984 985 p += sizeof(struct method_t); 986 offset += sizeof(struct method_t); 987 } 988} 989 990static 991void 992print_ivar_list_t( 993uint64_t p, 994struct info *info) 995{ 996 struct ivar_list_t il; 997 struct ivar_t i; 998 void *r; 999 uint32_t offset, left, j; 1000 struct section_info_64 *s; 1001 const char *name, *sym_name; 1002 uint64_t *ivar_offset_p, ivar_offset, n_value; 1003 1004 1005 r = get_pointer_64(p, &offset, &left, &s, info->sections, 1006 info->nsections); 1007 if(r == NULL) 1008 return; 1009 memset(&il, '\0', sizeof(struct ivar_list_t)); 1010 if(left < sizeof(struct ivar_list_t)){ 1011 memcpy(&il, r, left); 1012 printf(" (ivar_list_t entends past the end of the section)\n"); 1013 } 1014 else 1015 memcpy(&il, r, sizeof(struct ivar_list_t)); 1016 if(info->swapped) 1017 swap_ivar_list_t(&il, info->host_byte_sex); 1018 printf(" entsize %u\n", il.entsize); 1019 printf(" count %u\n", il.count); 1020 1021 p += sizeof(struct ivar_list_t); 1022 offset += sizeof(struct ivar_list_t); 1023 for(j = 0; j < il.count; j++){ 1024 r = get_pointer_64(p, &offset, &left, &s, info->sections, 1025 info->nsections); 1026 if(r == NULL) 1027 return; 1028 memset(&i, '\0', sizeof(struct ivar_t)); 1029 if(left < sizeof(struct ivar_t)){ 1030 memcpy(&i, r, left); 1031 printf(" (ivar_t entends past the end of the section)\n"); 1032 } 1033 else 1034 memcpy(&i, r, sizeof(struct ivar_t)); 1035 if(info->swapped) 1036 swap_ivar_t(&i, info->host_byte_sex); 1037 1038 printf("\t\t\t offset "); 1039 sym_name = get_symbol_64(offset + offsetof(struct ivar_t, offset), 1040 s->addr - info->database, i.offset, 1041 s->relocs, s->nrelocs, info, &n_value); 1042 if(n_value != 0){ 1043 if(info->Vflag && sym_name != NULL) 1044 printf("%s", sym_name); 1045 else 1046 printf("0x%llx", n_value); 1047 if(i.offset != 0) 1048 printf(" + 0x%llx", i.offset); 1049 } 1050 else 1051 printf("0x%llx", i.offset); 1052 ivar_offset_p = get_pointer_64(i.offset + n_value, NULL, &left, 1053 NULL,info->sections,info->nsections); 1054 if(ivar_offset_p != NULL && left >= sizeof(*ivar_offset_p)){ 1055 memcpy(&ivar_offset, ivar_offset_p, sizeof(ivar_offset)); 1056 if(info->swapped) 1057 ivar_offset = SWAP_LONG_LONG(ivar_offset); 1058 printf(" %llu\n", ivar_offset); 1059 } 1060 else 1061 printf("\n"); 1062 1063 printf("\t\t\t name "); 1064 sym_name = get_symbol_64(offset + offsetof(struct ivar_t, name), 1065 s->addr - info->database, i.name, 1066 s->relocs, s->nrelocs, info, &n_value); 1067 if(n_value != 0){ 1068 if(info->Vflag && sym_name != NULL) 1069 printf("%s", sym_name); 1070 else 1071 printf("0x%llx", n_value); 1072 if(i.name != 0) 1073 printf(" + 0x%llx", i.name); 1074 } 1075 else 1076 printf("0x%llx", i.name); 1077 name = get_pointer_64(i.name + n_value, NULL, &left, NULL, 1078 info->sections, info->nsections); 1079 if(name != NULL) 1080 printf(" %.*s", (int)left, name); 1081 printf("\n"); 1082 1083 printf("\t\t\t type "); 1084 sym_name = get_symbol_64(offset + offsetof(struct ivar_t, type), 1085 s->addr - info->database, i.type, 1086 s->relocs, s->nrelocs, info, &n_value); 1087 name = get_pointer_64(i.type + n_value, NULL, &left, NULL, 1088 info->sections, info->nsections); 1089 if(n_value != 0){ 1090 if(info->Vflag && sym_name != NULL) 1091 printf("%s", sym_name); 1092 else 1093 printf("0x%llx", n_value); 1094 if(i.type != 0) 1095 printf(" + 0x%llx", i.type); 1096 } 1097 else 1098 printf("0x%llx", i.type); 1099 if(name != NULL) 1100 printf(" %.*s", (int)left, name); 1101 printf("\n"); 1102 1103 printf("\t\t\talignment %u\n", i.alignment); 1104 printf("\t\t\t size %u\n", i.size); 1105 1106 p += sizeof(struct ivar_t); 1107 offset += sizeof(struct ivar_t); 1108 } 1109} 1110 1111static 1112void 1113print_protocol_list_t( 1114uint64_t p, 1115struct info *info) 1116{ 1117 struct protocol_list_t pl; 1118 uint64_t q, n_value; 1119 struct protocol_t pc; 1120 void *r; 1121 uint32_t offset, left, i; 1122 struct section_info_64 *s; 1123 const char *name, *sym_name; 1124 1125 r = get_pointer_64(p, &offset, &left, &s, info->sections, 1126 info->nsections); 1127 if(r == NULL) 1128 return; 1129 memset(&pl, '\0', sizeof(struct protocol_list_t)); 1130 if(left < sizeof(struct protocol_list_t)){ 1131 memcpy(&pl, r, left); 1132 printf(" (protocol_list_t entends past the end of the " 1133 "section)\n"); 1134 } 1135 else 1136 memcpy(&pl, r, sizeof(struct protocol_list_t)); 1137 if(info->swapped) 1138 swap_protocol_list_t(&pl, info->host_byte_sex); 1139 printf(" count %llu\n", pl.count); 1140 1141 p += sizeof(struct protocol_list_t); 1142 offset += sizeof(struct protocol_list_t); 1143 for(i = 0; i < pl.count; i++){ 1144 r = get_pointer_64(p, &offset, &left, &s, info->sections, 1145 info->nsections); 1146 if(r == NULL) 1147 return; 1148 q = 0; 1149 if(left < sizeof(uint64_t)){ 1150 memcpy(&q, r, left); 1151 printf(" (protocol_t * entends past the end of the " 1152 "section)\n"); 1153 } 1154 else 1155 memcpy(&q, r, sizeof(uint64_t)); 1156 if(info->swapped) 1157 q = SWAP_LONG_LONG(q); 1158 1159 printf("\t\t list[%u] ", i); 1160 sym_name = get_symbol_64(offset, s->addr - info->database, q, 1161 s->relocs, s->nrelocs, info, &n_value); 1162 if(n_value != 0){ 1163 if(info->Vflag && sym_name != NULL) 1164 printf("%s", sym_name); 1165 else 1166 printf("0x%llx", n_value); 1167 if(q != 0) 1168 printf(" + 0x%llx", q); 1169 } 1170 else 1171 printf("0x%llx", q); 1172 printf(" (struct protocol_t *)\n"); 1173 1174 r = get_pointer_64(q + n_value, &offset, &left, &s, info->sections, 1175 info->nsections); 1176 if(r == NULL) 1177 return; 1178 memset(&pc, '\0', sizeof(struct protocol_t)); 1179 if(left < sizeof(struct protocol_t)){ 1180 memcpy(&pc, r, left); 1181 printf(" (protocol_t entends past the end of the section)\n"); 1182 } 1183 else 1184 memcpy(&pc, r, sizeof(struct protocol_t)); 1185 if(info->swapped) 1186 swap_protocol_t(&pc, info->host_byte_sex); 1187 1188 printf("\t\t\t isa 0x%llx\n", pc.isa); 1189 1190 printf("\t\t\t name "); 1191 sym_name = get_symbol_64(offset + offsetof(struct protocol_t, name), 1192 s->addr - info->database, pc.name, 1193 s->relocs, s->nrelocs, info, &n_value); 1194 if(n_value != 0){ 1195 if(info->Vflag && sym_name != NULL) 1196 printf("%s", sym_name); 1197 else 1198 printf("0x%llx", n_value); 1199 if(pc.name != 0) 1200 printf(" + 0x%llx", pc.name); 1201 } 1202 else 1203 printf("0x%llx", pc.name); 1204 name = get_pointer_64(pc.name + n_value , NULL, &left, NULL, 1205 info->sections, info->nsections); 1206 if(name != NULL) 1207 printf(" %.*s", (int)left, name); 1208 printf("\n"); 1209 1210 printf("\t\t\tprotocols 0x%llx\n", pc.protocols); 1211 1212 printf("\t\t instanceMethods "); 1213 sym_name = get_symbol_64(offset + offsetof(struct protocol_t, 1214 instanceMethods), 1215 s->addr - info->database, 1216 pc.instanceMethods, s->relocs, s->nrelocs, 1217 info, &n_value); 1218 if(n_value != 0){ 1219 if(info->Vflag && sym_name != NULL) 1220 printf("%s", sym_name); 1221 else 1222 printf("0x%llx", n_value); 1223 if(pc.instanceMethods != 0) 1224 printf(" + 0x%llx", pc.instanceMethods); 1225 } 1226 else 1227 printf("0x%llx", pc.instanceMethods); 1228 printf(" (struct method_list_t *)\n"); 1229 if(pc.instanceMethods + n_value != 0) 1230 print_method_list_t(pc.instanceMethods + n_value, info, "\t"); 1231 1232 printf("\t\t classMethods "); 1233 sym_name = get_symbol_64(offset + offsetof(struct protocol_t, 1234 classMethods), 1235 s->addr - info->database, 1236 pc.classMethods, s->relocs, s->nrelocs, 1237 info, &n_value); 1238 if(n_value != 0){ 1239 if(info->Vflag && sym_name != NULL) 1240 printf("%s", sym_name); 1241 else 1242 printf("0x%llx", n_value); 1243 if(pc.classMethods != 0) 1244 printf(" + 0x%llx", pc.classMethods); 1245 } 1246 else 1247 printf("0x%llx", pc.classMethods); 1248 printf(" (struct method_list_t *)\n"); 1249 1250 if(pc.classMethods + n_value != 0) 1251 print_method_list_t(pc.classMethods + n_value, info, "\t"); 1252 printf("\t optionalInstanceMethods 0x%llx\n", 1253 pc.optionalInstanceMethods); 1254 printf("\t optionalClassMethods 0x%llx\n", 1255 pc.optionalClassMethods); 1256 printf("\t instanceProperties 0x%llx\n", 1257 pc.instanceProperties); 1258 1259 p += sizeof(uint64_t); 1260 offset += sizeof(uint64_t); 1261 } 1262} 1263 1264static 1265void 1266print_objc_property_list( 1267uint64_t p, 1268struct info *info) 1269{ 1270 struct objc_property_list opl; 1271 struct objc_property op; 1272 void *r; 1273 uint32_t offset, left, j; 1274 struct section_info_64 *s; 1275 const char *name, *sym_name; 1276 uint64_t n_value; 1277 1278 r = get_pointer_64(p, &offset, &left, &s, info->sections, 1279 info->nsections); 1280 if(r == NULL) 1281 return; 1282 memset(&opl, '\0', sizeof(struct objc_property_list)); 1283 if(left < sizeof(struct objc_property_list)){ 1284 memcpy(&opl, r, left); 1285 printf(" (objc_property_list entends past the end of the " 1286 "section)\n"); 1287 } 1288 else 1289 memcpy(&opl, r, sizeof(struct objc_property_list)); 1290 if(info->swapped) 1291 swap_objc_property_list(&opl, info->host_byte_sex); 1292 printf(" entsize %u\n", opl.entsize); 1293 printf(" count %u\n", opl.count); 1294 1295 p += sizeof(struct objc_property_list); 1296 offset += sizeof(struct objc_property_list); 1297 for(j = 0; j < opl.count; j++){ 1298 r = get_pointer_64(p, &offset, &left, &s, info->sections, 1299 info->nsections); 1300 if(r == NULL) 1301 return; 1302 memset(&op, '\0', sizeof(struct objc_property)); 1303 if(left < sizeof(struct objc_property)){ 1304 memcpy(&op, r, left); 1305 printf(" (objc_property entends past the end of the " 1306 "section)\n"); 1307 } 1308 else 1309 memcpy(&op, r, sizeof(struct objc_property)); 1310 if(info->swapped) 1311 swap_objc_property(&op, info->host_byte_sex); 1312 1313 printf("\t\t\t name "); 1314 sym_name = get_symbol_64(offset + offsetof(struct objc_property, 1315 name), 1316 s->addr - info->database, op.name, 1317 s->relocs, s->nrelocs, info, &n_value); 1318 if(n_value != 0){ 1319 if(info->Vflag && sym_name != NULL) 1320 printf("%s", sym_name); 1321 else 1322 printf("0x%llx", n_value); 1323 if(op.name != 0) 1324 printf(" + 0x%llx", op.name); 1325 } 1326 else 1327 printf("0x%llx", op.name); 1328 name = get_pointer_64(op.name + n_value, NULL, &left, NULL, 1329 info->sections, info->nsections); 1330 if(name != NULL) 1331 printf(" %.*s", (int)left, name); 1332 printf("\n"); 1333 1334 printf("\t\t\tattributes "); 1335 sym_name = get_symbol_64(offset + offsetof(struct objc_property, 1336 attributes), 1337 s->addr - info->database, op.attributes, 1338 s->relocs, s->nrelocs, info, &n_value); 1339 if(n_value != 0){ 1340 if(info->Vflag && sym_name != NULL) 1341 printf("%s", sym_name); 1342 else 1343 printf("0x%llx", n_value); 1344 if(op.attributes != 0) 1345 printf(" + 0x%llx", op.attributes); 1346 } 1347 else 1348 printf("0x%llx", op.attributes); 1349 name = get_pointer_64(op.attributes + n_value, NULL, &left, NULL, 1350 info->sections, info->nsections); 1351 if(name != NULL) 1352 printf(" %.*s", (int)left, name); 1353 printf("\n"); 1354 1355 p += sizeof(struct objc_property); 1356 offset += sizeof(struct objc_property); 1357 } 1358} 1359 1360static 1361void 1362print_category_t( 1363uint64_t p, 1364struct info *info) 1365{ 1366 struct category_t c; 1367 void *r; 1368 uint32_t offset, left; 1369 struct section_info_64 *s; 1370 const char *name, *sym_name; 1371 uint64_t n_value; 1372 1373 r = get_pointer_64(p, &offset, &left, &s, 1374 info->sections, info->nsections); 1375 if(r == NULL) 1376 return; 1377 memset(&c, '\0', sizeof(struct category_t)); 1378 if(left < sizeof(struct category_t)){ 1379 memcpy(&c, r, left); 1380 printf(" (category_t entends past the end of the section)\n"); 1381 } 1382 else 1383 memcpy(&c, r, sizeof(struct category_t)); 1384 if(info->swapped) 1385 swap_category_t(&c, info->host_byte_sex); 1386 1387 printf(" name "); 1388 sym_name = get_symbol_64(offset + offsetof(struct category_t, name), 1389 s->addr - info->database, c.name, s->relocs, 1390 s->nrelocs, info, &n_value); 1391 if(n_value != 0){ 1392 if(info->Vflag && sym_name != NULL) 1393 printf("%s", sym_name); 1394 else 1395 printf("0x%llx", n_value); 1396 if(c.name != 0) 1397 printf(" + 0x%llx", c.name); 1398 } 1399 else 1400 printf("0x%llx", c.name); 1401 name = get_pointer_64(c.name + n_value, NULL, &left, NULL, 1402 info->sections, info->nsections); 1403 if(name != NULL) 1404 printf(" %.*s", (int)left, name); 1405 printf("\n"); 1406 1407 printf(" cls "); 1408 sym_name = get_symbol_64(offset + offsetof(struct category_t, cls), 1409 s->addr - info->database, c.cls, s->relocs, 1410 s->nrelocs, info, &n_value); 1411 if(n_value != 0){ 1412 if(info->Vflag && sym_name != NULL) 1413 printf("%s", sym_name); 1414 else 1415 printf("0x%llx", n_value); 1416 if(c.cls != 0) 1417 printf(" + 0x%llx", c.cls); 1418 } 1419 else 1420 printf("0x%llx", c.cls); 1421 printf("\n"); 1422 if(c.cls + n_value != 0) 1423 print_class_t(c.cls + n_value, info); 1424 1425 printf(" instanceMethods "); 1426 sym_name = get_symbol_64(offset + offsetof(struct category_t, 1427 instanceMethods), 1428 s->addr - info->database, c.instanceMethods, 1429 s->relocs, s->nrelocs, info, &n_value); 1430 if(n_value != 0){ 1431 if(info->Vflag && sym_name != NULL) 1432 printf("%s", sym_name); 1433 else 1434 printf("0x%llx", n_value); 1435 if(c.instanceMethods != 0) 1436 printf(" + 0x%llx", c.instanceMethods); 1437 } 1438 else 1439 printf("0x%llx", c.instanceMethods); 1440 printf("\n"); 1441 if(c.instanceMethods + n_value != 0) 1442 print_method_list_t(c.instanceMethods + n_value, info, ""); 1443 1444 printf(" classMethods "); 1445 sym_name = get_symbol_64(offset + offsetof(struct category_t, 1446 classMethods), 1447 s->addr - info->database, c.classMethods, 1448 s->relocs, s->nrelocs, info, &n_value); 1449 if(n_value != 0){ 1450 if(info->Vflag && sym_name != NULL) 1451 printf("%s", sym_name); 1452 else 1453 printf("0x%llx", n_value); 1454 if(c.classMethods != 0) 1455 printf(" + 0x%llx", c.classMethods); 1456 } 1457 else 1458 printf("0x%llx", c.classMethods); 1459 printf("\n"); 1460 if(c.classMethods + n_value != 0) 1461 print_method_list_t(c.classMethods + n_value, info, ""); 1462 1463 printf(" protocols "); 1464 sym_name = get_symbol_64(offset + offsetof(struct category_t, 1465 protocols), 1466 s->addr - info->database, c.protocols, 1467 s->relocs, s->nrelocs, info, &n_value); 1468 if(n_value != 0){ 1469 if(info->Vflag && sym_name != NULL) 1470 printf("%s", sym_name); 1471 else 1472 printf("0x%llx", n_value); 1473 if(c.protocols != 0) 1474 printf(" + 0x%llx", c.protocols); 1475 } 1476 else 1477 printf("0x%llx", c.protocols); 1478 printf("\n"); 1479 if(c.protocols + n_value != 0) 1480 print_protocol_list_t(c.protocols + n_value, info); 1481 1482 printf("instanceProperties "); 1483 sym_name = get_symbol_64(offset + offsetof(struct category_t, 1484 instanceProperties), 1485 s->addr - info->database, c.instanceProperties, 1486 s->relocs, s->nrelocs, info, &n_value); 1487 if(n_value != 0){ 1488 if(info->Vflag && sym_name != NULL) 1489 printf("%s", sym_name); 1490 else 1491 printf("0x%llx", n_value); 1492 if(c.instanceProperties != 0) 1493 printf(" + 0x%llx", c.instanceProperties); 1494 } 1495 else 1496 printf("0x%llx", c.instanceProperties); 1497 printf("\n"); 1498 if(c.instanceProperties + n_value) 1499 print_objc_property_list(c.instanceProperties + n_value, info); 1500} 1501 1502static 1503void 1504print_message_refs( 1505struct section_info_64 *s, 1506struct info *info) 1507{ 1508 uint32_t i, left, offset; 1509 uint64_t p, n_value; 1510 struct message_ref mr; 1511 const char *name, *sym_name; 1512 void *r; 1513 1514 if(s == NULL) 1515 return; 1516 1517 printf("Contents of (%.16s,%.16s) section\n", s->segname, s->sectname); 1518 offset = 0; 1519 for(i = 0; i < s->size; i += sizeof(struct message_ref)){ 1520 p = s->addr + i; 1521 r = get_pointer_64(p, &offset, &left, &s, 1522 info->sections, info->nsections); 1523 if(r == NULL) 1524 return; 1525 memset(&mr, '\0', sizeof(struct message_ref)); 1526 if(left < sizeof(struct message_ref)){ 1527 memcpy(&mr, r, left); 1528 printf(" (message_ref entends past the end of the section)\n"); 1529 } 1530 else 1531 memcpy(&mr, r, sizeof(struct message_ref)); 1532 if(info->swapped) 1533 swap_message_ref(&mr, info->host_byte_sex); 1534 1535 printf(" imp "); 1536 name = get_symbol_64(offset + offsetof(struct message_ref, imp), 1537 s->addr - info->database, mr.imp, s->relocs, 1538 s->nrelocs, info, &n_value); 1539 if(n_value != 0){ 1540 printf("0x%llx", n_value); 1541 if(mr.imp != 0) 1542 printf(" + 0x%llx", mr.imp); 1543 } 1544 else 1545 printf("0x%llx", mr.imp); 1546 if(name != NULL) 1547 printf(" %s", name); 1548 printf("\n"); 1549 1550 printf(" sel "); 1551 sym_name = get_symbol_64(offset + offsetof(struct message_ref, sel), 1552 s->addr - info->database, mr.sel, 1553 s->relocs, s->nrelocs, info, &n_value); 1554 if(n_value != 0){ 1555 if(info->Vflag && sym_name != NULL) 1556 printf("%s", sym_name); 1557 else 1558 printf("0x%llx", n_value); 1559 if(mr.sel != 0) 1560 printf(" + 0x%llx", mr.sel); 1561 } 1562 else 1563 printf("0x%llx", mr.sel); 1564 name = get_pointer_64(mr.sel + n_value, NULL, &left, NULL, 1565 info->sections, info->nsections); 1566 if(name != NULL) 1567 printf(" %.*s", (int)left, name); 1568 printf("\n"); 1569 1570 offset += sizeof(struct message_ref); 1571 } 1572} 1573 1574static 1575void 1576print_image_info( 1577struct section_info_64 *s, 1578struct info *info) 1579{ 1580 uint32_t left, offset; 1581 uint64_t p; 1582 struct objc_image_info o; 1583 void *r; 1584 1585 if(s == NULL) 1586 return; 1587 1588 printf("Contents of (%.16s,%.16s) section\n", s->segname, s->sectname); 1589 p = s->addr; 1590 r = get_pointer_64(p, &offset, &left, &s, 1591 info->sections, info->nsections); 1592 if(r == NULL) 1593 return; 1594 memset(&o, '\0', sizeof(struct objc_image_info)); 1595 if(left < sizeof(struct objc_image_info)){ 1596 memcpy(&o, r, left); 1597 printf(" (objc_image_info entends past the end of the section)\n"); 1598 } 1599 else 1600 memcpy(&o, r, sizeof(struct objc_image_info)); 1601 if(info->swapped) 1602 swap_objc_image_info(&o, info->host_byte_sex); 1603 printf(" version %u\n", o.version); 1604 printf(" flags 0x%x", o.flags); 1605 if(o.flags & OBJC_IMAGE_IS_REPLACEMENT) 1606 printf(" OBJC_IMAGE_IS_REPLACEMENT"); 1607 if(o.flags & OBJC_IMAGE_SUPPORTS_GC) 1608 printf(" OBJC_IMAGE_SUPPORTS_GC"); 1609 printf("\n"); 1610} 1611 1612void 1613print_objc_string_object_section_64( 1614char *sectname, 1615struct load_command *load_commands, 1616uint32_t ncmds, 1617uint32_t sizeofcmds, 1618enum byte_sex object_byte_sex, 1619char *object_addr, 1620uint32_t object_size, 1621cpu_type_t cputype, 1622struct nlist_64 *symbols64, 1623uint32_t nsymbols, 1624char *strings, 1625const uint32_t strings_size, 1626struct symbol *sorted_symbols, 1627uint32_t nsorted_symbols, 1628enum bool verbose) 1629{ 1630 struct info info; 1631 struct section_info_64 *o, cstring_section; 1632 struct objc_string_object_64 *string_objects, *s, string_object; 1633 uint64_t string_objects_addr, string_objects_size; 1634 uint32_t size, left; 1635 char *p; 1636 const char *name; 1637 1638 printf("Contents of (" SEG_OBJC ",%s) section\n", sectname); 1639 info.host_byte_sex = get_host_byte_sex(); 1640 info.swapped = info.host_byte_sex != object_byte_sex; 1641 info.cputype = cputype; 1642 info.symbols64 = symbols64; 1643 info.nsymbols = nsymbols; 1644 info.strings = strings; 1645 info.strings_size = strings_size; 1646 info.sorted_symbols = sorted_symbols; 1647 info.nsorted_symbols = nsorted_symbols; 1648 info.verbose = verbose; 1649 get_sections_64(load_commands, ncmds, sizeofcmds, object_byte_sex, 1650 object_addr, object_size, &info.sections, 1651 &info.nsections, &info.database); 1652 o = get_section_64(info.sections, info.nsections, SEG_OBJC, sectname); 1653 get_cstring_section_64(load_commands, ncmds, sizeofcmds,object_byte_sex, 1654 object_addr, object_size, &cstring_section); 1655 1656 string_objects = (struct objc_string_object_64 *)o->contents; 1657 string_objects_addr = o->addr; 1658 string_objects_size = o->size; 1659 for(s = string_objects; 1660 (char *)s < (char *)string_objects + string_objects_size; 1661 s++){ 1662 1663 memset(&string_object, '\0', sizeof(struct objc_string_object_64)); 1664 left = string_objects_size - (s - string_objects); 1665 size = left < sizeof(struct objc_string_object_64) ? 1666 left : sizeof(struct objc_string_object_64); 1667 memcpy(&string_object, s, size); 1668 1669 if((char *)s + sizeof(struct objc_string_object_64) > 1670 (char *)s + string_objects_size) 1671 printf("String Object extends past end of %s section\n", 1672 sectname); 1673 printf("String Object 0x%llx\n", 1674 string_objects_addr + ((char *)s - (char *)string_objects)); 1675 1676 if(info.swapped) 1677 swap_string_object_64(&string_object, info.host_byte_sex); 1678 printf(" isa 0x%llx", string_object.isa); 1679 name = get_symbol_64((uintptr_t)s - (uintptr_t)string_objects, 1680 o->addr - info.database, string_object.isa, 1681 o->relocs, o->nrelocs, &info, NULL); 1682 if(name != NULL) 1683 printf(" %s\n", name); 1684 else 1685 printf("\n"); 1686 printf(" characters 0x%llx", string_object.characters); 1687 if(verbose){ 1688 p = get_pointer_64(string_object.characters, NULL, &left, 1689 NULL, info.sections, info.nsections); 1690 if(p != NULL) 1691 printf(" %.*s\n", (int)left, p); 1692 } 1693 else 1694 printf("\n"); 1695 printf(" _length %u\n", string_object._length); 1696 printf(" _pad %u\n", string_object._pad); 1697 } 1698} 1699 1700static 1701void 1702get_sections_64( 1703struct load_command *load_commands, 1704uint32_t ncmds, 1705uint32_t sizeofcmds, 1706enum byte_sex object_byte_sex, 1707char *object_addr, 1708uint32_t object_size, 1709struct section_info_64 **sections, 1710uint32_t *nsections, 1711uint64_t *database) 1712{ 1713 enum byte_sex host_byte_sex; 1714 enum bool swapped, database_set, zerobased, encrypt_found, encrypt64_found; 1715 1716 uint32_t i, j, left, size; 1717 struct load_command lcmd, *lc; 1718 char *p; 1719 struct segment_command_64 sg64; 1720 struct section_64 s64; 1721 struct encryption_info_command encrypt; 1722 struct encryption_info_command_64 encrypt64; 1723 1724 host_byte_sex = get_host_byte_sex(); 1725 swapped = host_byte_sex != object_byte_sex; 1726 1727 *sections = NULL; 1728 *nsections = 0; 1729 database_set = FALSE; 1730 *database = 0; 1731 zerobased = FALSE; 1732 encrypt_found = FALSE; 1733 encrypt64_found = FALSE; 1734 1735 lc = load_commands; 1736 for(i = 0 ; i < ncmds; i++){ 1737 memcpy((char *)&lcmd, (char *)lc, sizeof(struct load_command)); 1738 if(swapped) 1739 swap_load_command(&lcmd, host_byte_sex); 1740 if(lcmd.cmdsize % sizeof(int32_t) != 0) 1741 printf("load command %u size not a multiple of " 1742 "sizeof(int32_t)\n", i); 1743 if((char *)lc + lcmd.cmdsize > 1744 (char *)load_commands + sizeofcmds) 1745 printf("load command %u extends past end of load " 1746 "commands\n", i); 1747 left = sizeofcmds - ((char *)lc - (char *)load_commands); 1748 1749 switch(lcmd.cmd){ 1750 case LC_SEGMENT_64: 1751 memset((char *)&sg64, '\0', sizeof(struct segment_command_64)); 1752 size = left < sizeof(struct segment_command_64) ? 1753 left : sizeof(struct segment_command_64); 1754 memcpy((char *)&sg64, (char *)lc, size); 1755 if(swapped) 1756 swap_segment_command_64(&sg64, host_byte_sex); 1757 if((sg64.initprot & VM_PROT_WRITE) == VM_PROT_WRITE && 1758 database_set == FALSE){ 1759 *database = sg64.vmaddr; 1760 database_set = TRUE; 1761 } 1762 if((sg64.initprot & VM_PROT_READ) == VM_PROT_READ && 1763 sg64.vmaddr == 0) 1764 zerobased = TRUE; 1765 p = (char *)lc + sizeof(struct segment_command_64); 1766 for(j = 0 ; j < sg64.nsects ; j++){ 1767 if(p + sizeof(struct section_64) > 1768 (char *)load_commands + sizeofcmds){ 1769 printf("section structure command extends past " 1770 "end of load commands\n"); 1771 } 1772 left = sizeofcmds - (p - (char *)load_commands); 1773 memset((char *)&s64, '\0', sizeof(struct section_64)); 1774 size = left < sizeof(struct section_64) ? 1775 left : sizeof(struct section_64); 1776 memcpy((char *)&s64, p, size); 1777 if(swapped) 1778 swap_section_64(&s64, 1, host_byte_sex); 1779 1780 *sections = reallocate(*sections, 1781 sizeof(struct section_info_64) * (*nsections + 1)); 1782 memcpy((*sections)[*nsections].segname, 1783 s64.segname, 16); 1784 memcpy((*sections)[*nsections].sectname, 1785 s64.sectname, 16); 1786 (*sections)[*nsections].addr = s64.addr; 1787 (*sections)[*nsections].contents = object_addr + s64.offset; 1788 (*sections)[*nsections].offset = s64.offset; 1789 (*sections)[*nsections].zerofill = 1790 (s64.flags & SECTION_TYPE) == S_ZEROFILL ? TRUE : FALSE; 1791 if(s64.offset > object_size){ 1792 printf("section contents of: (%.16s,%.16s) is past " 1793 "end of file\n", s64.segname, s64.sectname); 1794 (*sections)[*nsections].size = 0; 1795 } 1796 else if(s64.offset + s64.size > object_size){ 1797 printf("part of section contents of: (%.16s,%.16s) " 1798 "is past end of file\n", 1799 s64.segname, s64.sectname); 1800 (*sections)[*nsections].size = object_size - s64.offset; 1801 } 1802 else 1803 (*sections)[*nsections].size = s64.size; 1804 if(s64.reloff >= object_size){ 1805 printf("relocation entries offset for (%.16s,%.16s)" 1806 ": is past end of file\n", s64.segname, 1807 s64.sectname); 1808 (*sections)[*nsections].nrelocs = 0; 1809 } 1810 else{ 1811 (*sections)[*nsections].relocs = 1812 (struct relocation_info *)(object_addr + 1813 s64.reloff); 1814 if(s64.reloff + 1815 s64.nreloc * sizeof(struct relocation_info) > 1816 object_size){ 1817 printf("relocation entries for section (%.16s," 1818 "%.16s) extends past end of file\n", 1819 s64.segname, s64.sectname); 1820 (*sections)[*nsections].nrelocs = 1821 (object_size - s64.reloff) / 1822 sizeof(struct relocation_info); 1823 } 1824 else 1825 (*sections)[*nsections].nrelocs = s64.nreloc; 1826 if(swapped) 1827 swap_relocation_info( 1828 (*sections)[*nsections].relocs, 1829 (*sections)[*nsections].nrelocs, 1830 host_byte_sex); 1831 } 1832 if(sg64.flags & SG_PROTECTED_VERSION_1) 1833 (*sections)[*nsections].protected = TRUE; 1834 else 1835 (*sections)[*nsections].protected = FALSE; 1836 if((s64.flags & SECTION_TYPE) == S_CSTRING_LITERALS) 1837 (*sections)[*nsections].cstring = TRUE; 1838 else 1839 (*sections)[*nsections].cstring = FALSE; 1840 (*nsections)++; 1841 1842 if(p + sizeof(struct section_64) > 1843 (char *)load_commands + sizeofcmds) 1844 break; 1845 p += size; 1846 } 1847 break; 1848 case LC_ENCRYPTION_INFO: 1849 memset((char *)&encrypt, '\0', 1850 sizeof(struct encryption_info_command)); 1851 size = left < sizeof(struct encryption_info_command) ? 1852 left : sizeof(struct encryption_info_command); 1853 memcpy((char *)&encrypt, (char *)lc, size); 1854 if(swapped) 1855 swap_encryption_command(&encrypt, host_byte_sex); 1856 encrypt_found = TRUE; 1857 break; 1858 case LC_ENCRYPTION_INFO_64: 1859 memset((char *)&encrypt64, '\0', 1860 sizeof(struct encryption_info_command_64)); 1861 size = left < sizeof(struct encryption_info_command_64) ? 1862 left : sizeof(struct encryption_info_command_64); 1863 memcpy((char *)&encrypt64, (char *)lc, size); 1864 if(swapped) 1865 swap_encryption_command_64(&encrypt64, host_byte_sex); 1866 encrypt64_found = TRUE; 1867 break; 1868 } 1869 if(lcmd.cmdsize == 0){ 1870 printf("load command %u size zero (can't advance to other " 1871 "load commands)\n", i); 1872 break; 1873 } 1874 lc = (struct load_command *)((char *)lc + lcmd.cmdsize); 1875 if((char *)lc > (char *)load_commands + sizeofcmds) 1876 break; 1877 } 1878 1879 if(encrypt_found == TRUE && encrypt.cryptid != 0){ 1880 for(i = 0; i < *nsections; i++){ 1881 if((*sections)[i].size > 0 && (*sections)[i].zerofill == FALSE){ 1882 if((*sections)[i].offset > 1883 encrypt.cryptoff + encrypt.cryptsize){ 1884 /* section starts past encryption area */ ; 1885 } 1886 else if((*sections)[i].offset + (*sections)[i].size < 1887 encrypt.cryptoff){ 1888 /* section ends before encryption area */ ; 1889 } 1890 else{ 1891 /* section has part in the encrypted area */ 1892 (*sections)[i].protected = TRUE; 1893 } 1894 } 1895 } 1896 } 1897 if(encrypt64_found == TRUE && encrypt64.cryptid != 0){ 1898 for(i = 0; i < *nsections; i++){ 1899 if((*sections)[i].size > 0 && (*sections)[i].zerofill == FALSE){ 1900 if((*sections)[i].offset > 1901 encrypt64.cryptoff + encrypt64.cryptsize){ 1902 /* section starts past encryption area */ ; 1903 } 1904 else if((*sections)[i].offset + (*sections)[i].size < 1905 encrypt64.cryptoff){ 1906 /* section ends before encryption area */ ; 1907 } 1908 else{ 1909 /* section has part in the encrypted area */ 1910 (*sections)[i].protected = TRUE; 1911 } 1912 } 1913 } 1914 } 1915} 1916 1917static 1918struct section_info_64 * 1919get_section_64( 1920struct section_info_64 *sections, 1921uint32_t nsections, 1922char *segname, 1923char *sectname) 1924{ 1925 uint32_t i; 1926 1927 for(i = 0; i < nsections; i++){ 1928 if(strncmp(sections[i].segname, segname, 16) == 0 && 1929 strncmp(sections[i].sectname, sectname, 16) == 0){ 1930 return(sections + i); 1931 } 1932 } 1933 return(NULL); 1934} 1935 1936static 1937void 1938get_cstring_section_64( 1939struct load_command *load_commands, 1940uint32_t ncmds, 1941uint32_t sizeofcmds, 1942enum byte_sex object_byte_sex, 1943char *object_addr, 1944uint32_t object_size, 1945struct section_info_64 *cstring_section) 1946{ 1947 enum byte_sex host_byte_sex; 1948 enum bool swapped; 1949 1950 uint32_t i, j, left, size; 1951 struct load_command lcmd, *lc; 1952 char *p; 1953 struct segment_command_64 sg64; 1954 struct section_64 s64; 1955 1956 host_byte_sex = get_host_byte_sex(); 1957 swapped = host_byte_sex != object_byte_sex; 1958 1959 memset(cstring_section, '\0', sizeof(struct section_info_64)); 1960 1961 lc = load_commands; 1962 for(i = 0 ; i < ncmds; i++){ 1963 memcpy((char *)&lcmd, (char *)lc, sizeof(struct load_command)); 1964 if(swapped) 1965 swap_load_command(&lcmd, host_byte_sex); 1966 if(lcmd.cmdsize % sizeof(int32_t) != 0) 1967 printf("load command %u size not a multiple of " 1968 "sizeof(int32_t)\n", i); 1969 if((char *)lc + lcmd.cmdsize > 1970 (char *)load_commands + sizeofcmds) 1971 printf("load command %u extends past end of load " 1972 "commands\n", i); 1973 left = sizeofcmds - ((char *)lc - (char *)load_commands); 1974 1975 switch(lcmd.cmd){ 1976 case LC_SEGMENT_64: 1977 memset((char *)&sg64, '\0', sizeof(struct segment_command_64)); 1978 size = left < sizeof(struct segment_command_64) ? 1979 left : sizeof(struct segment_command_64); 1980 memcpy((char *)&sg64, (char *)lc, size); 1981 if(swapped) 1982 swap_segment_command_64(&sg64, host_byte_sex); 1983 1984 p = (char *)lc + sizeof(struct segment_command_64); 1985 for(j = 0 ; j < sg64.nsects ; j++){ 1986 if(p + sizeof(struct section_64) > 1987 (char *)load_commands + sizeofcmds){ 1988 printf("section structure command extends past " 1989 "end of load commands\n"); 1990 } 1991 left = sizeofcmds - (p - (char *)load_commands); 1992 memset((char *)&s64, '\0', sizeof(struct section_64)); 1993 size = left < sizeof(struct section_64) ? 1994 left : sizeof(struct section_64); 1995 memcpy((char *)&s64, p, size); 1996 if(swapped) 1997 swap_section_64(&s64, 1, host_byte_sex); 1998 1999 if(strcmp(s64.segname, SEG_TEXT) == 0 && 2000 strcmp(s64.sectname, "__cstring") == 0){ 2001 cstring_section->addr = s64.addr; 2002 cstring_section->contents = object_addr + s64.offset; 2003 if(s64.offset > object_size){ 2004 printf("section contents of: (%.16s,%.16s) is past " 2005 "end of file\n", s64.segname, s64.sectname); 2006 cstring_section->size = 0; 2007 } 2008 else if(s64.offset + s64.size > object_size){ 2009 printf("part of section contents of: (%.16s,%.16s) " 2010 "is past end of file\n", 2011 s64.segname, s64.sectname); 2012 cstring_section->size = object_size - s64.offset; 2013 } 2014 else 2015 cstring_section->size = s64.size; 2016 if(sg64.flags & SG_PROTECTED_VERSION_1) 2017 cstring_section->protected = TRUE; 2018 else 2019 cstring_section->protected = FALSE; 2020 cstring_section->cstring = TRUE; 2021 return; 2022 } 2023 2024 if(p + sizeof(struct section) > 2025 (char *)load_commands + sizeofcmds) 2026 break; 2027 p += size; 2028 } 2029 break; 2030 } 2031 if(lcmd.cmdsize == 0){ 2032 printf("load command %u size zero (can't advance to other " 2033 "load commands)\n", i); 2034 break; 2035 } 2036 lc = (struct load_command *)((char *)lc + lcmd.cmdsize); 2037 if((char *)lc > (char *)load_commands + sizeofcmds) 2038 break; 2039 } 2040} 2041 2042static 2043void * 2044get_pointer_64( 2045uint64_t p, 2046uint32_t *offset, 2047uint32_t *left, 2048struct section_info_64 **s, 2049struct section_info_64 *sections, 2050uint32_t nsections) 2051{ 2052 void *r; 2053 uint64_t addr; 2054 uint32_t i; 2055 2056 addr = p; 2057 for(i = 0; i < nsections; i++){ 2058 if(addr >= sections[i].addr && 2059 addr < sections[i].addr + sections[i].size){ 2060 if(s != NULL) 2061 *s = sections + i; 2062 if(offset != NULL) 2063 *offset = addr - sections[i].addr; 2064 if(left != NULL) 2065 *left = sections[i].size - (addr - sections[i].addr); 2066 if(sections[i].protected == TRUE && sections[i].cstring == TRUE) 2067 r = "some string from a protected section"; 2068 else 2069 r = sections[i].contents + (addr - sections[i].addr); 2070 return(r); 2071 } 2072 } 2073 if(s != NULL) 2074 *s = NULL; 2075 if(offset != NULL) 2076 *offset = 0; 2077 if(left != NULL) 2078 *left = 0; 2079 return(NULL); 2080} 2081 2082/* 2083 * get_symbol() returns the name of a symbol (or NULL). Based on the relocation 2084 * information at the specified section offset or the value. 2085 */ 2086static 2087const char * 2088get_symbol_64( 2089uint32_t sect_offset, 2090uint64_t database_offset, 2091uint64_t value, 2092struct relocation_info *relocs, 2093uint32_t nrelocs, 2094struct info *info, 2095uint64_t *n_value) 2096{ 2097 uint32_t i; 2098 unsigned int r_symbolnum; 2099 uint32_t n_strx; 2100 2101 if(info->verbose == FALSE) 2102 return(NULL); 2103 2104 for(i = 0; i < nrelocs; i++){ 2105 if((uint32_t)relocs[i].r_address == sect_offset){ 2106 r_symbolnum = relocs[i].r_symbolnum; 2107 if(relocs[i].r_extern){ 2108 if(r_symbolnum >= info->nsymbols) 2109 break; 2110 n_strx = info->symbols64[r_symbolnum].n_un.n_strx; 2111 if(n_strx <= 0 || n_strx >= info->strings_size) 2112 break; 2113 if(n_value != NULL) 2114 *n_value = info->symbols64[r_symbolnum].n_value; 2115 return(info->strings + n_strx); 2116 } 2117 break; 2118 } 2119 if(reloc_has_pair(info->cputype, relocs[i].r_type) == TRUE) 2120 i++; 2121 } 2122 for(i = 0; i < info->next_relocs; i++){ 2123 if((uint32_t)info->ext_relocs[i].r_address == 2124 database_offset + sect_offset){ 2125 r_symbolnum = info->ext_relocs[i].r_symbolnum; 2126 if(info->ext_relocs[i].r_extern){ 2127 if(r_symbolnum >= info->nsymbols) 2128 break; 2129 n_strx = info->symbols64[r_symbolnum].n_un.n_strx; 2130 if(n_strx <= 0 || n_strx >= info->strings_size) 2131 break; 2132 if(n_value != NULL) 2133 *n_value = info->symbols64[r_symbolnum].n_value; 2134 return(info->strings + n_strx); 2135 } 2136 break; 2137 } 2138 if(reloc_has_pair(info->cputype, info->ext_relocs[i].r_type) ==TRUE) 2139 i++; 2140 } 2141 if(n_value != NULL) 2142 *n_value = 0; 2143 if(value == 0) 2144 return(NULL); 2145 return(guess_symbol(value, info->sorted_symbols, info->nsorted_symbols, 2146 info->verbose)); 2147} 2148