Rev 8600 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 8600 | Rev 8948 | ||
---|---|---|---|
Line 10... | Line 10... | ||
10 | #ifndef EPEP_READER |
10 | #ifndef EPEP_READER |
11 | #include |
11 | #include |
12 | #define EPEP_READER FILE * |
12 | #define EPEP_READER FILE * |
13 | #define EPEP_READER_GET(preader) getc(*preader) |
13 | #define EPEP_READER_GET(preader) getc(*preader) |
14 | #define EPEP_READER_SEEK(preader, offset) fseek(*preader, offset, SEEK_SET) |
14 | #define EPEP_READER_SEEK(preader, offset) fseek(*preader, offset, SEEK_SET) |
- | 15 | #define EPEP_READER_SEEK_END(preader, offset) fseek(*preader, offset, SEEK_END) |
|
15 | #define EPEP_READER_TELL(preader) ftell(*preader) |
16 | #define EPEP_READER_TELL(preader) ftell(*preader) |
16 | #define EPEP_READER_GET_BLOCK(preader, size, buf) fread(buf, 1, size, *preader); |
17 | #define EPEP_READER_GET_BLOCK(preader, size, buf) fread(buf, 1, size, *preader); |
17 | #endif |
18 | #endif |
Line 18... | Line 19... | ||
18 | 19 | ||
Line 37... | Line 38... | ||
37 | EPEP_ERR_OUTPUT_IS_NULL, |
38 | EPEP_ERR_OUTPUT_IS_NULL, |
38 | EPEP_ERR_ADDRESS_IS_OUT_OF_ANY_SECTION, |
39 | EPEP_ERR_ADDRESS_IS_OUT_OF_ANY_SECTION, |
39 | EPEP_ERR_EXPORT_ADDRESS_TABLE_ENTRY_NAME_NOT_FOUND, |
40 | EPEP_ERR_EXPORT_ADDRESS_TABLE_ENTRY_NAME_NOT_FOUND, |
40 | EPEP_ERR_NO_BASE_RELOCATION_TABLE, |
41 | EPEP_ERR_NO_BASE_RELOCATION_TABLE, |
41 | EPEP_ERR_BASE_RELOCATION_IS_ALREADY_END, |
42 | EPEP_ERR_BASE_RELOCATION_IS_ALREADY_END, |
- | 43 | EPEP_ERR_INVALID_DATA_DIRECTORY_OFFSET, |
|
- | 44 | EPEP_ERR_INVALID_SECTION_HEADER_OFFSET, |
|
- | 45 | EPEP_ERR_INVALID_SECTION_DATA_OFFSET, |
|
- | 46 | EPEP_ERR_INVALID_STRING_TABLE_SIZE_OFFSET, |
|
- | 47 | EPEP_ERR_INVALID_SYMBOL_OFFSET, |
|
- | 48 | EPEP_ERR_INVALID_IMPORT_DIRECTORY_OFFSET, |
|
- | 49 | EPEP_ERR_INVALID_IMPORT_DIRECTORY_NAME_OFFSET, |
|
- | 50 | EPEP_ERR_INVALID_LOOKUP_OFFSET, |
|
- | 51 | EPEP_ERR_INVALID_LOOKUP_NAME_OFFSET, |
|
- | 52 | EPEP_ERR_INVALID_EXPORT_TABLE_OFFSET, |
|
- | 53 | EPEP_ERR_INVALID_DLL_NAME_OFFSET, |
|
- | 54 | EPEP_ERR_INVALID_EXPORT_NAME_POINTER_OFFSET, |
|
- | 55 | EPEP_ERR_INVALID_ORDINAL_TABLE_OFFSET, |
|
- | 56 | EPEP_ERR_INVALID_EXPORT_NAME_OFFSET, |
|
- | 57 | EPEP_ERR_INVALID_EXPORT_ADDRESS_OFFSET, |
|
- | 58 | EPEP_ERR_INVALID_FORWARDER_OFFSET, |
|
- | 59 | EPEP_ERR_INVALID_BASE_RELOCATION_BLOCK_OFFSET, |
|
- | 60 | EPEP_ERR_INVALID_NEXT_BASE_RELOCATION_BLOCK_OFFSET, |
|
- | 61 | EPEP_ERR_INVALID_BASE_RELOCATION_BLOCK_BASE_RELOCATION_OFFSET, |
|
- | 62 | EPEP_ERR_INVALID_SECTION_RELOCATION_OFFSET, |
|
- | 63 | EPEP_ERR_INVALID_LINENUMBER_OFFSET, |
|
42 | } EpepError; |
64 | } EpepError; |
Line 43... | Line 65... | ||
43 | 65 | ||
44 | // |
66 | // |
45 | // Generic |
67 | // Generic |
Line 46... | Line 68... | ||
46 | // |
68 | // |
47 | 69 | ||
48 | typedef struct { |
70 | typedef struct { |
49 | EPEP_READER reader; |
71 | EPEP_READER reader; |
- | 72 | EpepKind kind; |
|
50 | EpepKind kind; |
73 | EpepError error_code; |
51 | EpepError error_code; |
74 | size_t file_size; |
52 | size_t signature_offset_offset; |
75 | size_t signature_offset_offset; |
53 | size_t signature_offset; |
76 | size_t signature_offset; |
54 | size_t first_data_directory_offset; |
77 | size_t first_data_directory_offset; |
Line 362... | Line 385... | ||
362 | static int epep_seek(Epep *epep, size_t offset) { |
385 | static int epep_seek(Epep *epep, size_t offset) { |
363 | EPEP_READER_SEEK(&epep->reader, offset); |
386 | EPEP_READER_SEEK(&epep->reader, offset); |
364 | return 1; |
387 | return 1; |
365 | } |
388 | } |
Line -... | Line 389... | ||
- | 389 | ||
- | 390 | static int epep_seek_end(Epep *epep, size_t offset) { |
|
- | 391 | EPEP_READER_SEEK_END(&epep->reader, offset); |
|
- | 392 | return 1; |
|
- | 393 | } |
|
366 | 394 | ||
367 | static int epep_read_block(Epep *epep, size_t size, void *block) { |
395 | static int epep_read_block(Epep *epep, size_t size, void *block) { |
368 | EPEP_READER_GET_BLOCK(&epep->reader, size, block); |
396 | EPEP_READER_GET_BLOCK(&epep->reader, size, block); |
369 | return 1; |
397 | return 1; |
Line 405... | Line 433... | ||
405 | 433 | ||
406 | static uint64_t epep_read_ptr(Epep *epep) { |
434 | static uint64_t epep_read_ptr(Epep *epep) { |
407 | return is_pe32(epep) ? epep_read_u32(epep) : epep_read_u64(epep); |
435 | return is_pe32(epep) ? epep_read_u32(epep) : epep_read_u64(epep); |
Line -... | Line 436... | ||
- | 436 | } |
|
- | 437 | ||
- | 438 | static int epep_valid_offset(Epep *epep, size_t offset, size_t size) { |
|
- | 439 | return (offset + size) <= epep->file_size; |
|
408 | } |
440 | } |
409 | 441 | ||
410 | // |
442 | // |
Line 411... | Line 443... | ||
411 | // Generic |
443 | // Generic |
412 | // |
444 | // |
413 | 445 | ||
414 | int epep_init(Epep *epep, EPEP_READER reader) { |
446 | int epep_init(Epep *epep, EPEP_READER reader) { |
- | 447 | *epep = (Epep){ 0 }; |
|
- | 448 | epep->kind = EPEP_IMAGE; |
|
- | 449 | epep->reader = reader; |
|
415 | *epep = (Epep){ 0 }; |
450 | epep_seek_end(epep, 0); |
416 | epep->kind = EPEP_IMAGE; |
451 | epep->file_size = EPEP_READER_TELL(&epep->reader); |
417 | epep->reader = reader; |
452 | epep_seek(epep, 0); |
418 | epep->error_code = EPEP_ERR_SUCCESS; |
- | |
419 | epep->signature_offset_offset = 0x3c; |
453 | epep->error_code = EPEP_ERR_SUCCESS; |
420 | epep_seek(epep, epep->signature_offset_offset); |
- | |
421 | epep->signature_offset = 0; |
- | |
422 | epep->signature_offset |= epep_read_u8(epep); |
- | |
423 | epep->signature_offset |= epep_read_u8(epep) << 8; |
454 | epep->signature_offset_offset = 0x3c; |
424 | epep->signature_offset |= epep_read_u8(epep) << 16; |
455 | epep_seek(epep, epep->signature_offset_offset); |
425 | epep->signature_offset |= epep_read_u8(epep) << 24; |
456 | epep->signature_offset = epep_read_u32(epep); |
426 | epep_seek(epep, epep->signature_offset); |
457 | epep_seek(epep, epep->signature_offset); |
427 | char signature_buf[4]; |
458 | char signature_buf[4]; |
Line 506... | Line 537... | ||
506 | int epep_get_data_directory_by_index(Epep *epep, EpepImageDataDirectory *idd, size_t index) { |
537 | int epep_get_data_directory_by_index(Epep *epep, EpepImageDataDirectory *idd, size_t index) { |
507 | if (index >= epep->optionalHeader.NumberOfRvaAndSizes) { |
538 | if (index >= epep->optionalHeader.NumberOfRvaAndSizes) { |
508 | epep->error_code = EPEP_ERR_DATA_DIRECTORY_INDEX_IS_INVALID; |
539 | epep->error_code = EPEP_ERR_DATA_DIRECTORY_INDEX_IS_INVALID; |
509 | return 0; |
540 | return 0; |
510 | } |
541 | } |
511 | epep_seek(epep, epep->first_data_directory_offset + sizeof(EpepImageDataDirectory) * index); |
542 | size_t offset = epep->first_data_directory_offset + sizeof(EpepImageDataDirectory) * index; |
- | 543 | if (!epep_valid_offset(epep, offset, sizeof(EpepImageDataDirectory))) { |
|
- | 544 | epep->error_code = EPEP_ERR_INVALID_DATA_DIRECTORY_OFFSET; |
|
- | 545 | return 0; |
|
- | 546 | } |
|
- | 547 | epep_seek(epep, offset); |
|
512 | idd->VirtualAddress = epep_read_u32(epep); |
548 | idd->VirtualAddress = epep_read_u32(epep); |
513 | idd->Size = epep_read_u32(epep); |
549 | idd->Size = epep_read_u32(epep); |
514 | return 1; |
550 | return 1; |
515 | } |
551 | } |
Line 521... | Line 557... | ||
521 | int epep_get_section_header_by_index(Epep *epep, EpepSectionHeader *sh, size_t index) { |
557 | int epep_get_section_header_by_index(Epep *epep, EpepSectionHeader *sh, size_t index) { |
522 | if (index >= epep->coffFileHeader.NumberOfSections) { |
558 | if (index >= epep->coffFileHeader.NumberOfSections) { |
523 | epep->error_code = EPEP_ERR_SECTION_HEADER_INDEX_IS_INVALID; |
559 | epep->error_code = EPEP_ERR_SECTION_HEADER_INDEX_IS_INVALID; |
524 | return 0; |
560 | return 0; |
525 | } |
561 | } |
526 | epep_seek(epep, epep->first_section_header_offset + sizeof(EpepSectionHeader) * index); |
562 | size_t offset = epep->first_section_header_offset + sizeof(EpepSectionHeader) * index; |
- | 563 | if (!epep_valid_offset(epep, offset, sizeof(EpepSectionHeader))) { |
|
- | 564 | epep->error_code = EPEP_ERR_INVALID_SECTION_HEADER_OFFSET; |
|
- | 565 | return 0; |
|
- | 566 | } |
|
- | 567 | epep_seek(epep, offset); |
|
527 | for (int i = 0; i < 8; i++) { |
568 | for (int i = 0; i < 8; i++) { |
528 | sh->Name[i] = epep_read_u8(epep); |
569 | sh->Name[i] = epep_read_u8(epep); |
529 | } |
570 | } |
530 | sh->VirtualSize = epep_read_u32(epep); |
571 | sh->VirtualSize = epep_read_u32(epep); |
531 | sh->VirtualAddress = epep_read_u32(epep); |
572 | sh->VirtualAddress = epep_read_u32(epep); |
Line 551... | Line 592... | ||
551 | epep->error_code = EPEP_ERR_ADDRESS_IS_OUT_OF_ANY_SECTION; |
592 | epep->error_code = EPEP_ERR_ADDRESS_IS_OUT_OF_ANY_SECTION; |
552 | return 0; |
593 | return 0; |
553 | } |
594 | } |
Line 554... | Line 595... | ||
554 | 595 | ||
- | 596 | int epep_get_section_contents(Epep *epep, EpepSectionHeader *sh, void *buf) { |
|
555 | int epep_get_section_contents(Epep *epep, EpepSectionHeader *sh, void *buf) { |
597 | size_t offset = sh->PointerToRawData; |
- | 598 | size_t size_of_raw_data = sh->SizeOfRawData; |
|
- | 599 | if (!epep_valid_offset(epep, offset, size_of_raw_data)) { |
|
- | 600 | epep->error_code = EPEP_ERR_INVALID_SECTION_DATA_OFFSET; |
|
- | 601 | return 0; |
|
556 | size_t size_of_raw_data = sh->SizeOfRawData; |
602 | } |
557 | epep_seek(epep, sh->PointerToRawData); |
603 | epep_seek(epep, offset); |
558 | epep_read_block(epep, size_of_raw_data, buf); |
604 | epep_read_block(epep, size_of_raw_data, buf); |
559 | return 1; |
605 | return 1; |
Line 560... | Line 606... | ||
560 | } |
606 | } |
561 | 607 | ||
562 | // |
608 | // |
Line 563... | Line 609... | ||
563 | // COFF Symbols |
609 | // COFF Symbols |
564 | // |
610 | // |
- | 611 | ||
- | 612 | int epep_get_string_table_size(Epep *epep, size_t *size) { |
|
- | 613 | size_t offset = epep->coffFileHeader.PointerToSymbolTable + 18 * epep->coffFileHeader.NumberOfSymbols; |
|
- | 614 | if (!epep_valid_offset(epep, offset, sizeof(uint32_t))) { |
|
- | 615 | epep->error_code = EPEP_ERR_INVALID_STRING_TABLE_SIZE_OFFSET; |
|
565 | 616 | return 0; |
|
566 | int epep_get_string_table_size(Epep *epep, size_t *size) { |
617 | } |
567 | epep_seek(epep, epep->coffFileHeader.PointerToSymbolTable + 18 * epep->coffFileHeader.NumberOfSymbols); |
618 | epep_seek(epep, offset); |
Line 568... | Line 619... | ||
568 | *size = epep_read_u32(epep); |
619 | *size = epep_read_u32(epep); |
Line 590... | Line 641... | ||
590 | } |
641 | } |
591 | if (index >= epep->coffFileHeader.NumberOfSymbols) { |
642 | if (index >= epep->coffFileHeader.NumberOfSymbols) { |
592 | epep->error_code = EPEP_ERR_SYMBOL_INDEX_IS_INVALID; |
643 | epep->error_code = EPEP_ERR_SYMBOL_INDEX_IS_INVALID; |
593 | return 0; |
644 | return 0; |
594 | } |
645 | } |
595 | epep_seek(epep, epep->coffFileHeader.PointerToSymbolTable + 18 * index); |
646 | size_t offset = epep->coffFileHeader.PointerToSymbolTable + 18 * index; |
- | 647 | if (!epep_valid_offset(epep, offset, 18)) { |
|
- | 648 | epep->error_code = EPEP_ERR_INVALID_SYMBOL_OFFSET; |
|
- | 649 | return 0; |
|
- | 650 | } |
|
- | 651 | epep_seek(epep, offset); |
|
596 | for (size_t i = 0; i < 18; i++) { |
652 | for (size_t i = 0; i < 18; i++) { |
597 | sym->auxFile.FileName[i] = epep_read_u8(epep); |
653 | sym->auxFile.FileName[i] = epep_read_u8(epep); |
598 | } |
654 | } |
599 | return 1; |
655 | return 1; |
600 | } |
656 | } |
Line 629... | Line 685... | ||
629 | if (epep->import_table_offset == 0) { |
685 | if (epep->import_table_offset == 0) { |
630 | if (!epep_read_import_table_offset(epep)) { |
686 | if (!epep_read_import_table_offset(epep)) { |
631 | return 0; |
687 | return 0; |
632 | } |
688 | } |
633 | } |
689 | } |
634 | epep_seek(epep, epep->import_table_offset + index * sizeof(*import_directory)); |
690 | size_t offset = epep->import_table_offset + index * sizeof(*import_directory); |
- | 691 | if (!epep_valid_offset(epep, offset, sizeof(*import_directory))) { |
|
- | 692 | epep->error_code = EPEP_ERR_INVALID_IMPORT_DIRECTORY_OFFSET; |
|
- | 693 | return 0; |
|
- | 694 | } |
|
- | 695 | epep_seek(epep, offset); |
|
635 | epep_read_block(epep, sizeof(*import_directory), import_directory); |
696 | epep_read_block(epep, sizeof(*import_directory), import_directory); |
636 | return 1; |
697 | return 1; |
637 | } |
698 | } |
Line 638... | Line 699... | ||
638 | 699 | ||
639 | int epep_get_import_directory_name_s(Epep *epep, EpepImportDirectory *import_directory, char *name, size_t name_max) { |
700 | int epep_get_import_directory_name_s(Epep *epep, EpepImportDirectory *import_directory, char *name, size_t name_max) { |
640 | size_t name_rva = import_directory->NameRva; |
701 | size_t name_rva = import_directory->NameRva; |
641 | size_t name_offset = 0; |
702 | size_t name_offset = 0; |
642 | if (!epep_get_file_offset_by_rva(epep, &name_offset, name_rva)) { |
703 | if (!epep_get_file_offset_by_rva(epep, &name_offset, name_rva)) { |
643 | return 0; |
704 | return 0; |
- | 705 | } |
|
- | 706 | if (!epep_valid_offset(epep, name_offset, 0)) { |
|
- | 707 | epep->error_code = EPEP_ERR_INVALID_IMPORT_DIRECTORY_NAME_OFFSET; |
|
- | 708 | return 0; |
|
644 | } |
709 | } |
645 | epep_seek(epep, name_offset); |
710 | epep_seek(epep, name_offset); |
646 | epep_read_block(epep, name_max, name); |
711 | epep_read_block(epep, name_max, name); |
647 | return 1; |
712 | return 1; |
Line 652... | Line 717... | ||
652 | if (!epep_get_file_offset_by_rva(epep, &first_lookup_offset, import_directory->ImportLookupTableRva)) { |
717 | if (!epep_get_file_offset_by_rva(epep, &first_lookup_offset, import_directory->ImportLookupTableRva)) { |
653 | return 0; |
718 | return 0; |
654 | } |
719 | } |
655 | size_t size_of_lookup = is_pe32(epep) ? 4 : 8; |
720 | size_t size_of_lookup = is_pe32(epep) ? 4 : 8; |
656 | size_t lookup_offset = first_lookup_offset + size_of_lookup * index; |
721 | size_t lookup_offset = first_lookup_offset + size_of_lookup * index; |
- | 722 | if (!epep_valid_offset(epep, lookup_offset, size_of_lookup)) { |
|
- | 723 | epep->error_code = EPEP_ERR_INVALID_LOOKUP_OFFSET; |
|
- | 724 | return 0; |
|
- | 725 | } |
|
657 | epep_seek(epep, lookup_offset); |
726 | epep_seek(epep, lookup_offset); |
658 | epep_read_block(epep, size_of_lookup, lookup); |
727 | epep_read_block(epep, size_of_lookup, lookup); |
659 | return 1; |
728 | return 1; |
660 | } |
729 | } |
Line 678... | Line 747... | ||
678 | if (!epep_get_file_offset_by_rva(epep, &name_offset, name_rva)) { |
747 | if (!epep_get_file_offset_by_rva(epep, &name_offset, name_rva)) { |
679 | return 0; |
748 | return 0; |
680 | } |
749 | } |
681 | // skip 2 bytes (Name Table :: Hint) |
750 | // skip 2 bytes (Name Table :: Hint) |
682 | name_offset += 2; |
751 | name_offset += 2; |
- | 752 | if (!epep_valid_offset(epep, name_offset, 0)) { |
|
- | 753 | epep->error_code = EPEP_ERR_INVALID_LOOKUP_NAME_OFFSET; |
|
- | 754 | return 0; |
|
- | 755 | } |
|
683 | epep_seek(epep, name_offset); |
756 | epep_seek(epep, name_offset); |
684 | epep_read_block(epep, name_max, name); |
757 | epep_read_block(epep, name_max, name); |
685 | return 1; |
758 | return 1; |
686 | } |
759 | } |
Line 715... | Line 788... | ||
715 | if (epep->export_table_offset == 0) { |
788 | if (epep->export_table_offset == 0) { |
716 | if (!epep_read_export_table_offset(epep)) { |
789 | if (!epep_read_export_table_offset(epep)) { |
717 | return 0; |
790 | return 0; |
718 | } |
791 | } |
719 | } |
792 | } |
- | 793 | if (!epep_valid_offset(epep, epep->export_table_offset, sizeof(epep->export_directory))) { |
|
- | 794 | epep->error_code = EPEP_ERR_INVALID_EXPORT_TABLE_OFFSET; |
|
- | 795 | return 0; |
|
- | 796 | } |
|
720 | epep_seek(epep, epep->export_table_offset); |
797 | epep_seek(epep, epep->export_table_offset); |
721 | epep_read_block(epep, sizeof(epep->export_directory), &epep->export_directory); |
798 | epep_read_block(epep, sizeof(epep->export_directory), &epep->export_directory); |
722 | return 1; |
799 | return 1; |
723 | } |
800 | } |
Line 724... | Line 801... | ||
724 | 801 | ||
725 | int epep_get_dll_name_s(Epep *epep, char *name, size_t name_max) { |
802 | int epep_get_dll_name_s(Epep *epep, char *name, size_t name_max) { |
726 | size_t offset = 0; |
803 | size_t offset = 0; |
727 | if (!epep_get_file_offset_by_rva(epep, &offset, epep->export_directory.NameRva)) { |
804 | if (!epep_get_file_offset_by_rva(epep, &offset, epep->export_directory.NameRva)) { |
728 | return 0; |
805 | return 0; |
- | 806 | } |
|
- | 807 | if (!epep_valid_offset(epep, offset, 0)) { |
|
- | 808 | epep->error_code = EPEP_ERR_INVALID_DLL_NAME_OFFSET; |
|
- | 809 | return 0; |
|
729 | } |
810 | } |
730 | epep_seek(epep, offset); |
811 | epep_seek(epep, offset); |
731 | epep_read_block(epep, name_max, name); |
812 | epep_read_block(epep, name_max, name); |
732 | return 1; |
813 | return 1; |
Line 736... | Line 817... | ||
736 | size_t name_pointer_table_rva = epep->export_directory.NamePointerRva; |
817 | size_t name_pointer_table_rva = epep->export_directory.NamePointerRva; |
737 | size_t name_pointer_table_offset = 0; |
818 | size_t name_pointer_table_offset = 0; |
738 | if (!epep_get_file_offset_by_rva(epep, &name_pointer_table_offset, name_pointer_table_rva)) { |
819 | if (!epep_get_file_offset_by_rva(epep, &name_pointer_table_offset, name_pointer_table_rva)) { |
739 | return 0; |
820 | return 0; |
740 | } |
821 | } |
741 | epep_seek(epep, name_pointer_table_offset + sizeof(uint32_t) * index); |
822 | size_t offset = name_pointer_table_offset + sizeof(uint32_t) * index; |
- | 823 | if (!epep_valid_offset(epep, offset, sizeof(uint32_t))) { |
|
- | 824 | epep->error_code = EPEP_ERR_INVALID_EXPORT_NAME_POINTER_OFFSET; |
|
- | 825 | return 0; |
|
- | 826 | } |
|
- | 827 | epep_seek(epep, offset); |
|
742 | *name_rva = epep_read_u32(epep); |
828 | *name_rva = epep_read_u32(epep); |
743 | return 1; |
829 | return 1; |
744 | } |
830 | } |
Line 745... | Line 831... | ||
745 | 831 | ||
746 | int epep_get_export_name_s_by_index(Epep *epep, char *name, size_t name_max, size_t index) { |
832 | int epep_get_export_name_s_by_index(Epep *epep, char *name, size_t name_max, size_t index) { |
747 | size_t ordinal_table_offset = 0; |
833 | size_t ordinal_table_offset = 0; |
748 | if (!epep_get_file_offset_by_rva(epep, &ordinal_table_offset, epep->export_directory.OrdinalTableRva)) { |
834 | if (!epep_get_file_offset_by_rva(epep, &ordinal_table_offset, epep->export_directory.OrdinalTableRva)) { |
749 | return 0; |
835 | return 0; |
- | 836 | } |
|
- | 837 | if (!epep_valid_offset(epep, ordinal_table_offset, 0)) { |
|
- | 838 | epep->error_code = EPEP_ERR_INVALID_ORDINAL_TABLE_OFFSET; |
|
- | 839 | return 0; |
|
750 | } |
840 | } |
751 | epep_seek(epep, ordinal_table_offset); |
841 | epep_seek(epep, ordinal_table_offset); |
752 | for (size_t i = 0; i < epep->export_directory.NumberOfNamePointers; i++) { |
842 | for (size_t i = 0; i < epep->export_directory.NumberOfNamePointers; i++) { |
753 | uint16_t ordinal = epep_read_u16(epep); |
843 | uint16_t ordinal = epep_read_u16(epep); |
754 | if (ordinal == index) { // SPEC_VIOL: Why should not epep->export_directory.OrdinalBase be substracted? |
844 | if (ordinal == index) { // SPEC_VIOL: Why should not epep->export_directory.OrdinalBase be substracted? |
Line 758... | Line 848... | ||
758 | } |
848 | } |
759 | size_t name_offset = 0; |
849 | size_t name_offset = 0; |
760 | if (!epep_get_file_offset_by_rva(epep, &name_offset, name_rva)) { |
850 | if (!epep_get_file_offset_by_rva(epep, &name_offset, name_rva)) { |
761 | return 0; |
851 | return 0; |
762 | } |
852 | } |
- | 853 | if (!epep_valid_offset(epep, name_offset, 0)) { |
|
- | 854 | epep->error_code = EPEP_ERR_INVALID_EXPORT_NAME_OFFSET; |
|
- | 855 | return 0; |
|
- | 856 | } |
|
763 | epep_seek(epep, name_offset); |
857 | epep_seek(epep, name_offset); |
764 | epep_read_block(epep, name_max, name); |
858 | epep_read_block(epep, name_max, name); |
765 | return 1; |
859 | return 1; |
766 | } |
860 | } |
767 | } |
861 | } |
Line 773... | Line 867... | ||
773 | size_t export_address_table_offset = 0; |
867 | size_t export_address_table_offset = 0; |
774 | if (!epep_get_file_offset_by_rva(epep, &export_address_table_offset, epep->export_directory.ExportAddressTableRva)) { |
868 | if (!epep_get_file_offset_by_rva(epep, &export_address_table_offset, epep->export_directory.ExportAddressTableRva)) { |
775 | return 0; |
869 | return 0; |
776 | } |
870 | } |
777 | EPEP_ASSERT(sizeof(EpepExportAddress) == sizeof(uint32_t)); |
871 | EPEP_ASSERT(sizeof(EpepExportAddress) == sizeof(uint32_t)); |
778 | epep_seek(epep, export_address_table_offset + sizeof(EpepExportAddress) * index); |
872 | size_t offset = export_address_table_offset + sizeof(EpepExportAddress) * index; |
- | 873 | if (!epep_valid_offset(epep, offset, sizeof(*export_address))) { |
|
- | 874 | epep->error_code = EPEP_ERR_INVALID_EXPORT_ADDRESS_OFFSET; |
|
- | 875 | return 0; |
|
- | 876 | } |
|
- | 877 | epep_seek(epep, offset); |
|
779 | epep_read_block(epep, sizeof(*export_address), export_address); |
878 | epep_read_block(epep, sizeof(*export_address), export_address); |
780 | return 1; |
879 | return 1; |
781 | } |
880 | } |
Line 782... | Line 881... | ||
782 | 881 | ||
783 | int epep_get_export_address_forwarder_s(Epep *epep, EpepExportAddress *export_address, char *forwarder, size_t forwarder_max) { |
882 | int epep_get_export_address_forwarder_s(Epep *epep, EpepExportAddress *export_address, char *forwarder, size_t forwarder_max) { |
784 | size_t forwarder_offset = 0; |
883 | size_t forwarder_offset = 0; |
785 | if (!epep_get_file_offset_by_rva(epep, &forwarder_offset, export_address->ForwarderRva)) { |
884 | if (!epep_get_file_offset_by_rva(epep, &forwarder_offset, export_address->ForwarderRva)) { |
786 | return 0; |
885 | return 0; |
- | 886 | } |
|
- | 887 | if (!epep_valid_offset(epep, forwarder_offset, 0)) { |
|
- | 888 | epep->error_code = EPEP_ERR_INVALID_FORWARDER_OFFSET; |
|
- | 889 | return 0; |
|
787 | } |
890 | } |
788 | epep_seek(epep, forwarder_offset); |
891 | epep_seek(epep, forwarder_offset); |
789 | epep_read_block(epep, forwarder_max, forwarder); |
892 | epep_read_block(epep, forwarder_max, forwarder); |
790 | return 1; |
893 | return 1; |
Line 836... | Line 939... | ||
836 | } |
939 | } |
837 | if (epep->base_relocation_table_offset == 0) { |
940 | if (epep->base_relocation_table_offset == 0) { |
838 | epep->error_code = EPEP_ERR_NO_BASE_RELOCATION_TABLE; |
941 | epep->error_code = EPEP_ERR_NO_BASE_RELOCATION_TABLE; |
839 | return 0; |
942 | return 0; |
840 | } |
943 | } |
- | 944 | if (!epep_valid_offset(epep, epep->base_relocation_table_offset, 0)) { |
|
- | 945 | epep->error_code = EPEP_ERR_INVALID_BASE_RELOCATION_BLOCK_OFFSET; |
|
- | 946 | return 0; |
|
- | 947 | } |
|
841 | if (!epep_seek(epep, epep->base_relocation_table_offset)) { |
948 | if (!epep_seek(epep, epep->base_relocation_table_offset)) { |
842 | return 0; |
949 | return 0; |
843 | } |
950 | } |
844 | brb->offset = epep->base_relocation_table_offset; |
951 | brb->offset = epep->base_relocation_table_offset; |
845 | brb->PageRva = epep_read_u32(epep); |
952 | brb->PageRva = epep_read_u32(epep); |
Line 855... | Line 962... | ||
855 | it->offset = it->offset + it->BlockSize; |
962 | it->offset = it->offset + it->BlockSize; |
856 | if (it->offset >= epep->base_relocation_table_end_offset) { |
963 | if (it->offset >= epep->base_relocation_table_end_offset) { |
857 | *it = (EpepBaseRelocationBlock){ 0 }; |
964 | *it = (EpepBaseRelocationBlock){ 0 }; |
858 | return 1; |
965 | return 1; |
859 | } |
966 | } |
- | 967 | if (!epep_valid_offset(epep, it->offset, 0)) { |
|
- | 968 | epep->error_code = EPEP_ERR_INVALID_NEXT_BASE_RELOCATION_BLOCK_OFFSET; |
|
- | 969 | return 0; |
|
- | 970 | } |
|
860 | if (!epep_seek(epep, it->offset)) { |
971 | if (!epep_seek(epep, it->offset)) { |
861 | return 0; |
972 | return 0; |
862 | } |
973 | } |
863 | it->PageRva = epep_read_u32(epep); |
974 | it->PageRva = epep_read_u32(epep); |
864 | it->BlockSize = epep_read_u32(epep); |
975 | it->BlockSize = epep_read_u32(epep); |
865 | return 1; |
976 | return 1; |
866 | } |
977 | } |
Line 867... | Line 978... | ||
867 | 978 | ||
868 | int epep_get_base_relocation_block_base_relocation_by_index(Epep *epep, EpepBaseRelocationBlock *brb, EpepBaseRelocation *br, size_t index) { |
979 | int epep_get_base_relocation_block_base_relocation_by_index(Epep *epep, EpepBaseRelocationBlock *brb, EpepBaseRelocation *br, size_t index) { |
- | 980 | size_t offset = brb->offset + 8 + sizeof(EpepBaseRelocation) * index; |
|
- | 981 | if (!epep_valid_offset(epep, offset, sizeof(EpepBaseRelocation))) { |
|
- | 982 | epep->error_code = EPEP_ERR_INVALID_BASE_RELOCATION_BLOCK_BASE_RELOCATION_OFFSET; |
|
- | 983 | return 0; |
|
- | 984 | } |
|
869 | if (!epep_seek(epep, brb->offset + 8 + sizeof(EpepBaseRelocation) * index)) { |
985 | if (!epep_seek(epep, offset)) { |
870 | return 0; |
986 | return 0; |
871 | } |
987 | } |
872 | br->u16 = epep_read_u16(epep); |
988 | br->u16 = epep_read_u16(epep); |
873 | return 1; |
989 | return 1; |
Line 876... | Line 992... | ||
876 | // |
992 | // |
877 | // COFF Relocations |
993 | // COFF Relocations |
878 | // |
994 | // |
Line 879... | Line 995... | ||
879 | 995 | ||
880 | int epep_get_section_relocation_by_index(Epep *epep, EpepSectionHeader *sh, EpepCoffRelocation *rel, size_t index) { |
996 | int epep_get_section_relocation_by_index(Epep *epep, EpepSectionHeader *sh, EpepCoffRelocation *rel, size_t index) { |
- | 997 | size_t offset = sh->PointerToRelocations + 10 * index; |
|
- | 998 | if (!epep_valid_offset(epep, offset, 10)) { |
|
- | 999 | epep->error_code = EPEP_ERR_INVALID_SECTION_RELOCATION_OFFSET; |
|
- | 1000 | return 0; |
|
881 | size_t relocationsOffset = sh->PointerToRelocations; |
1001 | } |
882 | epep_seek(epep, relocationsOffset + 10 * index); |
1002 | epep_seek(epep, offset); |
883 | epep_read_block(epep, 10, rel); |
1003 | epep_read_block(epep, 10, rel); |
884 | return 1; |
1004 | return 1; |
Line 885... | Line 1005... | ||
885 | } |
1005 | } |
886 | 1006 | ||
887 | // |
1007 | // |
Line 888... | Line 1008... | ||
888 | // COFF Line Numbers |
1008 | // COFF Line Numbers |
889 | // |
1009 | // |
- | 1010 | ||
- | 1011 | int epep_get_section_line_number_by_index(Epep *epep, EpepSectionHeader *sh, EpepCoffLinenumber *ln, size_t index) { |
|
- | 1012 | size_t offset = sh->PointerToLinenumbers + 6 * index; |
|
- | 1013 | if (!epep_valid_offset(epep, offset, 6)) { |
|
890 | 1014 | epep->error_code = EPEP_ERR_INVALID_LINENUMBER_OFFSET; |
|
891 | int epep_get_section_line_number_by_index(Epep *epep, EpepSectionHeader *sh, EpepCoffLinenumber *ln, size_t index) { |
1015 | return 0; |
892 | size_t LinenumbersOffset = sh->PointerToLinenumbers; |
1016 | } |
893 | epep_seek(epep, LinenumbersOffset + 6 * index); |
1017 | epep_seek(epep, offset); |
Line 894... | Line 1018... | ||
894 | epep_read_block(epep, 6, ln); |
1018 | epep_read_block(epep, 6, ln); |