You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
vmassembler/src/gen_header_template.h

80 lines
2.8 KiB

#pragma once
#pragma section( ".xmp2" )
#pragma comment( linker, "/section:.xmp2,RWE" )
using u8 = unsigned char;
using u16 = unsigned short;
using u32 = unsigned int;
using u64 = unsigned long long;
using __vmcall_t = void *( * )( ... );
namespace vm
{
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 __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()
{
for ( auto idx = 0u; idx < ( sizeof( __vmcall_shell_code ) / 15 ); ++idx )
{
*reinterpret_cast< u32 * >( &__vmcall_shell_code[ idx ][ 1 ] ) =
static_cast< u32 >( call_map[ idx ].second );
*reinterpret_cast< u32 * >( &__vmcall_shell_code[ idx ][ 6 ] ) =
static_cast< u32 >( call_map[ idx ].second );
*reinterpret_cast< u32 * >( &__vmcall_shell_code[ idx ][ 11 ] ) = reinterpret_cast< u32 >(
( bin - ( reinterpret_cast< u64 >( &__vmcall_shell_code[ idx ] ) + 15 ) ) + entry_rva );
}
return true; // only a bool so i can use static/call 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 * >( "hello world" );
}