parent
6bd06ea635
commit
6e2b3e56fc
@ -1 +1 @@
|
|||||||
Subproject commit a419fa4633f98e2f819b1119dc0884154e207482
|
Subproject commit 0f6ba9bad30d67f25f01b6c1e872077efdff61d4
|
@ -1,272 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#pragma section( ".xmp2" )
|
|
||||||
#pragma comment( linker, "/section:.xmp2,RWE" )
|
|
||||||
|
|
||||||
namespace vm
|
|
||||||
{
|
|
||||||
using u8 = unsigned char;
|
|
||||||
using s8 = signed char;
|
|
||||||
|
|
||||||
using u16 = unsigned short;
|
|
||||||
using s16 = signed short;
|
|
||||||
|
|
||||||
using u32 = unsigned int;
|
|
||||||
using s32 = signed int;
|
|
||||||
|
|
||||||
using u64 = unsigned long long;
|
|
||||||
using s64 = signed long long;
|
|
||||||
using __vmcall_t = void *( * )( ... );
|
|
||||||
|
|
||||||
constexpr u8 IMAGE_DIRECTORY_ENTRY_BASERELOC = 8;
|
|
||||||
constexpr u8 IMAGE_REL_BASED_ABSOLUTE = 0;
|
|
||||||
constexpr u8 IMAGE_REL_BASED_DIR64 = 10;
|
|
||||||
|
|
||||||
typedef struct _IMAGE_DOS_HEADER
|
|
||||||
{
|
|
||||||
/* 0x0000 */ unsigned short e_magic;
|
|
||||||
/* 0x0002 */ unsigned short e_cblp;
|
|
||||||
/* 0x0004 */ unsigned short e_cp;
|
|
||||||
/* 0x0006 */ unsigned short e_crlc;
|
|
||||||
/* 0x0008 */ unsigned short e_cparhdr;
|
|
||||||
/* 0x000a */ unsigned short e_minalloc;
|
|
||||||
/* 0x000c */ unsigned short e_maxalloc;
|
|
||||||
/* 0x000e */ unsigned short e_ss;
|
|
||||||
/* 0x0010 */ unsigned short e_sp;
|
|
||||||
/* 0x0012 */ unsigned short e_csum;
|
|
||||||
/* 0x0014 */ unsigned short e_ip;
|
|
||||||
/* 0x0016 */ unsigned short e_cs;
|
|
||||||
/* 0x0018 */ unsigned short e_lfarlc;
|
|
||||||
/* 0x001a */ unsigned short e_ovno;
|
|
||||||
/* 0x001c */ unsigned short e_res[ 4 ];
|
|
||||||
/* 0x0024 */ unsigned short e_oemid;
|
|
||||||
/* 0x0026 */ unsigned short e_oeminfo;
|
|
||||||
/* 0x0028 */ unsigned short e_res2[ 10 ];
|
|
||||||
/* 0x003c */ long e_lfanew;
|
|
||||||
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; /* size: 0x0040 */
|
|
||||||
|
|
||||||
typedef struct _IMAGE_FILE_HEADER
|
|
||||||
{
|
|
||||||
/* 0x0000 */ unsigned short Machine;
|
|
||||||
/* 0x0002 */ unsigned short NumberOfSections;
|
|
||||||
/* 0x0004 */ unsigned long TimeDateStamp;
|
|
||||||
/* 0x0008 */ unsigned long PointerToSymbolTable;
|
|
||||||
/* 0x000c */ unsigned long NumberOfSymbols;
|
|
||||||
/* 0x0010 */ unsigned short SizeOfOptionalHeader;
|
|
||||||
/* 0x0012 */ unsigned short Characteristics;
|
|
||||||
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; /* size: 0x0014 */
|
|
||||||
|
|
||||||
typedef struct _IMAGE_DATA_DIRECTORY
|
|
||||||
{
|
|
||||||
/* 0x0000 */ unsigned long VirtualAddress;
|
|
||||||
/* 0x0004 */ unsigned long Size;
|
|
||||||
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; /* size: 0x0008 */
|
|
||||||
|
|
||||||
typedef struct _IMAGE_OPTIONAL_HEADER64
|
|
||||||
{
|
|
||||||
/* 0x0000 */ unsigned short Magic;
|
|
||||||
/* 0x0002 */ unsigned char MajorLinkerVersion;
|
|
||||||
/* 0x0003 */ unsigned char MinorLinkerVersion;
|
|
||||||
/* 0x0004 */ unsigned long SizeOfCode;
|
|
||||||
/* 0x0008 */ unsigned long SizeOfInitializedData;
|
|
||||||
/* 0x000c */ unsigned long SizeOfUninitializedData;
|
|
||||||
/* 0x0010 */ unsigned long AddressOfEntryPoint;
|
|
||||||
/* 0x0014 */ unsigned long BaseOfCode;
|
|
||||||
/* 0x0018 */ unsigned __int64 ImageBase;
|
|
||||||
/* 0x0020 */ unsigned long SectionAlignment;
|
|
||||||
/* 0x0024 */ unsigned long FileAlignment;
|
|
||||||
/* 0x0028 */ unsigned short MajorOperatingSystemVersion;
|
|
||||||
/* 0x002a */ unsigned short MinorOperatingSystemVersion;
|
|
||||||
/* 0x002c */ unsigned short MajorImageVersion;
|
|
||||||
/* 0x002e */ unsigned short MinorImageVersion;
|
|
||||||
/* 0x0030 */ unsigned short MajorSubsystemVersion;
|
|
||||||
/* 0x0032 */ unsigned short MinorSubsystemVersion;
|
|
||||||
/* 0x0034 */ unsigned long Win32VersionValue;
|
|
||||||
/* 0x0038 */ unsigned long SizeOfImage;
|
|
||||||
/* 0x003c */ unsigned long SizeOfHeaders;
|
|
||||||
/* 0x0040 */ unsigned long CheckSum;
|
|
||||||
/* 0x0044 */ unsigned short Subsystem;
|
|
||||||
/* 0x0046 */ unsigned short DllCharacteristics;
|
|
||||||
/* 0x0048 */ unsigned __int64 SizeOfStackReserve;
|
|
||||||
/* 0x0050 */ unsigned __int64 SizeOfStackCommit;
|
|
||||||
/* 0x0058 */ unsigned __int64 SizeOfHeapReserve;
|
|
||||||
/* 0x0060 */ unsigned __int64 SizeOfHeapCommit;
|
|
||||||
/* 0x0068 */ unsigned long LoaderFlags;
|
|
||||||
/* 0x006c */ unsigned long NumberOfRvaAndSizes;
|
|
||||||
/* 0x0070 */ struct _IMAGE_DATA_DIRECTORY DataDirectory[ 16 ];
|
|
||||||
} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64; /* size: 0x00f0 */
|
|
||||||
|
|
||||||
typedef struct _IMAGE_NT_HEADERS64
|
|
||||||
{
|
|
||||||
/* 0x0000 */ unsigned long Signature;
|
|
||||||
/* 0x0004 */ struct _IMAGE_FILE_HEADER FileHeader;
|
|
||||||
/* 0x0018 */ struct _IMAGE_OPTIONAL_HEADER64 OptionalHeader;
|
|
||||||
} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64; /* size: 0x0108 */
|
|
||||||
|
|
||||||
typedef struct _IMAGE_SECTION_HEADER
|
|
||||||
{
|
|
||||||
/* 0x0000 */ unsigned char Name[ 8 ];
|
|
||||||
union
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
/* 0x0008 */ unsigned long PhysicalAddress;
|
|
||||||
/* 0x0008 */ unsigned long VirtualSize;
|
|
||||||
}; /* size: 0x0004 */
|
|
||||||
} /* size: 0x0004 */ Misc;
|
|
||||||
/* 0x000c */ unsigned long VirtualAddress;
|
|
||||||
/* 0x0010 */ unsigned long SizeOfRawData;
|
|
||||||
/* 0x0014 */ unsigned long PointerToRawData;
|
|
||||||
/* 0x0018 */ unsigned long PointerToRelocations;
|
|
||||||
/* 0x001c */ unsigned long PointerToLinenumbers;
|
|
||||||
/* 0x0020 */ unsigned short NumberOfRelocations;
|
|
||||||
/* 0x0022 */ unsigned short NumberOfLinenumbers;
|
|
||||||
/* 0x0024 */ unsigned long Characteristics;
|
|
||||||
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; /* size: 0x0028 */
|
|
||||||
|
|
||||||
typedef struct _IMAGE_BASE_RELOCATION
|
|
||||||
{
|
|
||||||
unsigned int VirtualAddress;
|
|
||||||
unsigned int SizeOfBlock;
|
|
||||||
} IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION;
|
|
||||||
|
|
||||||
constexpr auto entry_rva = 0x1000;
|
|
||||||
|
|
||||||
enum class calls : u32
|
|
||||||
{
|
|
||||||
get_world = 0xBFFD6FE9,
|
|
||||||
get_hello = 0xBFFD6FDD
|
|
||||||
};
|
|
||||||
|
|
||||||
template < class T, class U > struct _pair_t
|
|
||||||
{
|
|
||||||
T first;
|
|
||||||
U second;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline _pair_t< u8, calls > call_map[ 2 ] = { { 0, calls::get_world }, { 1, calls::get_hello } };
|
|
||||||
|
|
||||||
struct _gen_data
|
|
||||||
{
|
|
||||||
u8 bin[ 0x100000 ]; // this will the vmp binary...
|
|
||||||
u8 map_area[ 0x10000 ]; // map the binary into this space...
|
|
||||||
|
|
||||||
u8 __%s_vinstrs[%d] = {};
|
|
||||||
|
|
||||||
u8 __vmcall_shell_code[ 2 ][ 15 ] = { {
|
|
||||||
0x68, 0xE9, 0xD6, 0xFF, 0x0B, // push xxxx
|
|
||||||
0x68, 0xE9, 0xD6, 0xFF, 0x0B, // push xxxx
|
|
||||||
0xE9, 0x00, 0x00, 0x00, 0x00 // jmp rip+xxxx
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
0x68, 0xE9, 0xD6, 0xFF, 0x0B, // push xxxx
|
|
||||||
0x68, 0xE9, 0xD6, 0xFF, 0x0B, // push xxxx
|
|
||||||
0xE9, 0x00, 0x00, 0x00, 0x00 // jmp rip+xxxx
|
|
||||||
} };
|
|
||||||
|
|
||||||
bool init()
|
|
||||||
{
|
|
||||||
static const auto _memcpy = []( void *dest, const void *src, size_t len ) -> void * {
|
|
||||||
char *d = ( char * )dest;
|
|
||||||
const char *s = ( char * )src;
|
|
||||||
while ( len-- )
|
|
||||||
*d++ = *s++;
|
|
||||||
|
|
||||||
return dest;
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto dos_header = reinterpret_cast< IMAGE_DOS_HEADER * >( bin );
|
|
||||||
const auto nt_headers = reinterpret_cast< PIMAGE_NT_HEADERS64 >( bin + dos_header->e_lfanew );
|
|
||||||
|
|
||||||
_memcpy( map_area, bin, nt_headers->OptionalHeader.SizeOfHeaders );
|
|
||||||
|
|
||||||
auto sections = reinterpret_cast< PIMAGE_SECTION_HEADER >( ( u8 * )&nt_headers->OptionalHeader +
|
|
||||||
nt_headers->FileHeader.SizeOfOptionalHeader );
|
|
||||||
|
|
||||||
// map sections...
|
|
||||||
for ( u32 i = 0; i < nt_headers->FileHeader.NumberOfSections; ++i )
|
|
||||||
{
|
|
||||||
PIMAGE_SECTION_HEADER section = §ions[ i ];
|
|
||||||
|
|
||||||
_memcpy( ( void * )( map_area + section->VirtualAddress ),
|
|
||||||
( void * )( bin + section->PointerToRawData ), section->SizeOfRawData );
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle relocations...
|
|
||||||
const auto reloc_dir = &nt_headers->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_BASERELOC ];
|
|
||||||
|
|
||||||
if ( reloc_dir->VirtualAddress )
|
|
||||||
{
|
|
||||||
auto reloc = reinterpret_cast< IMAGE_BASE_RELOCATION * >( map_area + reloc_dir->VirtualAddress );
|
|
||||||
|
|
||||||
for ( auto current_size = 0u; current_size < reloc_dir->Size; )
|
|
||||||
{
|
|
||||||
u32 reloc_count = ( reloc->SizeOfBlock - sizeof( IMAGE_BASE_RELOCATION ) ) / sizeof( u16 );
|
|
||||||
u16 *reloc_data = ( u16 * )( ( u8 * )reloc + sizeof( IMAGE_BASE_RELOCATION ) );
|
|
||||||
u8 *reloc_base = map_area + reloc->VirtualAddress;
|
|
||||||
|
|
||||||
for ( auto idx = 0; idx < reloc_count; ++idx, ++reloc_data )
|
|
||||||
{
|
|
||||||
u16 data = *reloc_data;
|
|
||||||
u16 type = data >> 12;
|
|
||||||
u16 offset = data & 0xFFF;
|
|
||||||
|
|
||||||
switch ( type )
|
|
||||||
{
|
|
||||||
case IMAGE_REL_BASED_ABSOLUTE:
|
|
||||||
break;
|
|
||||||
case IMAGE_REL_BASED_DIR64:
|
|
||||||
{
|
|
||||||
u64 *rva = ( u64 * )( reloc_base + offset );
|
|
||||||
*rva = ( u64 )( map_area + ( *rva - nt_headers->OptionalHeader.ImageBase ) );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
current_size += reloc->SizeOfBlock;
|
|
||||||
reloc = ( IMAGE_BASE_RELOCATION * )reloc_data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// fix shellcode up...
|
|
||||||
for ( auto idx = 0u; idx < ( sizeof( __vmcall_shell_code ) / 15 ); ++idx )
|
|
||||||
{
|
|
||||||
// first push encrypted rva value...
|
|
||||||
*reinterpret_cast< u32 * >( &__vmcall_shell_code[ idx ][ 1 ] ) =
|
|
||||||
static_cast< u32 >( call_map[ idx ].second );
|
|
||||||
|
|
||||||
// second push encrypted rva value...
|
|
||||||
*reinterpret_cast< u32 * >( &__vmcall_shell_code[ idx ][ 6 ] ) =
|
|
||||||
static_cast< u32 >( call_map[ idx ].second );
|
|
||||||
|
|
||||||
// signed rip relative rva to vm entry...
|
|
||||||
*reinterpret_cast< u32 * >( &__vmcall_shell_code[ idx ][ 11 ] ) = reinterpret_cast< s32 >(
|
|
||||||
( map_area - ( reinterpret_cast< u64 >( &__vmcall_shell_code[ idx ] ) + 15 ) ) + entry_rva );
|
|
||||||
}
|
|
||||||
|
|
||||||
return true; // only a bool so i can use static/call init only once...
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
__declspec( allocate( ".xmp2" ) ) inline _gen_data gen_data;
|
|
||||||
|
|
||||||
template < calls e_call, class T, class... Ts > auto call( Ts... args ) -> T
|
|
||||||
{
|
|
||||||
static auto __init_result = gen_data.init();
|
|
||||||
|
|
||||||
__vmcall_t vmcall = nullptr;
|
|
||||||
for ( auto idx = 0u; idx < sizeof( call_map ) / sizeof( _pair_t< u8, calls > ); ++idx )
|
|
||||||
if ( call_map[ idx ].second == e_call )
|
|
||||||
vmcall = reinterpret_cast< __vmcall_t >( &gen_data.__vmcall_shell_code[ idx ] );
|
|
||||||
|
|
||||||
return reinterpret_cast< T >( vmcall( args... ) );
|
|
||||||
}
|
|
||||||
} // namespace vm
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
vm::call< vm::calls::get_hello, void * >();
|
|
||||||
}
|
|
@ -1,93 +0,0 @@
|
|||||||
get_hello:
|
|
||||||
SREGQ 0x90
|
|
||||||
SREGQ 0x88
|
|
||||||
SREGQ 0x80
|
|
||||||
SREGQ 0x78
|
|
||||||
SREGQ 0x70
|
|
||||||
SREGQ 0x68
|
|
||||||
SREGQ 0x60
|
|
||||||
SREGQ 0x58
|
|
||||||
SREGQ 0x50
|
|
||||||
SREGQ 0x48
|
|
||||||
SREGQ 0x40
|
|
||||||
SREGQ 0x38
|
|
||||||
SREGQ 0x30
|
|
||||||
SREGQ 0x28
|
|
||||||
SREGQ 0x20
|
|
||||||
SREGQ 0x18
|
|
||||||
SREGQ 0x10
|
|
||||||
SREGQ 0x8
|
|
||||||
SREGQ 0x0
|
|
||||||
|
|
||||||
LCONSTQ 0x6F6C6C6568
|
|
||||||
SREGQ 0x78
|
|
||||||
SREGQ 0x0
|
|
||||||
SREGQ 0x0
|
|
||||||
|
|
||||||
LREGQ 0x0
|
|
||||||
LREGQ 0x8
|
|
||||||
LREGQ 0x10
|
|
||||||
LREGQ 0x18
|
|
||||||
LREGQ 0x20
|
|
||||||
LREGQ 0x28
|
|
||||||
LREGQ 0x30
|
|
||||||
LREGQ 0x38
|
|
||||||
LREGQ 0x40
|
|
||||||
LREGQ 0x48
|
|
||||||
LREGQ 0x50
|
|
||||||
LREGQ 0x58
|
|
||||||
LREGQ 0x60
|
|
||||||
LREGQ 0x68
|
|
||||||
LREGQ 0x70
|
|
||||||
LREGQ 0x78
|
|
||||||
LREGQ 0x80
|
|
||||||
LREGQ 0x88
|
|
||||||
LREGQ 0x90
|
|
||||||
VMEXIT
|
|
||||||
|
|
||||||
get_world:
|
|
||||||
SREGQ 0x90
|
|
||||||
SREGQ 0x88
|
|
||||||
SREGQ 0x80
|
|
||||||
SREGQ 0x78
|
|
||||||
SREGQ 0x70
|
|
||||||
SREGQ 0x68
|
|
||||||
SREGQ 0x60
|
|
||||||
SREGQ 0x58
|
|
||||||
SREGQ 0x50
|
|
||||||
SREGQ 0x48
|
|
||||||
SREGQ 0x40
|
|
||||||
SREGQ 0x38
|
|
||||||
SREGQ 0x30
|
|
||||||
SREGQ 0x28
|
|
||||||
SREGQ 0x20
|
|
||||||
SREGQ 0x18
|
|
||||||
SREGQ 0x10
|
|
||||||
SREGQ 0x8
|
|
||||||
SREGQ 0x0
|
|
||||||
|
|
||||||
LCONSTQ 0x646C726F77
|
|
||||||
SREGQ 0x78
|
|
||||||
SREGQ 0x0
|
|
||||||
SREGQ 0x0
|
|
||||||
|
|
||||||
LREGQ 0x0
|
|
||||||
LREGQ 0x8
|
|
||||||
LREGQ 0x10
|
|
||||||
LREGQ 0x18
|
|
||||||
LREGQ 0x20
|
|
||||||
LREGQ 0x28
|
|
||||||
LREGQ 0x30
|
|
||||||
LREGQ 0x38
|
|
||||||
LREGQ 0x40
|
|
||||||
LREGQ 0x48
|
|
||||||
LREGQ 0x50
|
|
||||||
LREGQ 0x58
|
|
||||||
LREGQ 0x60
|
|
||||||
LREGQ 0x68
|
|
||||||
LREGQ 0x70
|
|
||||||
LREGQ 0x78
|
|
||||||
LREGQ 0x80
|
|
||||||
LREGQ 0x88
|
|
||||||
LREGQ 0x90
|
|
||||||
VMEXIT
|
|
@ -1,22 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <cstdint>
|
|
||||||
#define VASM_MAGIC 'MSAV'
|
|
||||||
|
|
||||||
namespace vmasm
|
|
||||||
{
|
|
||||||
enum class version_t
|
|
||||||
{
|
|
||||||
v1
|
|
||||||
};
|
|
||||||
|
|
||||||
struct file_header_t
|
|
||||||
{
|
|
||||||
std::uint32_t magic; // VASM
|
|
||||||
version_t version;
|
|
||||||
std::uint64_t epoch_time;
|
|
||||||
std::uint64_t alloc_rva;
|
|
||||||
std::uint64_t encrypted_rva;
|
|
||||||
std::uint32_t vasm_size;
|
|
||||||
std::uint32_t vasm_offset;
|
|
||||||
};
|
|
||||||
} // namespace vmasm
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue