added clang format file and image_size

master
_xeroxz 4 years ago
parent 7c32517322
commit 99a1fc74e1

@ -0,0 +1,18 @@
---
BasedOnStyle: Microsoft
AlignAfterOpenBracket: Align
AllowAllArgumentsOnNextLine: 'true'
AllowAllParametersOfDeclarationOnNextLine: 'true'
AllowShortIfStatementsOnASingleLine: Never
BreakBeforeBraces: Allman
IndentWidth: '4'
Language: Cpp
NamespaceIndentation: All
SpacesInAngles: 'true'
SpacesInCStyleCastParentheses: 'true'
SpacesInContainerLiterals: 'true'
SpacesInParentheses: 'true'
SpacesInSquareBrackets: 'true'
UseTab: Never
...

@ -2,19 +2,19 @@
#define _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS
#pragma comment( lib, "ntdll.lib" ) #pragma comment( lib, "ntdll.lib" )
#include <algorithm>
#include <cstdint> #include <cstdint>
#include <string> #include <fstream>
#include <functional>
#include <map> #include <map>
#include <memory> #include <memory>
#include <algorithm> #include <string>
#include <functional>
#include <fstream>
#include <Windows.h> #include <Windows.h>
#include <tlhelp32.h> #include <ntstatus.h>
#include <psapi.h> #include <psapi.h>
#include <tlhelp32.h>
#include <winternl.h> #include <winternl.h>
#include <ntstatus.h>
#define LOG_SIG "[xtils]" #define LOG_SIG "[xtils]"
#define LOG( ... ) \ #define LOG( ... ) \
@ -24,8 +24,8 @@
OutputDebugStringA( buff ); \ OutputDebugStringA( buff ); \
} }
#define NT_HEADER(x) reinterpret_cast<PIMAGE_NT_HEADERS>( \ #define NT_HEADER( x ) \
uint64_t(x) + reinterpret_cast<PIMAGE_DOS_HEADER>(x)->e_lfanew ) reinterpret_cast< PIMAGE_NT_HEADERS >( uint64_t( x ) + reinterpret_cast< PIMAGE_DOS_HEADER >( x )->e_lfanew )
#define PAGE_4K 0x1000 #define PAGE_4K 0x1000
#define PAGE_2MB PAGE_4K * 512 #define PAGE_2MB PAGE_4K * 512
@ -51,7 +51,6 @@ typedef struct _RTL_PROCESS_MODULES
RTL_PROCESS_MODULE_INFORMATION Modules[ 1 ]; RTL_PROCESS_MODULE_INFORMATION Modules[ 1 ];
} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES; } RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;
namespace xtils namespace xtils
{ {
using uq_handle = std::unique_ptr< void, decltype( &CloseHandle ) >; using uq_handle = std::unique_ptr< void, decltype( &CloseHandle ) >;
@ -62,7 +61,11 @@ namespace xtils
using module_map_t = std::map< std::wstring, std::uintptr_t >; using module_map_t = std::map< std::wstring, std::uintptr_t >;
public: public:
static auto get_instance() -> um_t* { static um_t obj; return &obj; } static auto get_instance() -> um_t *
{
static um_t obj;
return &obj;
}
auto image_base( const char *image_path ) -> std::uintptr_t auto image_base( const char *image_path ) -> std::uintptr_t
{ {
@ -74,11 +77,19 @@ namespace xtils
return NT_HEADER( image_header )->OptionalHeader.ImageBase; return NT_HEADER( image_header )->OptionalHeader.ImageBase;
} }
auto sigscan(void* base, std::uint32_t size, const char* pattern, const char* mask) -> void* auto image_size(const char* image_path) -> std::uintptr_t
{ {
static const auto check_mask = char image_header[ PAGE_4K ];
[&](const char* base, const char* pattern, const char* mask) -> bool std::ifstream file( image_path, std::ios::binary );
file.read( image_header, PAGE_4K );
file.close();
return NT_HEADER( image_header )->OptionalHeader.SizeOfImage;
}
auto sigscan( void *base, std::uint32_t size, const char *pattern, const char *mask ) -> void *
{ {
static const auto check_mask = [ & ]( const char *base, const char *pattern, const char *mask ) -> bool {
for ( ; *mask; ++base, ++pattern, ++mask ) for ( ; *mask; ++base, ++pattern, ++mask )
if ( *mask == 'x' && *base != *pattern ) if ( *mask == 'x' && *base != *pattern )
return false; return false;
@ -107,8 +118,7 @@ namespace xtils
Module32First( snapshot.get(), &module_info ); Module32First( snapshot.get(), &module_info );
// lowercase the module name... // lowercase the module name...
std::for_each(module_info.szModule, std::for_each( module_info.szModule, module_info.szModule + wcslen( module_info.szModule ) * 2,
module_info.szModule + wcslen(module_info.szModule) * 2,
[]( wchar_t &c ) { c = ::towlower( c ); } ); []( wchar_t &c ) { c = ::towlower( c ); } );
module_map[ module_info.szModule ] = reinterpret_cast< std::uintptr_t >( module_info.modBaseAddr ); module_map[ module_info.szModule ] = reinterpret_cast< std::uintptr_t >( module_info.modBaseAddr );
@ -116,12 +126,10 @@ namespace xtils
for ( Module32First( snapshot.get(), &module_info ); Module32Next( snapshot.get(), &module_info ); ) for ( Module32First( snapshot.get(), &module_info ); Module32Next( snapshot.get(), &module_info ); )
{ {
// lowercase the module name... // lowercase the module name...
std::for_each(module_info.szModule, std::for_each( module_info.szModule, module_info.szModule + wcslen( module_info.szModule ) * 2,
module_info.szModule + wcslen(module_info.szModule) * 2,
[]( wchar_t &c ) { c = ::towlower( c ); } ); []( wchar_t &c ) { c = ::towlower( c ); } );
module_map[module_info.szModule] = module_map[ module_info.szModule ] = reinterpret_cast< std::uintptr_t >( module_info.modBaseAddr );
reinterpret_cast<std::uintptr_t>(module_info.modBaseAddr);
} }
return true; return true;
@ -184,33 +192,26 @@ namespace xtils
auto get_handle( std::uint32_t pid, DWORD access = PROCESS_ALL_ACCESS ) -> uq_handle auto get_handle( std::uint32_t pid, DWORD access = PROCESS_ALL_ACCESS ) -> uq_handle
{ {
if (!pid) return { NULL, &CloseHandle }; if ( !pid )
return { NULL, &CloseHandle };
return { OpenProcess( access, FALSE, pid ), &CloseHandle }; return { OpenProcess( access, FALSE, pid ), &CloseHandle };
} }
auto load_lib( HANDLE proc_handle, const char *dll_path ) -> std::uintptr_t auto load_lib( HANDLE proc_handle, const char *dll_path ) -> std::uintptr_t
{ {
const auto dll_path_page = const auto dll_path_page =
VirtualAllocEx( VirtualAllocEx( proc_handle, nullptr, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE );
proc_handle,
nullptr,
0x1000,
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE
);
if ( !dll_path_page ) if ( !dll_path_page )
return {}; return {};
SIZE_T handled_bytes; SIZE_T handled_bytes;
if (!WriteProcessMemory(proc_handle, dll_path_page, if ( !WriteProcessMemory( proc_handle, dll_path_page, dll_path, strlen( dll_path ), &handled_bytes ) )
dll_path, strlen(dll_path), &handled_bytes))
return {}; return {};
// +6 for string address // +6 for string address
// +16 for LoadLibrary address... // +16 for LoadLibrary address...
unsigned char jmp_code[] = unsigned char jmp_code[] = {
{
0x48, 0x83, 0xEC, 0x28, // sub rsp, 0x28 0x48, 0x83, 0xEC, 0x28, // sub rsp, 0x28
0x48, 0xB9, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, // mov rcx, &dllpath 0x48, 0xB9, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, // mov rcx, &dllpath
0x48, 0xB8, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, // mov rax, &LoadLibraryA 0x48, 0xB8, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, // mov rax, &LoadLibraryA
@ -227,24 +228,17 @@ namespace xtils
reinterpret_cast< std::uintptr_t >( &LoadLibraryA ); reinterpret_cast< std::uintptr_t >( &LoadLibraryA );
const auto jmp_code_page = const auto jmp_code_page =
VirtualAllocEx( VirtualAllocEx( proc_handle, nullptr, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE );
proc_handle,
nullptr,
0x1000,
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE
);
if ( !jmp_code_page ) if ( !jmp_code_page )
return {}; return {};
if (!WriteProcessMemory(proc_handle, if ( !WriteProcessMemory( proc_handle, jmp_code_page, jmp_code, sizeof jmp_code, &handled_bytes ) )
jmp_code_page, jmp_code, sizeof jmp_code, &handled_bytes))
return {}; return {};
DWORD tid = 0u; DWORD tid = 0u;
auto thandle = CreateRemoteThread(proc_handle, nullptr, auto thandle = CreateRemoteThread( proc_handle, nullptr, NULL, ( LPTHREAD_START_ROUTINE )jmp_code_page,
NULL, (LPTHREAD_START_ROUTINE)jmp_code_page, nullptr, NULL, &tid); nullptr, NULL, &tid );
if ( thandle == INVALID_HANDLE_VALUE ) if ( thandle == INVALID_HANDLE_VALUE )
return {}; return {};
@ -253,25 +247,24 @@ namespace xtils
// read the base address out of the shellcode... // read the base address out of the shellcode...
std::uintptr_t module_base = 0u; std::uintptr_t module_base = 0u;
if (!ReadProcessMemory(proc_handle, reinterpret_cast<void*>( if ( !ReadProcessMemory( proc_handle,
reinterpret_cast<std::uintptr_t>(jmp_code_page) + sizeof jmp_code), reinterpret_cast< void * >( reinterpret_cast< std::uintptr_t >( jmp_code_page ) +
sizeof jmp_code ),
&module_base, sizeof module_base, &handled_bytes ) ) &module_base, sizeof module_base, &handled_bytes ) )
return {}; return {};
return module_base; return module_base;
} }
auto start_exec(const char* image_path, char* cmdline = nullptr, auto start_exec( const char *image_path, char *cmdline = nullptr, bool suspend = false )
bool suspend = false) -> std::tuple<HANDLE, std::uint32_t, std::uintptr_t> -> std::tuple< HANDLE, std::uint32_t, std::uintptr_t >
{ {
STARTUPINFOA info = { sizeof info }; STARTUPINFOA info = { sizeof info };
PROCESS_INFORMATION proc_info; PROCESS_INFORMATION proc_info;
if (!CreateProcessA(image_path, cmdline, nullptr, if ( !CreateProcessA( image_path, cmdline, nullptr, nullptr, false,
nullptr, false, suspend ? CREATE_SUSPENDED | CREATE_NEW_CONSOLE : CREATE_NEW_CONSOLE, nullptr,
suspend ? CREATE_SUSPENDED | CREATE_NEW_CONSOLE : CREATE_NEW_CONSOLE, nullptr, &info, &proc_info ) )
nullptr, nullptr, &info, &proc_info
))
return { {}, {}, {} }; return { {}, {}, {} };
Sleep( 1 ); // sleep just for a tiny amount of time so that get_process_base works... Sleep( 1 ); // sleep just for a tiny amount of time so that get_process_base works...
@ -280,9 +273,7 @@ namespace xtils
std::uintptr_t scan( std::uintptr_t base, std::uint32_t size, const char *pattern, const char *mask ) std::uintptr_t scan( std::uintptr_t base, std::uint32_t size, const char *pattern, const char *mask )
{ {
static const auto check_mask = static const auto check_mask = [ & ]( const char *base, const char *pattern, const char *mask ) -> bool {
[&](const char* base, const char* pattern, const char* mask) -> bool
{
for ( ; *mask; ++base, ++pattern, ++mask ) for ( ; *mask; ++base, ++pattern, ++mask )
if ( *mask == 'x' && *base != *pattern ) if ( *mask == 'x' && *base != *pattern )
return false; return false;
@ -300,30 +291,35 @@ namespace xtils
} }
private: private:
explicit um_t() {} explicit um_t()
{
}
}; };
class km_t class km_t
{ {
using kmodule_callback_t = std::function< bool( PRTL_PROCESS_MODULE_INFORMATION, const char * ) >; using kmodule_callback_t = std::function< bool( PRTL_PROCESS_MODULE_INFORMATION, const char * ) >;
public: public:
static auto get_instance() -> km_t* { static km_t obj; return &obj; }; static auto get_instance() -> km_t *
{
static km_t obj;
return &obj;
};
auto get_base( const char *drv_name ) -> std::uintptr_t auto get_base( const char *drv_name ) -> std::uintptr_t
{ {
void *buffer = nullptr; void *buffer = nullptr;
DWORD buffer_size = NULL; DWORD buffer_size = NULL;
auto status = NtQuerySystemInformation( auto status = NtQuerySystemInformation( static_cast< SYSTEM_INFORMATION_CLASS >( 0xB ), buffer, buffer_size,
static_cast<SYSTEM_INFORMATION_CLASS>(0xB), &buffer_size );
buffer, buffer_size, &buffer_size);
while ( status == STATUS_INFO_LENGTH_MISMATCH ) while ( status == STATUS_INFO_LENGTH_MISMATCH )
{ {
VirtualFree( buffer, NULL, MEM_RELEASE ); VirtualFree( buffer, NULL, MEM_RELEASE );
buffer = VirtualAlloc( nullptr, buffer_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE ); buffer = VirtualAlloc( nullptr, buffer_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE );
status = NtQuerySystemInformation( status = NtQuerySystemInformation( static_cast< SYSTEM_INFORMATION_CLASS >( 0xB ), buffer, buffer_size,
static_cast<SYSTEM_INFORMATION_CLASS>(0xB), &buffer_size );
buffer, buffer_size, &buffer_size);
} }
if ( !NT_SUCCESS( status ) ) if ( !NT_SUCCESS( status ) )
@ -336,15 +332,12 @@ namespace xtils
for ( auto idx = 0u; idx < modules->NumberOfModules; ++idx ) for ( auto idx = 0u; idx < modules->NumberOfModules; ++idx )
{ {
const auto current_module_name = const auto current_module_name =
std::string(reinterpret_cast<char*>( std::string( reinterpret_cast< char * >( modules->Modules[ idx ].FullPathName ) +
modules->Modules[idx].FullPathName) +
modules->Modules[ idx ].OffsetToFileName ); modules->Modules[ idx ].OffsetToFileName );
if ( !_stricmp( current_module_name.c_str(), drv_name ) ) if ( !_stricmp( current_module_name.c_str(), drv_name ) )
{ {
const auto result = const auto result = reinterpret_cast< std::uint64_t >( modules->Modules[ idx ].ImageBase );
reinterpret_cast<std::uint64_t>(
modules->Modules[idx].ImageBase);
VirtualFree( buffer, NULL, MEM_RELEASE ); VirtualFree( buffer, NULL, MEM_RELEASE );
return result; return result;
@ -353,7 +346,6 @@ namespace xtils
VirtualFree( buffer, NULL, MEM_RELEASE ); VirtualFree( buffer, NULL, MEM_RELEASE );
return NULL; return NULL;
} }
void each_module( kmodule_callback_t callback ) void each_module( kmodule_callback_t callback )
@ -361,17 +353,15 @@ namespace xtils
void *buffer = nullptr; void *buffer = nullptr;
DWORD buffer_size = NULL; DWORD buffer_size = NULL;
auto status = NtQuerySystemInformation( auto status = NtQuerySystemInformation( static_cast< SYSTEM_INFORMATION_CLASS >( 0xB ), buffer, buffer_size,
static_cast<SYSTEM_INFORMATION_CLASS>(0xB), &buffer_size );
buffer, buffer_size, &buffer_size);
while ( status == STATUS_INFO_LENGTH_MISMATCH ) while ( status == STATUS_INFO_LENGTH_MISMATCH )
{ {
VirtualFree( buffer, NULL, MEM_RELEASE ); VirtualFree( buffer, NULL, MEM_RELEASE );
buffer = VirtualAlloc( nullptr, buffer_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE ); buffer = VirtualAlloc( nullptr, buffer_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE );
status = NtQuerySystemInformation( status = NtQuerySystemInformation( static_cast< SYSTEM_INFORMATION_CLASS >( 0xB ), buffer, buffer_size,
static_cast<SYSTEM_INFORMATION_CLASS>(0xB), &buffer_size );
buffer, buffer_size, &buffer_size);
} }
if ( !NT_SUCCESS( status ) ) if ( !NT_SUCCESS( status ) )
@ -383,17 +373,14 @@ namespace xtils
const auto modules = static_cast< PRTL_PROCESS_MODULES >( buffer ); const auto modules = static_cast< PRTL_PROCESS_MODULES >( buffer );
for ( auto idx = 0u; idx < modules->NumberOfModules; ++idx ) for ( auto idx = 0u; idx < modules->NumberOfModules; ++idx )
{ {
auto full_path = std::string( auto full_path = std::string( reinterpret_cast< char * >( modules->Modules[ idx ].FullPathName ) );
reinterpret_cast<char*>(
modules->Modules[idx].FullPathName));
if ( full_path.find( "\\SystemRoot\\" ) != std::string::npos ) if ( full_path.find( "\\SystemRoot\\" ) != std::string::npos )
full_path.replace(full_path.find("\\SystemRoot\\"), full_path.replace( full_path.find( "\\SystemRoot\\" ), sizeof( "\\SystemRoot\\" ) - 1,
sizeof("\\SystemRoot\\") - 1, std::string(getenv("SYSTEMROOT")).append("\\")); std::string( getenv( "SYSTEMROOT" ) ).append( "\\" ) );
else if ( full_path.find( "\\??\\" ) != std::string::npos ) else if ( full_path.find( "\\??\\" ) != std::string::npos )
full_path.replace(full_path.find("\\??\\"), full_path.replace( full_path.find( "\\??\\" ), sizeof( "\\??\\" ) - 1, "" );
sizeof("\\??\\") - 1, "");
if ( !callback( &modules->Modules[ idx ], full_path.c_str() ) ) if ( !callback( &modules->Modules[ idx ], full_path.c_str() ) )
{ {
@ -406,29 +393,20 @@ namespace xtils
return; return;
} }
auto get_export( const char *drv_name, const char *export_name ) -> std::uintptr_t auto get_export( const char *drv_name, const char *export_name ) -> std::uintptr_t
{ {
void *buffer = nullptr; void *buffer = nullptr;
DWORD buffer_size = NULL; DWORD buffer_size = NULL;
NTSTATUS status = NtQuerySystemInformation( NTSTATUS status = NtQuerySystemInformation( static_cast< SYSTEM_INFORMATION_CLASS >( 0xB ), buffer,
static_cast<SYSTEM_INFORMATION_CLASS>(0xB), buffer_size, &buffer_size );
buffer,
buffer_size,
&buffer_size
);
while ( status == STATUS_INFO_LENGTH_MISMATCH ) while ( status == STATUS_INFO_LENGTH_MISMATCH )
{ {
VirtualFree( buffer, 0, MEM_RELEASE ); VirtualFree( buffer, 0, MEM_RELEASE );
buffer = VirtualAlloc( nullptr, buffer_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE ); buffer = VirtualAlloc( nullptr, buffer_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE );
status = NtQuerySystemInformation( status = NtQuerySystemInformation( static_cast< SYSTEM_INFORMATION_CLASS >( 0xB ), buffer, buffer_size,
static_cast<SYSTEM_INFORMATION_CLASS>(0xB), &buffer_size );
buffer,
buffer_size,
&buffer_size
);
} }
if ( !NT_SUCCESS( status ) ) if ( !NT_SUCCESS( status ) )
@ -442,37 +420,24 @@ namespace xtils
{ {
// find module and then load library it // find module and then load library it
const std::string current_module_name = const std::string current_module_name =
std::string(reinterpret_cast<char*>( std::string( reinterpret_cast< char * >( modules->Modules[ idx ].FullPathName ) +
modules->Modules[idx].FullPathName) + modules->Modules[ idx ].OffsetToFileName );
modules->Modules[idx].OffsetToFileName
);
if ( !_stricmp( current_module_name.c_str(), drv_name ) ) if ( !_stricmp( current_module_name.c_str(), drv_name ) )
{ {
auto full_path = std::string( auto full_path = std::string( reinterpret_cast< char * >( modules->Modules[ idx ].FullPathName ) );
reinterpret_cast<char*>(
modules->Modules[idx].FullPathName));
full_path.replace(full_path.find("\\SystemRoot\\"), full_path.replace( full_path.find( "\\SystemRoot\\" ), sizeof( "\\SystemRoot\\" ) - 1,
sizeof("\\SystemRoot\\") - 1, std::string(getenv("SYSTEMROOT")).append("\\")); std::string( getenv( "SYSTEMROOT" ) ).append( "\\" ) );
const auto module_base = const auto module_base = LoadLibraryExA( full_path.c_str(), NULL, DONT_RESOLVE_DLL_REFERENCES );
LoadLibraryExA(
full_path.c_str(),
NULL,
DONT_RESOLVE_DLL_REFERENCES
);
const auto image_base = const auto image_base = reinterpret_cast< std::uintptr_t >( modules->Modules[ idx ].ImageBase );
reinterpret_cast<std::uintptr_t>(
modules->Modules[idx].ImageBase);
// free the RTL_PROCESS_MODULES buffer... // free the RTL_PROCESS_MODULES buffer...
VirtualFree( buffer, NULL, MEM_RELEASE ); VirtualFree( buffer, NULL, MEM_RELEASE );
const auto rva = const auto rva = reinterpret_cast< std::uintptr_t >( GetProcAddress( module_base, export_name ) ) -
reinterpret_cast<std::uintptr_t>(
GetProcAddress(module_base, export_name)) -
reinterpret_cast< std::uintptr_t >( module_base ); reinterpret_cast< std::uintptr_t >( module_base );
return image_base + rva; return image_base + rva;
@ -481,47 +446,49 @@ namespace xtils
VirtualFree( buffer, NULL, MEM_RELEASE ); VirtualFree( buffer, NULL, MEM_RELEASE );
return NULL; return NULL;
} }
private: private:
explicit km_t() {} explicit km_t()
{
}
}; };
class pe_t class pe_t
{ {
using section_callback_t = std::function< bool( PIMAGE_SECTION_HEADER, std::uintptr_t ) >; using section_callback_t = std::function< bool( PIMAGE_SECTION_HEADER, std::uintptr_t ) >;
public: public:
static auto get_instance() -> pe_t* { static pe_t obj; return &obj; } static auto get_instance() -> pe_t *
{
static pe_t obj;
return &obj;
}
// returns an std::vector containing all of the bytes of the section // returns an std::vector containing all of the bytes of the section
// and also the RVA from the image base to the beginning of the section... // and also the RVA from the image base to the beginning of the section...
auto get_section(std::uintptr_t module_base, auto get_section( std::uintptr_t module_base, const char *section_name )
const char* section_name) -> std::pair<std::vector<std::uint8_t>, std::uint32_t> -> std::pair< std::vector< std::uint8_t >, std::uint32_t >
{ {
const auto nt_headers = reinterpret_cast< PIMAGE_NT_HEADERS >( const auto nt_headers = reinterpret_cast< PIMAGE_NT_HEADERS >(
reinterpret_cast< PIMAGE_DOS_HEADER >( module_base )->e_lfanew + module_base ); reinterpret_cast< PIMAGE_DOS_HEADER >( module_base )->e_lfanew + module_base );
const auto section_header = const auto section_header = reinterpret_cast< PIMAGE_SECTION_HEADER >(
reinterpret_cast<PIMAGE_SECTION_HEADER>( reinterpret_cast< std::uintptr_t >( nt_headers ) + sizeof( DWORD ) + sizeof( IMAGE_FILE_HEADER ) +
reinterpret_cast<std::uintptr_t>(nt_headers) + sizeof(DWORD) nt_headers->FileHeader.SizeOfOptionalHeader );
+ sizeof(IMAGE_FILE_HEADER) + nt_headers->FileHeader.SizeOfOptionalHeader);
for ( auto idx = 0u; idx < nt_headers->FileHeader.NumberOfSections; ++idx ) for ( auto idx = 0u; idx < nt_headers->FileHeader.NumberOfSections; ++idx )
{ {
const auto _section_name = const auto _section_name = reinterpret_cast< char * >( section_header[ idx ].Name );
reinterpret_cast<char*>(
section_header[idx].Name);
// sometimes section names are not null terminated... // sometimes section names are not null terminated...
if ( !strncmp( _section_name, section_name, strlen( section_name ) - 1 ) ) if ( !strncmp( _section_name, section_name, strlen( section_name ) - 1 ) )
{ {
const auto section_base = const auto section_base =
reinterpret_cast<std::uint8_t*>( reinterpret_cast< std::uint8_t * >( module_base + section_header[ idx ].VirtualAddress );
module_base + section_header[idx].VirtualAddress);
const auto section_end = const auto section_end =
reinterpret_cast<std::uint8_t*>( reinterpret_cast< std::uint8_t * >( section_base + section_header[ idx ].Misc.VirtualSize );
section_base + section_header[idx].Misc.VirtualSize);
std::vector< std::uint8_t > section_bin( section_base, section_end ); std::vector< std::uint8_t > section_bin( section_base, section_end );
return { section_bin, section_header[ idx ].VirtualAddress }; return { section_bin, section_header[ idx ].VirtualAddress };
@ -539,23 +506,21 @@ namespace xtils
const auto nt_headers = reinterpret_cast< PIMAGE_NT_HEADERS >( const auto nt_headers = reinterpret_cast< PIMAGE_NT_HEADERS >(
reinterpret_cast< PIMAGE_DOS_HEADER >( module_base )->e_lfanew + module_base ); reinterpret_cast< PIMAGE_DOS_HEADER >( module_base )->e_lfanew + module_base );
const auto section_header = const auto section_header = reinterpret_cast< PIMAGE_SECTION_HEADER >(
reinterpret_cast<PIMAGE_SECTION_HEADER>( reinterpret_cast< std::uintptr_t >( nt_headers ) + sizeof( DWORD ) + sizeof( IMAGE_FILE_HEADER ) +
reinterpret_cast<std::uintptr_t>(nt_headers) + sizeof(DWORD) nt_headers->FileHeader.SizeOfOptionalHeader );
+ sizeof(IMAGE_FILE_HEADER) + nt_headers->FileHeader.SizeOfOptionalHeader);
for ( auto idx = 0u; idx < nt_headers->FileHeader.NumberOfSections; ++idx ) for ( auto idx = 0u; idx < nt_headers->FileHeader.NumberOfSections; ++idx )
{ {
const auto _section_name = const auto _section_name = reinterpret_cast< char * >( section_header[ idx ].Name );
reinterpret_cast<char*>(
section_header[idx].Name);
// keep looping until the callback returns false... // keep looping until the callback returns false...
if ( !callback( &section_header[ idx ], module_base ) ) if ( !callback( &section_header[ idx ], module_base ) )
return; return;
} }
} }
private: private:
explicit pe_t(){}; explicit pe_t(){};
}; };
} } // namespace xtils
Loading…
Cancel
Save