| 650 | } |
| 651 | |
| 652 | uint64_t intel_driver::GetKernelModuleExport(uint64_t kernel_module_base, const std::string& function_name) { |
| 653 | if (!kernel_module_base) |
| 654 | return 0; |
| 655 | |
| 656 | IMAGE_DOS_HEADER dos_header = { 0 }; |
| 657 | IMAGE_NT_HEADERS64 nt_headers = { 0 }; |
| 658 | |
| 659 | if (!ReadMemory(kernel_module_base, &dos_header, sizeof(dos_header)) || dos_header.e_magic != IMAGE_DOS_SIGNATURE || |
| 660 | !ReadMemory(kernel_module_base + dos_header.e_lfanew, &nt_headers, sizeof(nt_headers)) || nt_headers.Signature != IMAGE_NT_SIGNATURE) |
| 661 | return 0; |
| 662 | |
| 663 | const auto export_base = nt_headers.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; |
| 664 | const auto export_base_size = nt_headers.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; |
| 665 | |
| 666 | if (!export_base || !export_base_size) |
| 667 | return 0; |
| 668 | |
| 669 | const auto export_data = reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(VirtualAlloc(nullptr, export_base_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)); |
| 670 | |
| 671 | if (!ReadMemory(kernel_module_base + export_base, export_data, export_base_size)) |
| 672 | { |
| 673 | VirtualFree(export_data, 0, MEM_RELEASE); |
| 674 | return 0; |
| 675 | } |
| 676 | |
| 677 | const auto delta = reinterpret_cast<uint64_t>(export_data) - export_base; |
| 678 | |
| 679 | const auto name_table = reinterpret_cast<uint32_t*>(export_data->AddressOfNames + delta); |
| 680 | const auto ordinal_table = reinterpret_cast<uint16_t*>(export_data->AddressOfNameOrdinals + delta); |
| 681 | const auto function_table = reinterpret_cast<uint32_t*>(export_data->AddressOfFunctions + delta); |
| 682 | |
| 683 | for (auto i = 0u; i < export_data->NumberOfNames; ++i) { |
| 684 | const std::string current_function_name = std::string(reinterpret_cast<char*>(name_table[i] + delta)); |
| 685 | |
| 686 | if (!_stricmp(current_function_name.c_str(), function_name.c_str())) { |
| 687 | const auto function_ordinal = ordinal_table[i]; |
| 688 | if (function_table[function_ordinal] <= 0x1000) { |
| 689 | // Wrong function address? |
| 690 | return 0; |
| 691 | } |
| 692 | const auto function_address = kernel_module_base + function_table[function_ordinal]; |
| 693 | |
| 694 | if (function_address >= kernel_module_base + export_base && function_address <= kernel_module_base + export_base + export_base_size) { |
| 695 | VirtualFree(export_data, 0, MEM_RELEASE); |
| 696 | return 0; // No forwarded exports on 64bit? |
| 697 | } |
| 698 | |
| 699 | VirtualFree(export_data, 0, MEM_RELEASE); |
| 700 | return function_address; |
| 701 | } |
| 702 | } |
| 703 | |
| 704 | VirtualFree(export_data, 0, MEM_RELEASE); |
| 705 | return 0; |
| 706 | } |
| 707 | |
| 708 | bool intel_driver::ClearMmUnloadedDrivers() { |
| 709 | std::ostringstream ss; |