parent
8e3436b01e
commit
1cb0d10e20
@ -1,31 +1,80 @@
|
||||
#pragma once
|
||||
#pragma section( ".xmp2" )
|
||||
#pragma comment( linker, "/section:.xmp2,RWE" )
|
||||
using __vmcall_t = void* (*)(...);
|
||||
|
||||
using u8 = unsigned char;
|
||||
using u16 = unsigned short;
|
||||
using u32 = unsigned int;
|
||||
using u64 = unsigned long long;
|
||||
using __vmcall_t = void *( * )( ... );
|
||||
|
||||
namespace vm
|
||||
{
|
||||
struct _gen_data
|
||||
constexpr auto entry_rva = 0x1000;
|
||||
|
||||
enum class calls : u32
|
||||
{
|
||||
get_world = 0xBFFD6FE9,
|
||||
get_hello = 0xBFFD6FDD
|
||||
};
|
||||
|
||||
template < class T, class U > struct _pair_t
|
||||
{
|
||||
unsigned char __vmcall_shell_code[3] = {0x0, 0x0, 0x0};
|
||||
} __declspec( allocate( ".xmp2" ) ) gen_data;
|
||||
T first;
|
||||
U second;
|
||||
};
|
||||
|
||||
inline __vmcall_t __vmcall = reinterpret_cast< __vmcall_t >( gen_data.__vmcall_shell_code );
|
||||
inline _pair_t< u8, calls > call_map[ 2 ] = { { 0, calls::get_world }, { 1, calls::get_hello } };
|
||||
|
||||
enum class calls : unsigned long long
|
||||
struct _gen_data
|
||||
{
|
||||
get_world = 0xBFFD6FE9,
|
||||
get_hello = 0xBFFD6FE9
|
||||
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...
|
||||
}
|
||||
};
|
||||
|
||||
template < class T, class... Ts > T call( vm::calls e_call, Ts... args )
|
||||
__declspec( allocate( ".xmp2" ) ) inline _gen_data gen_data;
|
||||
|
||||
template < calls e_call, class T, class... Ts > auto call( Ts... args ) -> T
|
||||
{
|
||||
return reinterpret_cast< T >( __vmcall( e_call, args ) );
|
||||
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<unsigned long long>( vm::calls::get_hello );
|
||||
|
||||
vm::call< vm::calls::get_hello, void * >( "hello world" );
|
||||
}
|
Loading…
Reference in new issue