| 369 | } |
| 370 | |
| 371 | struct exports_directory { |
| 372 | const char* _base; |
| 373 | const win::IMAGE_EXPORT_DIRECTORY* _ied; |
| 374 | unsigned long _ied_size; |
| 375 | |
| 376 | public: |
| 377 | using size_type = unsigned long; |
| 378 | |
| 379 | LAZY_IMPORTER_FORCEINLINE |
| 380 | exports_directory(const char* base) noexcept : _base(base) |
| 381 | { |
| 382 | const auto ied_data_dir = nt_headers(base)->OptionalHeader.DataDirectory[0]; |
| 383 | _ied = reinterpret_cast<const win::IMAGE_EXPORT_DIRECTORY*>( |
| 384 | base + ied_data_dir.VirtualAddress); |
| 385 | _ied_size = ied_data_dir.Size; |
| 386 | } |
| 387 | |
| 388 | LAZY_IMPORTER_FORCEINLINE explicit operator bool() const noexcept |
| 389 | { |
| 390 | return reinterpret_cast<const char*>(_ied) != _base; |
| 391 | } |
| 392 | |
| 393 | LAZY_IMPORTER_FORCEINLINE size_type size() const noexcept |
| 394 | { |
| 395 | return _ied->NumberOfNames; |
| 396 | } |
| 397 | |
| 398 | LAZY_IMPORTER_FORCEINLINE const char* base() const noexcept { return _base; } |
| 399 | LAZY_IMPORTER_FORCEINLINE const win::IMAGE_EXPORT_DIRECTORY* ied() const noexcept |
| 400 | { |
| 401 | return _ied; |
| 402 | } |
| 403 | |
| 404 | LAZY_IMPORTER_FORCEINLINE const char* name(size_type index) const noexcept |
| 405 | { |
| 406 | return reinterpret_cast<const char*>( |
| 407 | _base + reinterpret_cast<const unsigned long*>( |
| 408 | _base + _ied->AddressOfNames)[index]); |
| 409 | } |
| 410 | |
| 411 | LAZY_IMPORTER_FORCEINLINE const char* address(size_type index) const noexcept |
| 412 | { |
| 413 | const auto* const rva_table = |
| 414 | reinterpret_cast<const unsigned long*>(_base + _ied->AddressOfFunctions); |
| 415 | |
| 416 | const auto* const ord_table = reinterpret_cast<const unsigned short*>( |
| 417 | _base + _ied->AddressOfNameOrdinals); |
| 418 | |
| 419 | return _base + rva_table[ord_table[index]]; |
| 420 | } |
| 421 | |
| 422 | LAZY_IMPORTER_FORCEINLINE bool is_forwarded( |
| 423 | const char* export_address) const noexcept |
| 424 | { |
| 425 | const auto ui_ied = reinterpret_cast<const char*>(_ied); |
| 426 | return (export_address > ui_ied && export_address < ui_ied + _ied_size); |
| 427 | } |
| 428 | }; |
nothing calls this directly
no outgoing calls
no test coverage detected