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 * 32-bit Objective-C 2 meta data structures. 46 * 47 * The real structure definitions come from the objc4 project in the private 48 * header file runtime/objc-runtime-new.h in that project. 49 */ 50 51struct class_t { 52 uint32_t isa; /* class_t * (32-bit pointer) */ 53 uint32_t superclass; /* class_t * (32-bit pointer) */ 54 uint32_t cache; /* Cache (32-bit pointer) */ 55 uint32_t vtable; /* IMP * (32-bit pointer) */ 56 uint32_t data; /* class_ro_t * (32-bit pointer) */ 57}; 58 59static 60void 61swap_class_t( 62struct class_t *c, 63enum byte_sex target_byte_sex) 64{ 65 c->isa = SWAP_INT(c->isa); 66 c->superclass = SWAP_INT(c->superclass); 67 c->cache = SWAP_INT(c->cache); 68 c->vtable = SWAP_INT(c->vtable); 69 c->data = SWAP_INT(c->data); 70} 71 72struct class_ro_t { 73 uint32_t flags; 74 uint32_t instanceStart; 75 uint32_t instanceSize; 76 uint32_t ivarLayout; /* const uint8_t * (32-bit pointer) */ 77 uint32_t name; /* const char * (32-bit pointer) */ 78 uint32_t baseMethods; /* const method_list_t * (32-bit pointer) */ 79 uint32_t baseProtocols; /* const protocol_list_t * (32-bit pointer) */ 80 uint32_t ivars; /* const ivar_list_t * (32-bit pointer) */ 81 uint32_t weakIvarLayout; /* const uint8_t * (32-bit pointer) */ 82 uint32_t baseProperties; /* const struct objc_property_list * 83 (32-bit pointer) */ 84}; 85 86/* Values for class_ro_t->flags */ 87#define RO_META (1<<0) 88#define RO_ROOT (1<<1) 89#define RO_HAS_CXX_STRUCTORS (1<<2) 90 91 92static 93void 94swap_class_ro_t( 95struct class_ro_t *cro, 96enum byte_sex target_byte_sex) 97{ 98 cro->flags = SWAP_INT(cro->flags); 99 cro->instanceStart = SWAP_INT(cro->instanceStart); 100 cro->instanceSize = SWAP_INT(cro->instanceSize); 101 cro->ivarLayout = SWAP_INT(cro->ivarLayout); 102 cro->name = SWAP_INT(cro->name); 103 cro->baseMethods = SWAP_INT(cro->baseMethods); 104 cro->baseProtocols = SWAP_INT(cro->baseProtocols); 105 cro->ivars = SWAP_INT(cro->ivars); 106 cro->weakIvarLayout = SWAP_INT(cro->weakIvarLayout); 107 cro->baseProperties = SWAP_INT(cro->baseProperties); 108} 109 110struct method_list_t { 111 uint32_t entsize; 112 uint32_t count; 113 /* struct method_t first; These structures follow inline */ 114}; 115 116static 117void 118swap_method_list_t( 119struct method_list_t *ml, 120enum byte_sex target_byte_sex) 121{ 122 ml->entsize = SWAP_INT(ml->entsize); 123 ml->count = SWAP_INT(ml->count); 124} 125 126struct method_t { 127 uint32_t name; /* SEL (32-bit pointer) */ 128 uint32_t types; /* const char * (32-bit pointer) */ 129 uint32_t imp; /* IMP (32-bit pointer) */ 130}; 131 132static 133void 134swap_method_t( 135struct method_t *m, 136enum byte_sex target_byte_sex) 137{ 138 m->name = SWAP_INT(m->name); 139 m->types = SWAP_INT(m->types); 140 m->imp = SWAP_INT(m->imp); 141} 142 143struct ivar_list_t { 144 uint32_t entsize; 145 uint32_t count; 146 /* struct ivar_t first; These structures follow inline */ 147}; 148 149static 150void 151swap_ivar_list_t( 152struct ivar_list_t *il, 153enum byte_sex target_byte_sex) 154{ 155 il->entsize = SWAP_INT(il->entsize); 156 il->count = SWAP_INT(il->count); 157} 158 159struct ivar_t { 160 uint32_t offset; /* uintptr_t * (32-bit pointer) */ 161 uint32_t name; /* const char * (32-bit pointer) */ 162 uint32_t type; /* const char * (32-bit pointer) */ 163 uint32_t alignment; 164 uint32_t size; 165}; 166 167static 168void 169swap_ivar_t( 170struct ivar_t *i, 171enum byte_sex target_byte_sex) 172{ 173 i->offset = SWAP_INT(i->offset); 174 i->name = SWAP_INT(i->name); 175 i->type = SWAP_INT(i->type); 176 i->alignment = SWAP_INT(i->alignment); 177 i->size = SWAP_INT(i->size); 178} 179 180struct protocol_list_t { 181 uint32_t count; /* uintptr_t (a 32-bit value) */ 182 /* struct protocol_t * list[0]; These pointers follow inline */ 183}; 184 185static 186void 187swap_protocol_list_t( 188struct protocol_list_t *pl, 189enum byte_sex target_byte_sex) 190{ 191 pl->count = SWAP_INT(pl->count); 192} 193 194struct protocol_t { 195 uint32_t isa; /* id * (32-bit pointer) */ 196 uint32_t name; /* const char * (32-bit pointer) */ 197 uint32_t protocols; /* struct protocol_list_t * 198 (32-bit pointer) */ 199 uint32_t instanceMethods; /* method_list_t * (32-bit pointer) */ 200 uint32_t classMethods; /* method_list_t * (32-bit pointer) */ 201 uint32_t optionalInstanceMethods; /* method_list_t * (32-bit pointer) */ 202 uint32_t optionalClassMethods; /* method_list_t * (32-bit pointer) */ 203 uint32_t instanceProperties; /* struct objc_property_list * 204 (32-bit pointer) */ 205}; 206 207static 208void 209swap_protocol_t( 210struct protocol_t *p, 211enum byte_sex target_byte_sex) 212{ 213 p->isa = SWAP_INT(p->isa); 214 p->name = SWAP_INT(p->name); 215 p->protocols = SWAP_INT(p->protocols); 216 p->instanceMethods = SWAP_INT(p->instanceMethods); 217 p->classMethods = SWAP_INT(p->classMethods); 218 p->optionalInstanceMethods = SWAP_INT(p->optionalInstanceMethods); 219 p->optionalClassMethods = SWAP_INT(p->optionalClassMethods); 220 p->instanceProperties = SWAP_INT(p->instanceProperties); 221} 222 223struct objc_property_list { 224 uint32_t entsize; 225 uint32_t count; 226 /* struct objc_property first; These structures follow inline */ 227}; 228 229static 230void 231swap_objc_property_list( 232struct objc_property_list *pl, 233enum byte_sex target_byte_sex) 234{ 235 pl->entsize = SWAP_INT(pl->entsize); 236 pl->count = SWAP_INT(pl->count); 237} 238 239struct objc_property { 240 uint32_t name; /* const char * (32-bit pointer) */ 241 uint32_t attributes; /* const char * (32-bit pointer) */ 242}; 243 244static 245void 246swap_objc_property( 247struct objc_property *op, 248enum byte_sex target_byte_sex) 249{ 250 op->name = SWAP_INT(op->name); 251 op->attributes = SWAP_INT(op->attributes); 252} 253 254struct category_t { 255 uint32_t name; /* const char * (32-bit pointer) */ 256 uint32_t cls; /* struct class_t * (32-bit pointer) */ 257 uint32_t instanceMethods; /* struct method_list_t * (32-bit pointer) */ 258 uint32_t classMethods; /* struct method_list_t * (32-bit pointer) */ 259 uint32_t protocols; /* struct protocol_list_t * (32-bit pointer) */ 260 uint32_t instanceProperties; /* struct objc_property_list * 261 (32-bit pointer) */ 262}; 263 264static 265void 266swap_category_t( 267struct category_t *c, 268enum byte_sex target_byte_sex) 269{ 270 c->name = SWAP_INT(c->name); 271 c->cls = SWAP_INT(c->cls); 272 c->instanceMethods = SWAP_INT(c->instanceMethods); 273 c->classMethods = SWAP_INT(c->classMethods); 274 c->protocols = SWAP_INT(c->protocols); 275 c->instanceProperties = SWAP_INT(c->instanceProperties); 276} 277 278struct message_ref { 279 uint32_t imp; /* IMP (32-bit pointer) */ 280 uint32_t sel; /* SEL (32-bit pointer) */ 281}; 282 283static 284void 285swap_message_ref( 286struct message_ref *mr, 287enum byte_sex target_byte_sex) 288{ 289 mr->imp = SWAP_INT(mr->imp); 290 mr->sel = SWAP_INT(mr->sel); 291} 292 293struct objc_image_info { 294 uint32_t version; 295 uint32_t flags; 296}; 297/* masks for objc_image_info.flags */ 298#define OBJC_IMAGE_IS_REPLACEMENT (1<<0) 299#define OBJC_IMAGE_SUPPORTS_GC (1<<1) 300 301 302static 303void 304swap_objc_image_info( 305struct objc_image_info *o, 306enum byte_sex target_byte_sex) 307{ 308 o->version = SWAP_INT(o->version); 309 o->flags = SWAP_INT(o->flags); 310} 311 312struct info { 313 enum bool swapped; 314 enum byte_sex host_byte_sex; 315 struct section_info_32 *sections; 316 uint32_t nsections; 317 cpu_type_t cputype; 318 struct nlist *symbols; 319 uint32_t nsymbols; 320 char *strings; 321 uint32_t strings_size; 322 struct symbol *sorted_symbols; 323 uint32_t nsorted_symbols; 324 uint32_t database; 325 struct relocation_info *ext_relocs; 326 uint32_t next_relocs; 327 struct relocation_info *loc_relocs; 328 uint32_t nloc_relocs; 329 enum bool verbose; 330}; 331 332struct section_info_32 { 333 char segname[16]; 334 char sectname[16]; 335 char *contents; 336 uint32_t addr; 337 uint32_t size; 338 uint32_t offset; 339 struct relocation_info *relocs; 340 uint32_t nrelocs; 341 enum bool protected; 342 enum bool zerofill; 343}; 344 345static void walk_pointer_list( 346 char *listname, 347 struct section_info_32 *s, 348 struct info *info, 349 void (*func)(uint32_t, struct info *)); 350 351static void print_class_t( 352 uint32_t p, 353 struct info *info); 354 355static void print_class_ro_t( 356 uint32_t p, 357 struct info *info, 358 enum bool *is_meta_class); 359 360static void print_layout_map( 361 uint32_t p, 362 struct info *info); 363 364static void print_method_list_t( 365 uint32_t p, 366 struct info *info, 367 char *indent); 368 369static void print_ivar_list_t( 370 uint32_t p, 371 struct info *info); 372 373static void print_protocol_list_t( 374 uint32_t p, 375 struct info *info); 376 377static void print_objc_property_list( 378 uint32_t p, 379 struct info *info); 380 381static void print_category_t( 382 uint32_t p, 383 struct info *info); 384 385static void print_message_refs( 386 struct section_info_32 *s, 387 struct info *info); 388 389static void print_image_info( 390 struct section_info_32 *s, 391 struct info *info); 392 393static void get_sections_32( 394 struct load_command *load_commands, 395 uint32_t ncmds, 396 uint32_t sizeofcmds, 397 enum byte_sex object_byte_sex, 398 char *object_addr, 399 uint32_t object_size, 400 struct section_info_32 **sections, 401 uint32_t *nsections, 402 uint32_t *database); 403 404static struct section_info_32 *get_section_32( 405 struct section_info_32 *sections, 406 uint32_t nsections, 407 char *segname, 408 char *sectname); 409 410static void *get_pointer_32( 411 uint32_t p, 412 uint32_t *offset, 413 uint32_t *left, 414 struct section_info_32 **s, 415 struct section_info_32 *sections, 416 uint32_t nsections); 417 418static const char *get_symbol_32( 419 uint32_t sect_offset, 420 uint32_t database_offset, 421 uint64_t value, 422 struct relocation_info *relocs, 423 uint32_t nrelocs, 424 struct info *info); 425 426/* 427 * Print the objc2 meta data in 32-bit Mach-O files. 428 */ 429void 430print_objc2_32bit( 431cpu_type_t cputype, 432struct load_command *load_commands, 433uint32_t ncmds, 434uint32_t sizeofcmds, 435enum byte_sex object_byte_sex, 436char *object_addr, 437uint32_t object_size, 438struct nlist *symbols, 439uint32_t nsymbols, 440char *strings, 441uint32_t strings_size, 442struct symbol *sorted_symbols, 443uint32_t nsorted_symbols, 444struct relocation_info *ext_relocs, 445uint32_t next_relocs, 446struct relocation_info *loc_relocs, 447uint32_t nloc_relocs, 448enum bool verbose) 449{ 450 struct section_info_32 *s; 451 struct info info; 452 453 info.host_byte_sex = get_host_byte_sex(); 454 info.swapped = info.host_byte_sex != object_byte_sex; 455 info.cputype = cputype; 456 info.symbols = symbols; 457 info.nsymbols = nsymbols; 458 info.strings = strings; 459 info.strings_size = strings_size; 460 info.sorted_symbols = sorted_symbols; 461 info.nsorted_symbols = nsorted_symbols; 462 info.ext_relocs = ext_relocs; 463 info.next_relocs = next_relocs; 464 info.loc_relocs = loc_relocs; 465 info.nloc_relocs = nloc_relocs; 466 info.verbose = verbose; 467 get_sections_32(load_commands, ncmds, sizeofcmds, object_byte_sex, 468 object_addr, object_size, &info.sections, 469 &info.nsections, &info.database); 470 471 s = get_section_32(info.sections, info.nsections, 472 "__OBJC2", "__class_list"); 473 if(s == NULL) 474 s = get_section_32(info.sections, info.nsections, 475 "__DATA", "__objc_classlist"); 476 walk_pointer_list("class", s, &info, print_class_t); 477 478 s = get_section_32(info.sections, info.nsections, 479 "__OBJC2", "__class_refs"); 480 if(s == NULL) 481 s = get_section_32(info.sections, info.nsections, 482 "__DATA", "__objc_classrefs"); 483 walk_pointer_list("class refs", s, &info, NULL); 484 485 s = get_section_32(info.sections, info.nsections, 486 "__OBJC2", "__super_refs"); 487 if(s == NULL) 488 s = get_section_32(info.sections, info.nsections, 489 "__DATA", "__objc_superrefs"); 490 walk_pointer_list("super refs", s, &info, NULL); 491 492 s = get_section_32(info.sections, info.nsections, 493 "__OBJC2", "__category_list"); 494 if(s == NULL) 495 s = get_section_32(info.sections, info.nsections, 496 "__DATA", "__objc_catlist"); 497 walk_pointer_list("category", s, &info, print_category_t); 498 499 s = get_section_32(info.sections, info.nsections, 500 "__OBJC2", "__protocol_list"); 501 if(s == NULL) 502 s = get_section_32(info.sections, info.nsections, 503 "__DATA", "__objc_protolist"); 504 walk_pointer_list("protocol", s, &info, NULL); 505 506 s = get_section_32(info.sections, info.nsections, 507 "__OBJC2", "__message_refs"); 508 if(s == NULL) 509 s = get_section_32(info.sections, info.nsections, 510 "__DATA", "__objc_msgrefs"); 511 print_message_refs(s, &info); 512 513 s = get_section_32(info.sections, info.nsections, 514 "__OBJC", "__image_info"); 515 if(s == NULL) 516 s = get_section_32(info.sections, info.nsections, 517 "__DATA", "__objc_imageinfo"); 518 print_image_info(s, &info); 519} 520 521static 522void 523walk_pointer_list( 524char *listname, 525struct section_info_32 *s, 526struct info *info, 527void (*func)(uint32_t, struct info *)) 528{ 529 uint32_t i, size, left; 530 uint32_t p; 531 const char *name; 532 533 if(s == NULL) 534 return; 535 536 printf("Contents of (%.16s,%.16s) section\n", s->segname, s->sectname); 537 for(i = 0; i < s->size; i += sizeof(uint32_t)){ 538 539 memset(&p, '\0', sizeof(uint32_t)); 540 left = s->size - i; 541 size = left < sizeof(uint32_t) ? 542 left : sizeof(uint32_t); 543 memcpy(&p, s->contents + i, size); 544 545 if(i + sizeof(uint32_t) > s->size) 546 printf("%s list pointer extends past end of (%.16s,%.16s) " 547 "section\n", listname, s->segname, s->sectname); 548 printf("%08x ", s->addr + i); 549 550 if(info->swapped) 551 p = SWAP_INT(p); 552 printf("0x%x", p); 553 554 name = get_symbol_32(i, s->addr - info->database, p, 555 s->relocs, s->nrelocs, info); 556 if(name != NULL) 557 printf(" %s\n", name); 558 else 559 printf("\n"); 560 if(func != NULL) 561 func(p, info); 562 } 563} 564 565static 566void 567print_class_t( 568uint32_t p, 569struct info *info) 570{ 571 struct class_t c; 572 void *r; 573 uint32_t offset, left; 574 struct section_info_32 *s; 575 const char *name; 576 enum bool is_meta_class; 577 578 is_meta_class = FALSE; 579 r = get_pointer_32(p, &offset, &left, &s, 580 info->sections, info->nsections); 581 if(r == NULL) 582 return; 583 memset(&c, '\0', sizeof(struct class_t)); 584 if(left < sizeof(struct class_t)){ 585 memcpy(&c, r, left); 586 printf(" (class_t entends past the end of the section)\n"); 587 } 588 else 589 memcpy(&c, r, sizeof(struct class_t)); 590 if(info->swapped) 591 swap_class_t(&c, info->host_byte_sex); 592 printf(" isa 0x%x", c.isa); 593 name = get_symbol_32(offset + offsetof(struct class_t, isa), 594 s->addr - info->database, c.isa, s->relocs, 595 s->nrelocs, info); 596 if(name != NULL) 597 printf(" %s\n", name); 598 else 599 printf("\n"); 600 printf(" superclass 0x%x", c.superclass); 601 name = get_symbol_32(offset + offsetof(struct class_t, superclass), 602 s->addr - info->database, c.superclass, s->relocs, 603 s->nrelocs, info); 604 if(name != NULL) 605 printf(" %s\n", name); 606 else 607 printf("\n"); 608 printf(" cache 0x%x", c.cache); 609 name = get_symbol_32(offset + offsetof(struct class_t, cache), 610 s->addr - info->database, c.cache, s->relocs, 611 s->nrelocs, info); 612 if(name != NULL) 613 printf(" %s\n", name); 614 else 615 printf("\n"); 616 printf(" vtable 0x%x", c.vtable); 617 name = get_symbol_32(offset + offsetof(struct class_t, vtable), 618 s->addr - info->database, c.vtable, s->relocs, 619 s->nrelocs, info); 620 if(name != NULL) 621 printf(" %s\n", name); 622 else 623 printf("\n"); 624 printf(" data 0x%x (struct class_ro_t *)\n", c.data); 625 print_class_ro_t(c.data, info, &is_meta_class); 626 627 if(! is_meta_class) 628 { 629 printf("Meta Class\n"); 630 print_class_t(c.isa, info); 631 } 632} 633 634static 635void 636print_class_ro_t( 637uint32_t p, 638struct info *info, 639enum bool *is_meta_class) 640{ 641 struct class_ro_t cro; 642 void *r; 643 uint32_t offset, left; 644 struct section_info_32 *s; 645 const char *name; 646 647 r = get_pointer_32(p, &offset, &left, &s, info->sections, 648 info->nsections); 649 if(r == NULL) 650 return; 651 memset(&cro, '\0', sizeof(struct class_ro_t)); 652 if(left < sizeof(struct class_ro_t)){ 653 memcpy(&cro, r, left); 654 printf(" (class_ro_t entends past the end of the section)\n"); 655 } 656 else 657 memcpy(&cro, r, sizeof(struct class_ro_t)); 658 if(info->swapped) 659 swap_class_ro_t(&cro, info->host_byte_sex); 660 printf(" flags 0x%x", cro.flags); 661 if(cro.flags & RO_META) 662 printf(" RO_META"); 663 if(cro.flags & RO_ROOT) 664 printf(" RO_ROOT"); 665 if(cro.flags & RO_HAS_CXX_STRUCTORS) 666 printf(" RO_HAS_CXX_STRUCTORS"); 667 printf("\n"); 668 printf(" instanceStart %u\n", cro.instanceStart); 669 printf(" instanceSize %u\n", cro.instanceSize); 670 printf(" ivarLayout 0x%x\n", cro.ivarLayout); 671 print_layout_map(cro.ivarLayout, info); 672 printf(" name 0x%x", cro.name); 673 name = get_pointer_32(cro.name, NULL, &left, NULL, info->sections, 674 info->nsections); 675 if(name != NULL) 676 printf(" %.*s\n", (int)left, name); 677 else 678 printf("\n"); 679 printf(" baseMethods 0x%x (struct method_list_t *)\n", 680 cro.baseMethods); 681 if(cro.baseMethods != 0) 682 print_method_list_t(cro.baseMethods, info, ""); 683 printf(" baseProtocols 0x%x\n", cro.baseProtocols); 684 if(cro.baseProtocols != 0) 685 print_protocol_list_t(cro.baseProtocols, info); 686 printf(" ivars 0x%x\n", cro.ivars); 687 if(cro.ivars != 0) 688 print_ivar_list_t(cro.ivars, info); 689 printf(" weakIvarLayout 0x%x\n", cro.weakIvarLayout); 690 print_layout_map(cro.weakIvarLayout, info); 691 printf(" baseProperties 0x%x\n", cro.baseProperties); 692 if(cro.baseProperties != 0) 693 print_objc_property_list(cro.baseProperties, info); 694 if (is_meta_class) 695 *is_meta_class = (cro.flags & RO_META) ? TRUE : FALSE; 696} 697 698static 699void 700print_layout_map( 701uint32_t p, 702struct info *info) 703{ 704 uint32_t offset, left; 705 struct section_info_32 *s; 706 char *layout_map; 707 708 if(p == 0) 709 return; 710 layout_map = get_pointer_32(p, &offset, &left, &s, 711 info->sections, info->nsections); 712 if(layout_map != NULL){ 713 printf(" layout map: "); 714 do{ 715 printf("0x%02x ", (*layout_map) & 0xff); 716 left--; 717 layout_map++; 718 }while(*layout_map != '\0' && left != 0); 719 printf("\n"); 720 } 721} 722 723static 724void 725print_method_list_t( 726uint32_t p, 727struct info *info, 728char *indent) 729{ 730 struct method_list_t ml; 731 struct method_t m; 732 void *r; 733 uint32_t offset, left, i; 734 struct section_info_32 *s; 735 const char *name; 736 737 r = get_pointer_32(p, &offset, &left, &s, info->sections, 738 info->nsections); 739 if(r == NULL) 740 return; 741 memset(&ml, '\0', sizeof(struct method_list_t)); 742 if(left < sizeof(struct method_list_t)){ 743 memcpy(&ml, r, left); 744 printf("%s (method_list_t entends past the end of the " 745 "section)\n", indent); 746 } 747 else 748 memcpy(&ml, r, sizeof(struct method_list_t)); 749 if(info->swapped) 750 swap_method_list_t(&ml, info->host_byte_sex); 751 printf("%s\t\t entsize %u\n", indent, ml.entsize); 752 printf("%s\t\t count %u\n", indent, ml.count); 753 754 p += sizeof(struct method_list_t); 755 offset += sizeof(struct method_list_t); 756 for(i = 0; i < ml.count; i++){ 757 r = get_pointer_32(p, &offset, &left, &s, info->sections, 758 info->nsections); 759 if(r == NULL) 760 return; 761 memset(&m, '\0', sizeof(struct method_t)); 762 if(left < sizeof(struct method_t)){ 763 memcpy(&m, r, left); 764 printf("%s (method_t entends past the end of the " 765 "section)\n", indent); 766 } 767 else 768 memcpy(&m, r, sizeof(struct method_t)); 769 if(info->swapped) 770 swap_method_t(&m, info->host_byte_sex); 771 772 printf("%s\t\t name 0x%x", indent, m.name); 773 name = get_pointer_32(m.name, NULL, &left, NULL, info->sections, 774 info->nsections); 775 if(name != NULL) 776 printf(" %.*s\n", (int)left, name); 777 else 778 printf("\n"); 779 printf("%s\t\t types 0x%x", indent, m.types); 780 name = get_pointer_32(m.types, NULL, &left, NULL, info->sections, 781 info->nsections); 782 if(name != NULL) 783 printf(" %.*s\n", (int)left, name); 784 else 785 printf("\n"); 786 printf("%s\t\t imp 0x%x", indent, m.imp); 787 name = get_symbol_32(offset + offsetof(struct method_t, imp), 788 s->addr - info->database, m.imp, s->relocs, 789 s->nrelocs, info); 790 if(name != NULL) 791 printf(" %s\n", name); 792 else 793 printf("\n"); 794 795 p += sizeof(struct method_t); 796 offset += sizeof(struct method_t); 797 } 798} 799 800static 801void 802print_ivar_list_t( 803uint32_t p, 804struct info *info) 805{ 806 struct ivar_list_t il; 807 struct ivar_t i; 808 void *r; 809 uint32_t offset, left, j; 810 struct section_info_32 *s; 811 const char *name; 812 uint32_t *ivar_offset_p, ivar_offset; 813 814 r = get_pointer_32(p, &offset, &left, &s, info->sections, 815 info->nsections); 816 if(r == NULL) 817 return; 818 memset(&il, '\0', sizeof(struct ivar_list_t)); 819 if(left < sizeof(struct ivar_list_t)){ 820 memcpy(&il, r, left); 821 printf(" (ivar_list_t entends past the end of the section)\n"); 822 } 823 else 824 memcpy(&il, r, sizeof(struct ivar_list_t)); 825 if(info->swapped) 826 swap_ivar_list_t(&il, info->host_byte_sex); 827 printf(" entsize %u\n", il.entsize); 828 printf(" count %u\n", il.count); 829 830 p += sizeof(struct ivar_list_t); 831 offset += sizeof(struct ivar_list_t); 832 for(j = 0; j < il.count; j++){ 833 r = get_pointer_32(p, &offset, &left, &s, info->sections, 834 info->nsections); 835 if(r == NULL) 836 return; 837 memset(&i, '\0', sizeof(struct ivar_t)); 838 if(left < sizeof(struct ivar_t)){ 839 memcpy(&i, r, left); 840 printf(" (ivar_t entends past the end of the section)\n"); 841 } 842 else 843 memcpy(&i, r, sizeof(struct ivar_t)); 844 if(info->swapped) 845 swap_ivar_t(&i, info->host_byte_sex); 846 847 printf("\t\t\t offset 0x%x", i.offset); 848 ivar_offset_p = get_pointer_32(i.offset, NULL, &left, NULL, 849 info->sections, info->nsections); 850 if(ivar_offset_p != NULL && left >= sizeof(*ivar_offset_p)){ 851 memcpy(&ivar_offset, ivar_offset_p, sizeof(ivar_offset)); 852 if(info->swapped) 853 ivar_offset = SWAP_INT(ivar_offset); 854 printf(" %u\n", ivar_offset); 855 } 856 else 857 printf("\n"); 858 859 printf("\t\t\t name 0x%x", i.name); 860 name = get_pointer_32(i.name, NULL, &left, NULL, info->sections, 861 info->nsections); 862 if(name != NULL) 863 printf(" %.*s\n", (int)left, name); 864 else 865 printf("\n"); 866 printf("\t\t\t type 0x%x", i.type); 867 name = get_pointer_32(i.type, NULL, &left, NULL, info->sections, 868 info->nsections); 869 if(name != NULL) 870 printf(" %.*s\n", (int)left, name); 871 else 872 printf("\n"); 873 printf("\t\t\talignment %u\n", i.alignment); 874 printf("\t\t\t size %u\n", i.size); 875 876 p += sizeof(struct ivar_t); 877 offset += sizeof(struct ivar_t); 878 } 879} 880 881static 882void 883print_protocol_list_t( 884uint32_t p, 885struct info *info) 886{ 887 struct protocol_list_t pl; 888 uint32_t q; 889 struct protocol_t pc; 890 void *r; 891 uint32_t offset, left, i; 892 struct section_info_32 *s; 893 const char *name; 894 895 r = get_pointer_32(p, &offset, &left, &s, info->sections, 896 info->nsections); 897 if(r == NULL) 898 return; 899 memset(&pl, '\0', sizeof(struct protocol_list_t)); 900 if(left < sizeof(struct protocol_list_t)){ 901 memcpy(&pl, r, left); 902 printf(" (protocol_list_t entends past the end of the " 903 "section)\n"); 904 } 905 else 906 memcpy(&pl, r, sizeof(struct protocol_list_t)); 907 if(info->swapped) 908 swap_protocol_list_t(&pl, info->host_byte_sex); 909 printf(" count %u\n", pl.count); 910 911 p += sizeof(struct protocol_list_t); 912 offset += sizeof(struct protocol_list_t); 913 for(i = 0; i < pl.count; i++){ 914 r = get_pointer_32(p, &offset, &left, &s, info->sections, 915 info->nsections); 916 if(r == NULL) 917 return; 918 q = 0; 919 if(left < sizeof(uint32_t)){ 920 memcpy(&q, r, left); 921 printf(" (protocol_t * entends past the end of the " 922 "section)\n"); 923 } 924 else 925 memcpy(&q, r, sizeof(uint32_t)); 926 if(info->swapped) 927 q = SWAP_INT(q); 928 printf("\t\t list[%u] 0x%x (struct protocol_t *)\n", i, q); 929 930 r = get_pointer_32(q, &offset, &left, &s, info->sections, 931 info->nsections); 932 if(r == NULL) 933 return; 934 memset(&pc, '\0', sizeof(struct protocol_t)); 935 if(left < sizeof(struct protocol_t)){ 936 memcpy(&pc, r, left); 937 printf(" (protocol_t entends past the end of the section)\n"); 938 } 939 else 940 memcpy(&pc, r, sizeof(struct protocol_t)); 941 if(info->swapped) 942 swap_protocol_t(&pc, info->host_byte_sex); 943 944 printf("\t\t\t isa 0x%x\n", pc.isa); 945 printf("\t\t\t name 0x%x", pc.name); 946 name = get_pointer_32(pc.name, NULL, &left, NULL, info->sections, 947 info->nsections); 948 if(name != NULL) 949 printf(" %.*s\n", (int)left, name); 950 else 951 printf("\n"); 952 printf("\t\t\tprotocols 0x%x\n", pc.protocols); 953 printf("\t\t instanceMethods 0x%x (struct method_list_t *)\n", 954 pc.instanceMethods); 955 if(pc.instanceMethods != 0) 956 print_method_list_t(pc.instanceMethods, info, "\t"); 957 printf("\t\t classMethods 0x%x (struct method_list_t *)\n", 958 pc.classMethods); 959 if(pc.classMethods != 0) 960 print_method_list_t(pc.classMethods, info, "\t"); 961 printf("\t optionalInstanceMethods 0x%x\n", 962 pc.optionalInstanceMethods); 963 printf("\t optionalClassMethods 0x%x\n", 964 pc.optionalClassMethods); 965 printf("\t instanceProperties 0x%x\n", 966 pc.instanceProperties); 967 968 p += sizeof(uint32_t); 969 offset += sizeof(uint32_t); 970 } 971} 972 973static 974void 975print_objc_property_list( 976uint32_t p, 977struct info *info) 978{ 979 struct objc_property_list opl; 980 struct objc_property op; 981 void *r; 982 uint32_t offset, left, j; 983 struct section_info_32 *s; 984 const char *name; 985 986 r = get_pointer_32(p, &offset, &left, &s, info->sections, 987 info->nsections); 988 if(r == NULL) 989 return; 990 memset(&opl, '\0', sizeof(struct objc_property_list)); 991 if(left < sizeof(struct objc_property_list)){ 992 memcpy(&opl, r, left); 993 printf(" (objc_property_list entends past the end of the " 994 "section)\n"); 995 } 996 else 997 memcpy(&opl, r, sizeof(struct objc_property_list)); 998 if(info->swapped) 999 swap_objc_property_list(&opl, info->host_byte_sex); 1000 printf(" entsize %u\n", opl.entsize); 1001 printf(" count %u\n", opl.count); 1002 1003 p += sizeof(struct objc_property_list); 1004 offset += sizeof(struct objc_property_list); 1005 for(j = 0; j < opl.count; j++){ 1006 r = get_pointer_32(p, &offset, &left, &s, info->sections, 1007 info->nsections); 1008 if(r == NULL) 1009 return; 1010 memset(&op, '\0', sizeof(struct objc_property)); 1011 if(left < sizeof(struct objc_property)){ 1012 memcpy(&op, r, left); 1013 printf(" (objc_property entends past the end of the " 1014 "section)\n"); 1015 } 1016 else 1017 memcpy(&op, r, sizeof(struct objc_property)); 1018 if(info->swapped) 1019 swap_objc_property(&op, info->host_byte_sex); 1020 1021 printf("\t\t\t name 0x%x", op.name); 1022 name = get_pointer_32(op.name, NULL, &left, NULL, info->sections, 1023 info->nsections); 1024 if(name != NULL) 1025 printf(" %.*s\n", (int)left, name); 1026 else 1027 printf("\n"); 1028 printf("\t\t\tattributes x%x", op.attributes); 1029 name = get_pointer_32(op.attributes, NULL, &left, NULL, 1030 info->sections, info->nsections); 1031 if(name != NULL) 1032 printf(" %.*s\n", (int)left, name); 1033 else 1034 printf("\n"); 1035 1036 p += sizeof(struct objc_property); 1037 offset += sizeof(struct objc_property); 1038 } 1039} 1040 1041static 1042void 1043print_category_t( 1044uint32_t p, 1045struct info *info) 1046{ 1047 struct category_t c; 1048 void *r; 1049 uint32_t offset, left; 1050 struct section_info_32 *s; 1051 const char *name; 1052 1053 r = get_pointer_32(p, &offset, &left, &s, 1054 info->sections, info->nsections); 1055 if(r == NULL) 1056 return; 1057 memset(&c, '\0', sizeof(struct category_t)); 1058 if(left < sizeof(struct category_t)){ 1059 memcpy(&c, r, left); 1060 printf(" (category_t entends past the end of the section)\n"); 1061 } 1062 else 1063 memcpy(&c, r, sizeof(struct category_t)); 1064 if(info->swapped) 1065 swap_category_t(&c, info->host_byte_sex); 1066 printf(" name 0x%x", c.name); 1067 name = get_symbol_32(offset + offsetof(struct category_t, name), 1068 s->addr - info->database, c.name, s->relocs, 1069 s->nrelocs, info); 1070 if(name != NULL) 1071 printf(" %s\n", name); 1072 else 1073 printf("\n"); 1074 printf(" cls 0x%x\n", c.cls); 1075 if(c.cls != 0) 1076 print_class_t(c.cls, info); 1077 printf(" instanceMethods 0x%x\n", c.instanceMethods); 1078 if(c.instanceMethods != 0) 1079 print_method_list_t(c.instanceMethods, info, ""); 1080 printf(" classMethods 0x%x\n", c.classMethods); 1081 if(c.classMethods != 0) 1082 print_method_list_t(c.classMethods, info, ""); 1083 printf(" protocols 0x%x\n", c.protocols); 1084 if(c.protocols != 0) 1085 print_protocol_list_t(c.protocols, info); 1086 printf("instanceProperties 0x%x\n", c.instanceProperties); 1087 if(c.instanceProperties) 1088 print_objc_property_list(c.instanceProperties, info); 1089} 1090 1091static 1092void 1093print_message_refs( 1094struct section_info_32 *s, 1095struct info *info) 1096{ 1097 uint32_t i, left, offset; 1098 uint32_t p; 1099 struct message_ref mr; 1100 const char *name; 1101 void *r; 1102 1103 if(s == NULL) 1104 return; 1105 1106 printf("Contents of (%.16s,%.16s) section\n", s->segname, s->sectname); 1107 offset = 0; 1108 for(i = 0; i < s->size; i += sizeof(struct message_ref)){ 1109 p = s->addr + i; 1110 r = get_pointer_32(p, &offset, &left, &s, 1111 info->sections, info->nsections); 1112 if(r == NULL) 1113 return; 1114 memset(&mr, '\0', sizeof(struct message_ref)); 1115 if(left < sizeof(struct message_ref)){ 1116 memcpy(&mr, r, left); 1117 printf(" (message_ref entends past the end of the section)\n"); 1118 } 1119 else 1120 memcpy(&mr, r, sizeof(struct message_ref)); 1121 if(info->swapped) 1122 swap_message_ref(&mr, info->host_byte_sex); 1123 printf(" imp 0x%x", mr.imp); 1124 name = get_symbol_32(offset + offsetof(struct message_ref, imp), 1125 s->addr - info->database, mr.imp, s->relocs, 1126 s->nrelocs, info); 1127 if(name != NULL) 1128 printf(" %s\n", name); 1129 else 1130 printf("\n"); 1131 printf(" sel 0x%x", mr.sel); 1132 name = get_pointer_32(mr.sel, NULL, &left, NULL, info->sections, 1133 info->nsections); 1134 if(name != NULL) 1135 printf(" %.*s\n", (int)left, name); 1136 else 1137 printf("\n"); 1138 offset += sizeof(struct message_ref); 1139 } 1140} 1141 1142static 1143void 1144print_image_info( 1145struct section_info_32 *s, 1146struct info *info) 1147{ 1148 uint32_t left, offset; 1149 uint32_t p; 1150 struct objc_image_info o; 1151 void *r; 1152 1153 if(s == NULL) 1154 return; 1155 1156 printf("Contents of (%.16s,%.16s) section\n", s->segname, s->sectname); 1157 p = s->addr; 1158 r = get_pointer_32(p, &offset, &left, &s, 1159 info->sections, info->nsections); 1160 if(r == NULL) 1161 return; 1162 memset(&o, '\0', sizeof(struct objc_image_info)); 1163 if(left < sizeof(struct objc_image_info)){ 1164 memcpy(&o, r, left); 1165 printf(" (objc_image_info entends past the end of the section)\n"); 1166 } 1167 else 1168 memcpy(&o, r, sizeof(struct objc_image_info)); 1169 if(info->swapped) 1170 swap_objc_image_info(&o, info->host_byte_sex); 1171 printf(" version %u\n", o.version); 1172 printf(" flags 0x%x", o.flags); 1173 if(o.flags & OBJC_IMAGE_IS_REPLACEMENT) 1174 printf(" OBJC_IMAGE_IS_REPLACEMENT"); 1175 if(o.flags & OBJC_IMAGE_SUPPORTS_GC) 1176 printf(" OBJC_IMAGE_SUPPORTS_GC"); 1177 printf("\n"); 1178} 1179 1180static 1181void 1182get_sections_32( 1183struct load_command *load_commands, 1184uint32_t ncmds, 1185uint32_t sizeofcmds, 1186enum byte_sex object_byte_sex, 1187char *object_addr, 1188uint32_t object_size, 1189struct section_info_32 **sections, 1190uint32_t *nsections, 1191uint32_t *database) 1192{ 1193 enum byte_sex host_byte_sex; 1194 enum bool swapped, database_set, zerobased, encrypt_found, encrypt64_found; 1195 1196 uint32_t i, j, left, size; 1197 struct load_command lcmd, *lc; 1198 char *p; 1199 struct segment_command sg; 1200 struct section s; 1201 struct encryption_info_command encrypt; 1202 struct encryption_info_command_64 encrypt64; 1203 1204 host_byte_sex = get_host_byte_sex(); 1205 swapped = host_byte_sex != object_byte_sex; 1206 1207 *sections = NULL; 1208 *nsections = 0; 1209 database_set = FALSE; 1210 *database = 0; 1211 zerobased = FALSE; 1212 encrypt_found = FALSE; 1213 encrypt64_found = FALSE; 1214 1215 lc = load_commands; 1216 for(i = 0 ; i < ncmds; i++){ 1217 memcpy((char *)&lcmd, (char *)lc, sizeof(struct load_command)); 1218 if(swapped) 1219 swap_load_command(&lcmd, host_byte_sex); 1220 if(lcmd.cmdsize % sizeof(int32_t) != 0) 1221 printf("load command %u size not a multiple of " 1222 "sizeof(int32_t)\n", i); 1223 if((char *)lc + lcmd.cmdsize > 1224 (char *)load_commands + sizeofcmds) 1225 printf("load command %u extends past end of load " 1226 "commands\n", i); 1227 left = sizeofcmds - ((char *)lc - (char *)load_commands); 1228 1229 switch(lcmd.cmd){ 1230 case LC_SEGMENT: 1231 memset((char *)&sg, '\0', sizeof(struct segment_command)); 1232 size = left < sizeof(struct segment_command) ? 1233 left : sizeof(struct segment_command); 1234 memcpy((char *)&sg, (char *)lc, size); 1235 if(swapped) 1236 swap_segment_command(&sg, host_byte_sex); 1237 if((sg.initprot & VM_PROT_WRITE) == VM_PROT_WRITE && 1238 database_set == FALSE){ 1239 *database = sg.vmaddr; 1240 database_set = TRUE; 1241 } 1242 if((sg.initprot & VM_PROT_READ) == VM_PROT_READ && 1243 sg.vmaddr == 0) 1244 zerobased = TRUE; 1245 p = (char *)lc + sizeof(struct segment_command); 1246 for(j = 0 ; j < sg.nsects ; j++){ 1247 if(p + sizeof(struct section) > 1248 (char *)load_commands + sizeofcmds){ 1249 printf("section structure command extends past " 1250 "end of load commands\n"); 1251 } 1252 left = sizeofcmds - (p - (char *)load_commands); 1253 memset((char *)&s, '\0', sizeof(struct section)); 1254 size = left < sizeof(struct section) ? 1255 left : sizeof(struct section); 1256 memcpy((char *)&s, p, size); 1257 if(swapped) 1258 swap_section(&s, 1, host_byte_sex); 1259 1260 *sections = reallocate(*sections, 1261 sizeof(struct section_info_32) * (*nsections + 1)); 1262 memcpy((*sections)[*nsections].segname, 1263 s.segname, 16); 1264 memcpy((*sections)[*nsections].sectname, 1265 s.sectname, 16); 1266 (*sections)[*nsections].addr = s.addr; 1267 (*sections)[*nsections].contents = object_addr + s.offset; 1268 (*sections)[*nsections].offset = s.offset; 1269 (*sections)[*nsections].zerofill = (s.flags & SECTION_TYPE) 1270 == S_ZEROFILL ? TRUE : FALSE; 1271 if(s.offset > object_size){ 1272 printf("section contents of: (%.16s,%.16s) is past " 1273 "end of file\n", s.segname, s.sectname); 1274 (*sections)[*nsections].size = 0; 1275 } 1276 else if(s.offset + s.size > object_size){ 1277 printf("part of section contents of: (%.16s,%.16s) " 1278 "is past end of file\n", 1279 s.segname, s.sectname); 1280 (*sections)[*nsections].size = object_size - s.offset; 1281 } 1282 else 1283 (*sections)[*nsections].size = s.size; 1284 if(s.reloff >= object_size){ 1285 printf("relocation entries offset for (%.16s,%.16s)" 1286 ": is past end of file\n", s.segname, 1287 s.sectname); 1288 (*sections)[*nsections].nrelocs = 0; 1289 } 1290 else{ 1291 (*sections)[*nsections].relocs = 1292 (struct relocation_info *)(object_addr + 1293 s.reloff); 1294 if(s.reloff + 1295 s.nreloc * sizeof(struct relocation_info) > 1296 object_size){ 1297 printf("relocation entries for section (%.16s," 1298 "%.16s) extends past end of file\n", 1299 s.segname, s.sectname); 1300 (*sections)[*nsections].nrelocs = 1301 (object_size - s.reloff) / 1302 sizeof(struct relocation_info); 1303 } 1304 else 1305 (*sections)[*nsections].nrelocs = s.nreloc; 1306 if(swapped) 1307 swap_relocation_info( 1308 (*sections)[*nsections].relocs, 1309 (*sections)[*nsections].nrelocs, 1310 host_byte_sex); 1311 } 1312 if(sg.flags & SG_PROTECTED_VERSION_1) 1313 (*sections)[*nsections].protected = TRUE; 1314 else 1315 (*sections)[*nsections].protected = FALSE; 1316 (*nsections)++; 1317 1318 if(p + sizeof(struct section) > 1319 (char *)load_commands + sizeofcmds) 1320 break; 1321 p += size; 1322 } 1323 break; 1324 case LC_ENCRYPTION_INFO: 1325 memset((char *)&encrypt, '\0', 1326 sizeof(struct encryption_info_command)); 1327 size = left < sizeof(struct encryption_info_command) ? 1328 left : sizeof(struct encryption_info_command); 1329 memcpy((char *)&encrypt, (char *)lc, size); 1330 if(swapped) 1331 swap_encryption_command(&encrypt, host_byte_sex); 1332 encrypt_found = TRUE; 1333 break; 1334 case LC_ENCRYPTION_INFO_64: 1335 memset((char *)&encrypt64, '\0', 1336 sizeof(struct encryption_info_command_64)); 1337 size = left < sizeof(struct encryption_info_command_64) ? 1338 left : sizeof(struct encryption_info_command_64); 1339 memcpy((char *)&encrypt64, (char *)lc, size); 1340 if(swapped) 1341 swap_encryption_command_64(&encrypt64, host_byte_sex); 1342 encrypt64_found = TRUE; 1343 break; 1344 } 1345 if(lcmd.cmdsize == 0){ 1346 printf("load command %u size zero (can't advance to other " 1347 "load commands)\n", i); 1348 break; 1349 } 1350 lc = (struct load_command *)((char *)lc + lcmd.cmdsize); 1351 if((char *)lc > (char *)load_commands + sizeofcmds) 1352 break; 1353 } 1354 if(zerobased == TRUE) 1355 *database = 0; 1356 1357 if(encrypt_found == TRUE && encrypt.cryptid != 0){ 1358 for(i = 0; i < *nsections; i++){ 1359 if((*sections)[i].size > 0 && (*sections)[i].zerofill == FALSE){ 1360 if((*sections)[i].offset > 1361 encrypt.cryptoff + encrypt.cryptsize){ 1362 /* section starts past encryption area */ ; 1363 } 1364 else if((*sections)[i].offset + (*sections)[i].size < 1365 encrypt.cryptoff){ 1366 /* section ends before encryption area */ ; 1367 } 1368 else{ 1369 /* section has part in the encrypted area */ 1370 (*sections)[i].protected = TRUE; 1371 } 1372 } 1373 } 1374 } 1375 if(encrypt64_found == TRUE && encrypt64.cryptid != 0){ 1376 for(i = 0; i < *nsections; i++){ 1377 if((*sections)[i].size > 0 && (*sections)[i].zerofill == FALSE){ 1378 if((*sections)[i].offset > 1379 encrypt64.cryptoff + encrypt64.cryptsize){ 1380 /* section starts past encryption area */ ; 1381 } 1382 else if((*sections)[i].offset + (*sections)[i].size < 1383 encrypt64.cryptoff){ 1384 /* section ends before encryption area */ ; 1385 } 1386 else{ 1387 /* section has part in the encrypted area */ 1388 (*sections)[i].protected = TRUE; 1389 } 1390 } 1391 } 1392 } 1393} 1394 1395static 1396struct section_info_32 * 1397get_section_32( 1398struct section_info_32 *sections, 1399uint32_t nsections, 1400char *segname, 1401char *sectname) 1402{ 1403 uint32_t i; 1404 1405 for(i = 0; i < nsections; i++){ 1406 if(strncmp(sections[i].segname, segname, 16) == 0 && 1407 strncmp(sections[i].sectname, sectname, 16) == 0){ 1408 return(sections + i); 1409 } 1410 } 1411 return(NULL); 1412} 1413 1414static 1415void * 1416get_pointer_32( 1417uint32_t p, 1418uint32_t *offset, 1419uint32_t *left, 1420struct section_info_32 **s, 1421struct section_info_32 *sections, 1422uint32_t nsections) 1423{ 1424 void *r; 1425 uint32_t addr; 1426 uint32_t i; 1427 1428 addr = p; 1429 for(i = 0; i < nsections; i++){ 1430 if(addr >= sections[i].addr && 1431 addr < sections[i].addr + sections[i].size){ 1432 if(s != NULL) 1433 *s = sections + i; 1434 if(offset != NULL) 1435 *offset = addr - sections[i].addr; 1436 if(left != NULL) 1437 *left = sections[i].size - (addr - sections[i].addr); 1438 if(sections[i].protected == TRUE) 1439 r = "some string from a protected section"; 1440 else 1441 r = sections[i].contents + (addr - sections[i].addr); 1442 return(r); 1443 } 1444 } 1445 if(s != NULL) 1446 *s = NULL; 1447 if(offset != NULL) 1448 *offset = 0; 1449 if(left != NULL) 1450 *left = 0; 1451 return(NULL); 1452} 1453 1454/* 1455 * get_symbol() returns the name of a symbol (or NULL). Based on the relocation 1456 * information at the specified section offset or the value. 1457 */ 1458static 1459const char * 1460get_symbol_32( 1461uint32_t sect_offset, 1462uint32_t database_offset, 1463uint64_t value, 1464struct relocation_info *relocs, 1465uint32_t nrelocs, 1466struct info *info) 1467{ 1468 uint32_t i; 1469 unsigned int r_symbolnum; 1470 uint32_t n_strx; 1471 1472 if(info->verbose == FALSE) 1473 return(NULL); 1474 1475 for(i = 0; i < nrelocs; i++){ 1476 if((uint32_t)relocs[i].r_address == sect_offset){ 1477 r_symbolnum = relocs[i].r_symbolnum; 1478 if(relocs[i].r_extern){ 1479 if(r_symbolnum >= info->nsymbols) 1480 break; 1481 n_strx = info->symbols[r_symbolnum].n_un.n_strx; 1482 if(n_strx <= 0 || n_strx >= info->strings_size) 1483 break; 1484 return(info->strings + n_strx); 1485 } 1486 break; 1487 } 1488 if(reloc_has_pair(info->cputype, relocs[i].r_type) == TRUE) 1489 i++; 1490 } 1491 for(i = 0; i < info->next_relocs; i++){ 1492 if((uint32_t)info->ext_relocs[i].r_address == 1493 database_offset + sect_offset){ 1494 r_symbolnum = info->ext_relocs[i].r_symbolnum; 1495 if(info->ext_relocs[i].r_extern){ 1496 if(r_symbolnum >= info->nsymbols) 1497 break; 1498 n_strx = info->symbols[r_symbolnum].n_un.n_strx; 1499 if(n_strx <= 0 || n_strx >= info->strings_size) 1500 break; 1501 return(info->strings + n_strx); 1502 } 1503 break; 1504 } 1505 if(reloc_has_pair(info->cputype, info->ext_relocs[i].r_type) ==TRUE) 1506 i++; 1507 } 1508 return(guess_symbol(value, info->sorted_symbols, info->nsorted_symbols, 1509 info->verbose)); 1510} 1511