From 661b73df47caae2cc62a9a2f7b85eb925ff1f80b Mon Sep 17 00:00:00 2001 From: auth12 <67507608+auth12@users.noreply.github.com> Date: Sun, 4 Jul 2021 01:15:09 +0100 Subject: initial commit --- sysmap/src/mapper/pe.h | 118 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 sysmap/src/mapper/pe.h (limited to 'sysmap/src/mapper/pe.h') diff --git a/sysmap/src/mapper/pe.h b/sysmap/src/mapper/pe.h new file mode 100644 index 0000000..9841cb2 --- /dev/null +++ b/sysmap/src/mapper/pe.h @@ -0,0 +1,118 @@ +#pragma once + +#include + +namespace pe { + struct export_data_t { + uintptr_t func_rva; + std::string f_mod; + std::string f_func; + }; + + struct image_t { + uintptr_t base; + std::unordered_map exports; + std::vector sections; + + image_t() : base{ 0 } { } + image_t(uintptr_t b) : base{ b } { + auto image = reinterpret_cast(b); + + auto nt = image->get_nt_headers(); + + for (auto &sec : nt->sections()) { + sections.emplace_back(sec); + } + + auto export_dir = b + nt->optional_header.data_directories.export_directory.rva; + auto export_size = nt->optional_header.data_directories.export_directory.size; + + auto exp = reinterpret_cast(export_dir); + + if (exp->num_functions == 0) return; + + auto names = reinterpret_cast(b + exp->rva_names); + auto funcs = reinterpret_cast(b + exp->rva_functions); + auto ords = reinterpret_cast(b + exp->rva_name_ordinals); + + if (!names || !funcs || !ords) return; + + for (size_t i{}; i < exp->num_names; i++) { + std::string name = reinterpret_cast(b + names[i]); + + export_data_t ret; + + ret.func_rva = funcs[ords[i]]; + + uintptr_t proc_addr = b + funcs[ords[i]]; + if (proc_addr > export_dir && proc_addr < export_dir + export_size) { + std::string forwarded_name = reinterpret_cast(proc_addr); + + size_t delim = forwarded_name.find('.'); + if (delim == std::string::npos) continue; + + ret.f_mod = forwarded_name.substr(0, delim + 1); + ret.f_mod.append("dll"); + + std::transform(ret.f_mod.begin(), ret.f_mod.end(), ret.f_mod.begin(), ::tolower); + + ret.f_func = forwarded_name.substr(delim + 1); + } + + + exports[name] = ret; + } + } + }; + + struct import_data_t { + std::string name; + uintptr_t rva; + }; + + struct raw_image_t { + win::nt_headers_x64_t* nt; + + std::unordered_map> imports; + std::unordered_map> relocs; + std::vector sections; + + raw_image_t(std::vector& buffer) { + auto image = reinterpret_cast(buffer.data()); + + nt = image->get_nt_headers(); + + for (auto& sec : nt->sections()) { + sections.emplace_back(sec); + } + + auto import_rva = nt->optional_header.data_directories.import_directory.rva; + + auto desc = image->rva_to_ptr(import_rva); + + for (uint32_t i = 0; i < desc->rva_name; i = desc->rva_name, ++desc) { + std::string mod = image->rva_to_ptr(desc->rva_name); + + auto thunk = image->rva_to_ptr(desc->rva_original_first_thunk); + + for (uint32_t index = 0; thunk->address; index += sizeof(u64), ++thunk) { + auto named_import = image->rva_to_ptr(thunk->address); + + if (!thunk->is_ordinal) { + std::transform(mod.begin(), mod.end(), mod.begin(), ::tolower); + + imports[mod].emplace_back(import_data_t{ reinterpret_cast(named_import->name), desc->rva_first_thunk + index }); + } + } + } + + auto reloc_dir = image->rva_to_ptr(nt->optional_header.data_directories.basereloc_directory.rva); + + for (auto* block = &reloc_dir->first_block; block->base_rva; block = block->next()) { + for (auto& entry : *block) { + relocs[block->base_rva].emplace_back(entry); + } + } + } + }; +}; \ No newline at end of file -- cgit v1.2.3