Skip to content

papstuc/portable_executable

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Modern C++ wrapper around the Microsoft Portable Executable file format

Note: For the "no_crt" version please checkout this link.

This is a W.I.P. library to interact with Microsoft PE files (.exe, .dll, .sys) in a modern C++ way.

Code to traverse tables (IAT, EAT, Relocs, etc...) is being abstracted by iterators to provide developers with a clean abstracted interface to base their work on.

Examples

More samples can be found in the main.cpp file.

Obtaining an image instance

The library currently only works with already mapped PE files, which means that sections have to be mapped to their virtual addresses.

The library however provides a way to map PE files on disk to memory using RAII.

// obtain image from a already mapped pe
HMODULE user32 = LoadLibrary(L"user32");
auto in_memory_image = reinterpret_cast<const portable_executable::image_t*>(user32);

// obtain image from filesystem and load it into memory
portable_executable::file_t ntoskrnl("C:\\Windows\\System32\\ntoskrnl.exe");

if (!ntoskrnl.load())
{
    // handle error cases
}

const portable_executable::image_t* from_fs_image = ntoskrnl.image();

Iterating sections

The section iterator provides the caller with a raw view of a section header.

for (const auto& section : image->sections())
{
    std::printf("section name: %s -> va: 0x%x size: 0x%x\n",
                    section.to_str().c_str(),
                    section.virtual_address,
                    section.virtual_size);
}

Iterating imports

The imports iterator abstracts away boilerplate code and returns the module name, function name and address of the respective import.

for (const auto& [module_name, import_name, address] : image->imports())
{
    std::printf("%s!%s -> 0x%p\n", module_name.c_str(), import_name.c_str(), address);
}

Iterating relocations

The relocations iterator provides the caller with a raw view of the offset of the relocation and its type.

for (const auto& relocation : image->relocations())
{
    std::printf("offset: %x -> type: %x\n", relocation.offset, relocation.type);
}

Iterating debug information

The debug information iterator provides the caller with a raw view of the debug information.

for (const auto debug_info : image->debug_info())
{
	std::printf("va: 0x%x -> type: 0x%x\n", debug_info.virtual_address, static_cast<std::uint32_t>(debug_info.type));
}

Iterating exceptions/runtime functions

The runtime functions iterator abstracts away boilerplate code and returns the pointer to the function begin, function end, and the unwind info.

The unwind code iterator provides the caller with a raw view of the unwind code. This is accessed via the unwind_info_t structure.

for (const auto runtime_function : image->runtime_functions())
{
	const auto virtual_address = static_cast<std::uint32_t>(runtime_function.function_begin - image->as<const std::uint8_t*>());

	std::printf("va: 0x%x -> unwind code count: 0x%x\n", virtual_address, runtime_function.unwind_info->unwind_code_count);

	for (const auto unwind_opcode : *runtime_function.unwind_info)
	{
		std::printf("(unwind code) offset: 0x%x, info: 0x%x\n", unwind_opcode.offset, unwind_opcode.info);
	}
}

Signature scanning

This library supports both IDA and Byte signature scanning.

// signature made for ntoskrnl version 22h2
std::uint8_t* hvi_is_any_hypervisor_present = ntoskrnl->signature_scan("40 53 48 83 EC ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 44 24 ? 33 C9 41 B9");

if (!hvi_is_any_hypervisor_present)
{
    // handle error cases
}

std::printf("ntoskrnl!HviIsAnyHypervisorPresent -> 0x%p\n", hvi_is_any_hypervisor_present);

Credits

  • noahware for the relocations parsing, debug information parsing, and exceptions parsing
  • can1357 for section_characteristics_t, thunk_data_t, data_directory_t and data_directories_t definitions from his linux-pe library
  • john for forcing me into releasing a version without any CRT linkage

About

modern c++ wrapper around the microsoft portable executable file format

Topics

Resources

Stars

Watchers

Forks

Languages