1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
#include "manualmap.hpp"
void inject::c_map::initialize( int pid ) {
m_handle = OpenProcess( PROCESS_ALL_ACCESS, 0, pid );
}
void inject::c_map::initialize( HANDLE process ) {
m_handle = process;
}
void inject::c_map::write( uintptr_t address, void* data, size_t size ) {
WriteProcessMemory( m_handle, ( void* )address, data, size, nullptr );
}
uintptr_t inject::c_map::allocate( size_t size ) {
void* allocation = VirtualAllocEx( m_handle, 0, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE );
m_allocations.push_back( allocation );
return uintptr_t( allocation );
}
void inject::c_map::free_allocated_regions( ) {
for( auto& it : m_allocations ) {
VirtualFreeEx( m_handle, it, 0, MEM_FREE );
}
m_allocations.clear( );
}
void inject::c_map::inject( uintptr_t interfaces ) {
HMODULE mod_data = ( HMODULE )m_inject_data.data( );
IMAGE_DOS_HEADER dos_hdr;
IMAGE_NT_HEADERS nt_hdrs;
dos_hdr = *( decltype( dos_hdr )* )( mod_data );
nt_hdrs = *( decltype( nt_hdrs )* )( uintptr_t( mod_data ) + dos_hdr.e_lfanew );
auto allocation = allocate( nt_hdrs.OptionalHeader.SizeOfImage );
auto size_of_headers = nt_hdrs.OptionalHeader.SizeOfHeaders;
auto num_of_sections = nt_hdrs.FileHeader.NumberOfSections;
m_allocation = malloc( nt_hdrs.OptionalHeader.SizeOfImage );
memset( m_allocation, 0, nt_hdrs.OptionalHeader.SizeOfImage );
memcpy( m_allocation, mod_data, size_of_headers );
write( allocation, m_allocation, size_of_headers );
auto sections = ( IMAGE_SECTION_HEADER* )( ( uintptr_t )( mod_data ) + dos_hdr.e_lfanew + sizeof( IMAGE_NT_HEADERS ) );
for( size_t i{ }; i < num_of_sections; ++i ) {
auto section = sections[ i ];
uintptr_t address = ( uintptr_t )m_allocation + section.VirtualAddress;
memcpy( ( void* )address,
( void* )( uintptr_t( mod_data ) + section.PointerToRawData ),
( size_t )section.SizeOfRawData );
}
auto base = nt_hdrs.OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_BASERELOC ].VirtualAddress;
auto base_reloc = ( IMAGE_BASE_RELOCATION* )( ( uintptr_t )m_allocation + base );
auto delta = allocation - nt_hdrs.OptionalHeader.ImageBase;
while( base_reloc->VirtualAddress ) {
if( base_reloc->SizeOfBlock >= sizeof( IMAGE_BASE_RELOCATION ) ) {
size_t count = ( base_reloc->SizeOfBlock - sizeof( IMAGE_BASE_RELOCATION ) ) / sizeof( uint16_t );
auto list = ( uint16_t* )( base_reloc + 1 );
uintptr_t* ptr{ };
for( size_t i{ }; i < count; ++i ) {
if( list[ i ] ) {
ptr = ( uintptr_t* )( ( uintptr_t )( m_allocation ) + ( base_reloc->VirtualAddress + ( list[ i ] & 0xfff ) ) );
*ptr += delta;
}
}
}
base_reloc = ( IMAGE_BASE_RELOCATION* )( ( uintptr_t )base_reloc + base_reloc->SizeOfBlock );
}
write( allocation, m_allocation, nt_hdrs.OptionalHeader.SizeOfImage );
free( m_allocation );
auto shellcode_allocation = allocate( 0x1000 );
img_data_t img_data{
allocation,
nt_hdrs.OptionalHeader.ImageBase,
nt_hdrs.OptionalHeader.AddressOfEntryPoint,
nt_hdrs.OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_BASERELOC ].VirtualAddress,
nt_hdrs.OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ].VirtualAddress,
( uintptr_t )( LoadLibraryA ),
( uintptr_t )( GetProcAddress ),
interfaces
};
write( shellcode_allocation, &img_data, sizeof( img_data_t ) );
auto loader_code_start = shellcode_allocation + sizeof( img_data_t );
auto loader_code_size = ( size_t )( ( uintptr_t )( &dummy_func_1 ) - ( uintptr_t )( &loader_shellcode ) );
write( loader_code_start, &loader_shellcode, loader_code_size );
auto thread = CreateRemoteThread( m_handle, nullptr, 0,
( LPTHREAD_START_ROUTINE )loader_code_start,
( void* )shellcode_allocation, 0, 0 );
WaitForSingleObject( thread, INFINITE );
ulong_t exit{ };
GetExitCodeThread( thread, &exit );
}
|