Advertisement
es3n1n

pe mapper

May 20th, 2022 (edited)
49
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.     @note: @es3n1n: Basic PE file mapper
  3. */
  4. namespace mapper {
  5.     namespace detail {
  6.         std::uintptr_t allocate_region( std::size_t size_of_image ) noexcept {
  7.             return reinterpret_cast< std::uintptr_t >( VirtualAlloc( nullptr, size_of_image, MEM_COMMIT, PAGE_READWRITE ) );
  8.         }
  9.     }
  10.  
  11.     struct mapper_ctx_t {
  12.     public:
  13.         mapper_ctx_t( ) = default;
  14.         mapper_ctx_t( const std::uint8_t* pe_file_buffer ) : m_pe_file_buffer( pe_file_buffer ) {
  15.             m_dos_header = reinterpret_cast< PIMAGE_DOS_HEADER >( const_cast< std::uint8_t* >( m_pe_file_buffer ) );
  16.             m_nt_headers = reinterpret_cast< PIMAGE_NT_HEADERS >( const_cast< std::uint8_t* >( m_pe_file_buffer ) + m_dos_header->e_lfanew );
  17.  
  18.             m_mapped_to = detail::allocate_region( m_nt_headers->OptionalHeader.SizeOfImage );
  19.             if ( !m_mapped_to )
  20.                 ; // @todo: throw errors
  21.         }
  22.         ~mapper_ctx_t( ) = default;
  23.     public:
  24.         void map_sections( ) const {
  25.             PIMAGE_SECTION_HEADER section_header = IMAGE_FIRST_SECTION( m_nt_headers );
  26.  
  27.             for ( int i = 0; i < m_nt_headers->FileHeader.NumberOfSections; i++ ) {
  28.                 std::memcpy(
  29.                     reinterpret_cast< void* >( m_mapped_to + section_header[ i ].VirtualAddress ),
  30.                     reinterpret_cast< void* >( const_cast< std::uint8_t* >( m_pe_file_buffer ) + section_header[ i ].PointerToRawData ),
  31.                     section_header[ i ].SizeOfRawData
  32.                 );
  33.             }
  34.         }
  35.  
  36.         void relocate( ) const {
  37.             PIMAGE_BASE_RELOCATION relocation = reinterpret_cast< PIMAGE_BASE_RELOCATION >(
  38.                 m_mapped_to + m_nt_headers->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_BASERELOC ].VirtualAddress
  39.             );
  40.             const auto delta = m_mapped_to - m_nt_headers->OptionalHeader.ImageBase;
  41.  
  42.             while ( relocation->VirtualAddress ) {
  43.                 if ( relocation->SizeOfBlock >= sizeof( IMAGE_BASE_RELOCATION ) ) {
  44.                     const auto count = ( relocation->SizeOfBlock - sizeof( IMAGE_BASE_RELOCATION ) ) / sizeof( uint16_t );
  45.                     const auto list = reinterpret_cast< uint16_t* >( relocation + 1 );
  46.  
  47.                     for ( int i = 0; i < count; i++ ) {
  48.                         if ( list[ i ] ) {
  49.                             uintptr_t* ptr = reinterpret_cast< uintptr_t* >( m_mapped_to + ( relocation->VirtualAddress + ( list[ i ] & 0xFFF ) ) );
  50.                             *ptr += delta;
  51.                         }
  52.                     }
  53.                 }
  54.  
  55.                 relocation = reinterpret_cast< PIMAGE_BASE_RELOCATION >( reinterpret_cast< uintptr_t >( relocation ) + relocation->SizeOfBlock );
  56.             }
  57.         }
  58.     public:
  59.         const std::uint8_t* m_pe_file_buffer = nullptr;
  60.         std::uintptr_t m_mapped_to = 0x0;
  61.  
  62.         PIMAGE_DOS_HEADER m_dos_header = nullptr;
  63.         PIMAGE_NT_HEADERS m_nt_headers = nullptr;
  64.     };
  65.  
  66.     /*
  67.         @note: @es3n1n: Maps PE image to a memory and returns context with already mapped image
  68.     */
  69.     mapper_ctx_t map_pe( const std::uint8_t* pe_file_buffer ) {
  70.         mapper_ctx_t ctx( pe_file_buffer );
  71.         ctx.map_sections( );
  72.         ctx.relocate( );
  73.         return ctx;
  74.     }
  75. }
  76.  
  77. int main( ) {
  78.     const auto pe = detail::read_file( L"D:\\local-projects\\test-cpp-proj\\output\\Release\\1.dll" );
  79.     const auto mapped_img = mapper::map_pe( pe.data( ) );
  80.  
  81.     std::cout << std::hex << std::showbase << mapped_img.m_mapped_to << std::endl;
  82.  
  83.     __debugbreak( );
  84.  
  85.     return EXIT_SUCCESS;
  86. }
  87.  
Advertisement
RAW Paste Data Copied
Advertisement