mirror of
https://github.com/orange-cpp/omath.git
synced 2026-02-13 07:03:25 +00:00
Adds PE scanner infrastructure and data structures
Initializes infrastructure for PE file scanning. Adds data structures for PE headers (DOS, optional, section), including user-defined types for section characteristics. Refactors existing pattern scanning code to utilize new PE data structures. Adds basic parsing of PE headers.
This commit is contained in:
5
include/omath/system/pe/data_directory.hpp
Normal file
5
include/omath/system/pe/data_directory.hpp
Normal file
@@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by Vlad on 10/8/2025.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
5
include/omath/system/pe/optional_header.hpp
Normal file
5
include/omath/system/pe/optional_header.hpp
Normal file
@@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by Vlad on 10/8/2025.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
62
include/omath/system/pe/section_header.hpp
Normal file
62
include/omath/system/pe/section_header.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// Created by Vlad on 10/8/2025.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
union section_characteristics_t
|
||||
{
|
||||
std::uint32_t flags;
|
||||
struct
|
||||
{
|
||||
std::uint32_t _pad0 : 5;
|
||||
std::uint32_t cnt_code : 1; // Section contains code.
|
||||
std::uint32_t cnt_init_data : 1; // Section contains initialized data.
|
||||
std::uint32_t cnt_uninit_data : 1; // Section contains uninitialized data.
|
||||
std::uint32_t _pad1 : 1;
|
||||
std::uint32_t lnk_info : 1; // Section contains comments or some other type of information.
|
||||
std::uint32_t _pad2 : 1;
|
||||
std::uint32_t lnk_remove : 1; // Section contents will not become part of image.
|
||||
std::uint32_t lnk_comdat : 1; // Section contents comdat.
|
||||
std::uint32_t _pad3 : 1;
|
||||
std::uint32_t no_defer_spec_exc : 1; // Reset speculative exceptions handling bits in the TLB entries for this
|
||||
// section.
|
||||
std::uint32_t mem_far : 1;
|
||||
std::uint32_t _pad4 : 1;
|
||||
std::uint32_t mem_purgeable : 1;
|
||||
std::uint32_t mem_locked : 1;
|
||||
std::uint32_t mem_preload : 1;
|
||||
std::uint32_t alignment : 4; // Alignment calculated as: n ? 1 << ( n - 1 ) : 16
|
||||
std::uint32_t lnk_nreloc_ovfl : 1; // Section contains extended relocations.
|
||||
std::uint32_t mem_discardable : 1; // Section can be discarded.
|
||||
std::uint32_t mem_not_cached : 1; // Section is not cachable.
|
||||
std::uint32_t mem_not_paged : 1; // Section is not pageable.
|
||||
std::uint32_t mem_shared : 1; // Section is shareable.
|
||||
std::uint32_t mem_execute : 1; // Section is executable.
|
||||
std::uint32_t mem_read : 1; // Section is readable.
|
||||
std::uint32_t mem_write : 1; // Section is writeable.
|
||||
};
|
||||
};
|
||||
|
||||
// Section header
|
||||
//
|
||||
struct section_header_t
|
||||
{
|
||||
char name[8];
|
||||
union
|
||||
{
|
||||
std::uint32_t physical_address;
|
||||
std::uint32_t virtual_size;
|
||||
};
|
||||
std::uint32_t virtual_address;
|
||||
|
||||
std::uint32_t size_raw_data;
|
||||
std::uint32_t ptr_raw_data;
|
||||
|
||||
std::uint32_t ptr_relocs;
|
||||
std::uint32_t ptr_line_numbers;
|
||||
uint16_t num_relocs;
|
||||
uint16_t num_line_numbers;
|
||||
|
||||
section_characteristics_t characteristics;
|
||||
};
|
||||
@@ -2,11 +2,12 @@
|
||||
// Created by Vlad on 10/7/2025.
|
||||
//
|
||||
#include "omath/utility/pe_pattern_scan.hpp"
|
||||
#include "omath/system/pe/section_header.hpp"
|
||||
#include "omath/utility/pattern_scan.hpp"
|
||||
#include <fstream>
|
||||
#include <omath/system/pe/dos_header.hpp>
|
||||
#include <span>
|
||||
#include <stdexcept>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
@@ -68,7 +69,7 @@ namespace omath
|
||||
if (!file.is_open()) [[unlikely]]
|
||||
return std::nullopt;
|
||||
|
||||
IMAGE_DOS_HEADER dos_header{};
|
||||
system::pe::DosHeader dos_header{};
|
||||
file.read(reinterpret_cast<char*>(&dos_header), sizeof(dos_header));
|
||||
|
||||
if (dos_header.e_magic != 0x5A4D) [[unlikely]]
|
||||
@@ -86,20 +87,20 @@ namespace omath
|
||||
const auto offset_to_segment_table = dos_header.e_lfanew + nt_headers.FileHeader.SizeOfOptionalHeader
|
||||
+ sizeof(IMAGE_FILE_HEADER) + size_of_signature;
|
||||
|
||||
file.seekg(offset_to_segment_table, std::ios::beg);
|
||||
file.seekg(static_cast<std::fstream::off_type>(offset_to_segment_table), std::ios::beg);
|
||||
|
||||
for (size_t i = 0; i < nt_headers.FileHeader.NumberOfSections; i++)
|
||||
for (std::size_t i = 0; i < nt_headers.FileHeader.NumberOfSections; i++)
|
||||
{
|
||||
IMAGE_SECTION_HEADER current_section{};
|
||||
section_header_t current_section{};
|
||||
file.read(reinterpret_cast<char*>(¤t_section), sizeof(IMAGE_SECTION_HEADER));
|
||||
|
||||
if (std::string_view(reinterpret_cast<char*>(current_section.Name)) != section_name)
|
||||
if (std::string_view(current_section.name) != section_name)
|
||||
continue;
|
||||
|
||||
std::vector<std::byte> section_data(current_section.SizeOfRawData);
|
||||
std::vector<std::byte> section_data(current_section.size_raw_data);
|
||||
|
||||
file.seekg(current_section.PointerToRawData, std::ios::beg);
|
||||
file.read(reinterpret_cast<char*>(section_data.data()), section_data.size());
|
||||
file.seekg(current_section.ptr_raw_data, std::ios::beg);
|
||||
file.read(reinterpret_cast<char*>(section_data.data()), static_cast<std::streamsize>(section_data.size()));
|
||||
|
||||
return section_data;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user