| 535 | } |
| 536 | |
| 537 | PE_STATUS peParseExportTable( PE *pe, uint32_t dwMaxExports, uint32_t dwOptions /* = PE_EXPORT_OPT_DEFAULT */ ) |
| 538 | { |
| 539 | PE_STATUS status = PE_SUCCESS; |
| 540 | |
| 541 | if( PE_IS_PARSED( pe, EXPORTS ) == FALSE ) |
| 542 | { |
| 543 | uint32_t dwExportRVA = PE_HEADERS_OPT_FIELD( pe, DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress ), |
| 544 | dwExportSize = PE_HEADERS_OPT_FIELD( pe, DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size ); |
| 545 | |
| 546 | if( dwExportRVA != 0 && dwExportSize != 0 ) |
| 547 | { |
| 548 | PE_ADDRESS_FROM_VA |
| 549 | ( |
| 550 | pe, |
| 551 | pe->ExportTable.Address, |
| 552 | pe->qwBaseAddress + dwExportRVA |
| 553 | ); |
| 554 | |
| 555 | if( PE_IS_VALID_ADDRESS( pe->ExportTable.Address ) ) |
| 556 | { |
| 557 | pe->ExportTable.Address.Size = (uint64_t)dwExportSize; |
| 558 | |
| 559 | PIMAGE_EXPORT_DIRECTORY pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)pe->ExportTable.Address.Data; |
| 560 | |
| 561 | uint32_t *pdwFunctions, |
| 562 | *pdwFunctionNames; |
| 563 | uint16_t *pwOrdinals; |
| 564 | uint32_t dwCurrent = 0; |
| 565 | |
| 566 | pdwFunctions = (uint32_t *)PE_GET_POINTER( pe, pExportDirectory->AddressOfFunctions ); |
| 567 | pwOrdinals = (uint16_t *)PE_GET_POINTER( pe, pExportDirectory->AddressOfNameOrdinals ); |
| 568 | pdwFunctionNames = (uint32_t *)PE_GET_POINTER( pe, pExportDirectory->AddressOfNames ); |
| 569 | |
| 570 | ll_init( &pe->ExportTable.Symbols ); |
| 571 | |
| 572 | pe->ExportTable.ByAddress = HT_CREATE_BY_QWORD(); |
| 573 | pe->ExportTable.ByOrdinal = HT_CREATE_BY_WORD(); |
| 574 | pe->ExportTable.ByName = HT_CREATE_BY_ISTRING(); |
| 575 | |
| 576 | #define SHOULD_APPEND_SYMBOL( SYM ) \ |
| 577 | ( PE_IS_VALID_ADDRESS( (SYM)->Address ) && ht_get( pe->ExportTable.ByAddress, (void *)(SYM)->Address.VA ) == NULL ) |
| 578 | |
| 579 | #define APPEND_SYMBOL( SYM ) \ |
| 580 | if( (SYM)->Name[0] != 0x00 ){ \ |
| 581 | ht_add( pe->ExportTable.ByName, (SYM)->Name, (SYM) ); \ |
| 582 | } \ |
| 583 | ll_append( &pe->ExportTable.Symbols, (SYM) ); \ |
| 584 | ht_add( pe->ExportTable.ByAddress, (void *)(SYM)->Address.VA, (SYM) ); \ |
| 585 | ht_add( pe->ExportTable.ByOrdinal, (void *)(SYM)->Ordinal, (SYM) ) |
| 586 | |
| 587 | dwMaxExports = min( dwMaxExports, pExportDirectory->NumberOfNames + pExportDirectory->NumberOfFunctions ); |
| 588 | |
| 589 | #pragma region Loop by Name |
| 590 | |
| 591 | PE_SYMBOL *pSymbol = NULL; |
| 592 | |
| 593 | for( uint32_t i = 0; i < dwMaxExports; ++i ) |
| 594 | { |
no test coverage detected