still working on it, got it like 80% done working on gen files..

merge-requests/2/head
_xeroxz 4 years ago
parent a371b2f00e
commit 8e3436b01e

@ -5,19 +5,26 @@ namespace vm
compiler_t::compiler_t( vm::ctx_t *vmctx ) : vmctx( vmctx ) compiler_t::compiler_t( vm::ctx_t *vmctx ) : vmctx( vmctx )
{ {
if ( !parse_t::get_instance()->for_each( [ & ]( _vlabel_meta *label_data ) -> bool { if ( !parse_t::get_instance()->for_each( [ & ]( _vlabel_meta *label_data ) -> bool {
for ( const auto &vinstr : label_data->vinstrs ) std::printf( "> checking label %s for invalid instructions... number of instructions = %d\n",
{ label_data->label_name.c_str(), label_data->vinstrs.size() );
std::printf( "> vinstr name = %s, has imm = %d, imm = 0x%p\n", vinstr.name.c_str(), vinstr.has_imm,
vinstr.imm ); const auto result = std::find_if(
label_data->vinstrs.begin(), label_data->vinstrs.end(),
for ( auto &vm_handler : vmctx->vm_handlers ) [ & ]( const _vinstr_meta &vinstr ) -> bool {
if ( vm_handler.profile && vm_handler.profile->name == vinstr.name ) std::printf( "> vinstr name = %s, has imm = %d, imm = 0x%p\n", vinstr.name.c_str(),
return true; vinstr.has_imm, vinstr.imm );
std::printf( "[!] this vm protected file does not have the vm handler for: %s...\n", for ( auto &vm_handler : vmctx->vm_handlers )
vinstr.name.c_str() ); if ( vm_handler.profile && vm_handler.profile->name == vinstr.name )
} return false;
return false;
std::printf( "[!] this vm protected file does not have the vm handler for: %s...\n",
vinstr.name.c_str() );
return true;
} );
return result == label_data->vinstrs.end();
} ) ) } ) )
{ {
std::printf( "[!] binary does not have the required vm handlers...\n" ); std::printf( "[!] binary does not have the required vm handlers...\n" );
@ -46,15 +53,15 @@ namespace vm
std::vector< vlabel_data > *compiler_t::encode() std::vector< vlabel_data > *compiler_t::encode()
{ {
parse_t::get_instance()->for_each( [ & ]( _vlabel_meta *label_data ) -> bool { parse_t::get_instance()->for_each( [ & ]( _vlabel_meta *label_data ) -> bool {
virt_labels.push_back( { label_data->label_name } );
for ( const auto &vinstr : label_data->vinstrs ) for ( const auto &vinstr : label_data->vinstrs )
{ {
for ( auto itr = vmctx->vm_handlers.begin(); itr != vmctx->vm_handlers.end(); ++itr ) for ( auto itr = vmctx->vm_handlers.begin(); itr != vmctx->vm_handlers.end(); ++itr )
{ {
virt_labels.push_back( { label_data->label_name } );
if ( itr->profile && itr->profile->name == vinstr.name ) if ( itr->profile && itr->profile->name == vinstr.name )
{ {
virt_labels.back().vinstrs.push_back( { ( std::uint8_t )( itr - vmctx->vm_handlers.begin() ), virt_labels.back().vinstrs.push_back( { ( std::uint8_t )( itr - vmctx->vm_handlers.begin() ),
vinstr.imm, itr->profile->imm_size } ); vinstr.imm, itr->profile->imm_size } );
break; break;
} }
} }
@ -75,8 +82,10 @@ namespace vm
std::uintptr_t decrypt_key = end_of_module, start_addr; std::uintptr_t decrypt_key = end_of_module, start_addr;
if ( vmctx->exec_type == vmp2::exec_type_t::backward ) if ( vmctx->exec_type == vmp2::exec_type_t::backward )
{ {
std::for_each( virt_labels.begin(), virt_labels.end(), [ & ]( const vinstr_data &vinstr ) { std::for_each( virt_labels.begin(), virt_labels.end(), [ & ]( const vlabel_data &label ) {
( ++decrypt_key ) += vinstr.imm_size ? vinstr.imm_size / 8 : 0; std::for_each( label.vinstrs.begin(), label.vinstrs.end(), [ & ]( const vinstr_data &vinstr ) {
( ++decrypt_key ) += vinstr.imm_size ? vinstr.imm_size / 8 : 0;
} );
} ); } );
} }
start_addr = decrypt_key; start_addr = decrypt_key;
@ -92,8 +101,6 @@ namespace vm
for ( auto &vinstr : label.vinstrs ) for ( auto &vinstr : label.vinstrs )
{ {
std::printf( "> decrypt key = 0x%p\n", decrypt_key );
auto vm_handler_idx = vinstr.vm_handler; auto vm_handler_idx = vinstr.vm_handler;
std::tie( vinstr.vm_handler, decrypt_key ) = std::tie( vinstr.vm_handler, decrypt_key ) =
vm::instrs::encrypt_operand( calc_jmp_transforms, vinstr.vm_handler, decrypt_key ); vm::instrs::encrypt_operand( calc_jmp_transforms, vinstr.vm_handler, decrypt_key );
@ -135,15 +142,10 @@ namespace vm
std::uint64_t compiler_t::encrypt_rva( std::uint64_t rva ) std::uint64_t compiler_t::encrypt_rva( std::uint64_t rva )
{ {
std::printf( "> encrypt virtual instruction rva transformations:\n" );
for ( auto &transform : encrypt_vinstrs_rva )
vm::util::print( transform );
for ( auto &instr : encrypt_vinstrs_rva ) for ( auto &instr : encrypt_vinstrs_rva )
rva = vm::transform::apply( instr.operands[ 0 ].size, instr.mnemonic, rva, rva = vm::transform::apply( instr.operands[ 0 ].size, instr.mnemonic, rva,
transform::has_imm( &instr ) ? instr.operands[ 1 ].imm.value.u : 0 ); transform::has_imm( &instr ) ? instr.operands[ 1 ].imm.value.u : 0 );
std::printf( "> encrypted rva = 0x%p\n", rva );
return rva; return rva;
} }
} // namespace vm } // namespace vm

@ -0,0 +1,31 @@
#pragma once
#pragma section( ".xmp2" )
#pragma comment( linker, "/section:.xmp2,RWE" )
using __vmcall_t = void* (*)(...);
namespace vm
{
struct _gen_data
{
unsigned char __vmcall_shell_code[3] = {0x0, 0x0, 0x0};
} __declspec( allocate( ".xmp2" ) ) gen_data;
inline __vmcall_t __vmcall = reinterpret_cast< __vmcall_t >( gen_data.__vmcall_shell_code );
enum class calls : unsigned long long
{
get_world = 0xBFFD6FE9,
get_hello = 0xBFFD6FE9
};
template < class T, class... Ts > T call( vm::calls e_call, Ts... args )
{
return reinterpret_cast< T >( __vmcall( e_call, args ) );
}
} // namespace vm
int main()
{
vm::call<unsigned long long>( vm::calls::get_hello );
}

@ -352,8 +352,8 @@ static void yynoreturn yy_fatal_error ( const char* msg );
(yy_hold_char) = *yy_cp; \ (yy_hold_char) = *yy_cp; \
*yy_cp = '\0'; \ *yy_cp = '\0'; \
(yy_c_buf_p) = yy_cp; (yy_c_buf_p) = yy_cp;
#define YY_NUM_RULES 5 #define YY_NUM_RULES 6
#define YY_END_OF_BUFFER 6 #define YY_END_OF_BUFFER 7
/* This struct is not used in this scanner, /* This struct is not used in this scanner,
but its presence is necessary. */ but its presence is necessary. */
struct yy_trans_info struct yy_trans_info
@ -361,10 +361,10 @@ struct yy_trans_info
flex_int32_t yy_verify; flex_int32_t yy_verify;
flex_int32_t yy_nxt; flex_int32_t yy_nxt;
}; };
static const flex_int16_t yy_accept[13] = static const flex_int16_t yy_accept[14] =
{ 0, { 0,
0, 0, 6, 5, 4, 3, 2, 2, 2, 2, 0, 0, 7, 6, 5, 4, 3, 3, 3, 2,
1, 0 3, 1, 0
} ; } ;
static const YY_CHAR yy_ec[256] = static const YY_CHAR yy_ec[256] =
@ -374,15 +374,15 @@ static const YY_CHAR yy_ec[256] =
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 4, 5, 5, 1, 1, 1, 1, 1, 1, 1, 4, 5, 5,
5, 5, 5, 5, 5, 5, 5, 1, 1, 1, 5, 5, 5, 5, 5, 5, 5, 6, 1, 1,
1, 1, 2, 1, 5, 5, 5, 5, 5, 5, 1, 1, 2, 1, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
6, 6, 6, 6, 6, 6, 6, 7, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 7, 7,
1, 1, 1, 1, 6, 1, 5, 5, 5, 5, 1, 1, 1, 1, 7, 1, 5, 5, 5, 5,
5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7,
6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8,
6, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@ -399,33 +399,35 @@ static const YY_CHAR yy_ec[256] =
1, 1, 1, 1, 1 1, 1, 1, 1, 1
} ; } ;
static const YY_CHAR yy_meta[8] = static const YY_CHAR yy_meta[9] =
{ 0, { 0,
1, 1, 1, 2, 2, 2, 2 1, 1, 1, 2, 2, 2, 2, 2
} ; } ;
static const flex_int16_t yy_base[14] = static const flex_int16_t yy_base[15] =
{ 0, { 0,
0, 0, 12, 13, 13, 13, 4, 0, 0, 4, 0, 0, 15, 16, 16, 16, 3, 8, 0, 16,
0, 13, 8 8, 0, 16, 8
} ; } ;
static const flex_int16_t yy_def[14] = static const flex_int16_t yy_def[15] =
{ 0, { 0,
12, 1, 12, 12, 12, 12, 13, 13, 13, 13, 13, 1, 13, 13, 13, 13, 14, 14, 8, 13,
10, 0, 12 8, 11, 0, 13
} ; } ;
static const flex_int16_t yy_nxt[21] = static const flex_int16_t yy_nxt[25] =
{ 0, { 0,
4, 5, 6, 7, 8, 8, 8, 11, 11, 9, 4, 5, 6, 7, 8, 4, 8, 8, 10, 9,
10, 12, 3, 12, 12, 12, 12, 12, 12, 12 11, 12, 12, 10, 13, 3, 13, 13, 13, 13,
13, 13, 13, 13
} ; } ;
static const flex_int16_t yy_chk[21] = static const flex_int16_t yy_chk[25] =
{ 0, { 0,
1, 1, 1, 1, 1, 1, 1, 10, 10, 13, 1, 1, 1, 1, 1, 1, 1, 1, 7, 14,
7, 3, 12, 12, 12, 12, 12, 12, 12, 12 7, 11, 11, 8, 3, 13, 13, 13, 13, 13,
13, 13, 13, 13
} ; } ;
static yy_state_type yy_last_accepting_state; static yy_state_type yy_last_accepting_state;
@ -446,8 +448,8 @@ char *yytext;
#line 2 "lexer.l" #line 2 "lexer.l"
#include "parser.tab.h" #include "parser.tab.h"
#include <stdlib.h> #include <stdlib.h>
#line 449 "lexer.flex.cpp" #line 451 "lexer.flex.cpp"
#line 450 "lexer.flex.cpp" #line 452 "lexer.flex.cpp"
#define INITIAL 0 #define INITIAL 0
@ -663,7 +665,7 @@ YY_DECL
{ {
#line 6 "lexer.l" #line 6 "lexer.l"
#line 666 "lexer.flex.cpp" #line 668 "lexer.flex.cpp"
while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
{ {
@ -690,13 +692,13 @@ yy_match:
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{ {
yy_current_state = (int) yy_def[yy_current_state]; yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 13 ) if ( yy_current_state >= 14 )
yy_c = yy_meta[yy_c]; yy_c = yy_meta[yy_c];
} }
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
++yy_cp; ++yy_cp;
} }
while ( yy_base[yy_current_state] != 13 ); while ( yy_base[yy_current_state] != 16 );
yy_find_action: yy_find_action:
yy_act = yy_accept[yy_current_state]; yy_act = yy_accept[yy_current_state];
@ -728,26 +730,31 @@ YY_RULE_SETUP
case 2: case 2:
YY_RULE_SETUP YY_RULE_SETUP
#line 8 "lexer.l" #line 8 "lexer.l"
{ strcpy(yylval.vinstr_name, yytext); return VINSTR; } { strcpy(yylval.label_name, yytext); return LABEL; }
YY_BREAK YY_BREAK
case 3: case 3:
/* rule 3 can match eol */
YY_RULE_SETUP YY_RULE_SETUP
#line 9 "lexer.l" #line 9 "lexer.l"
{ yylineno++; } { strcpy(yylval.vinstr_name, yytext); return VINSTR; }
YY_BREAK YY_BREAK
case 4: case 4:
/* rule 4 can match eol */ /* rule 4 can match eol */
YY_RULE_SETUP YY_RULE_SETUP
#line 10 "lexer.l" #line 10 "lexer.l"
{ yylineno++; }
YY_BREAK YY_BREAK
case 5: case 5:
/* rule 5 can match eol */
YY_RULE_SETUP YY_RULE_SETUP
#line 11 "lexer.l" #line 11 "lexer.l"
YY_BREAK
case 6:
YY_RULE_SETUP
#line 12 "lexer.l"
ECHO; ECHO;
YY_BREAK YY_BREAK
#line 750 "lexer.flex.cpp" #line 757 "lexer.flex.cpp"
case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(INITIAL):
yyterminate(); yyterminate();
@ -1044,7 +1051,7 @@ static int yy_get_next_buffer (void)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{ {
yy_current_state = (int) yy_def[yy_current_state]; yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 13 ) if ( yy_current_state >= 14 )
yy_c = yy_meta[yy_c]; yy_c = yy_meta[yy_c];
} }
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
@ -1072,11 +1079,11 @@ static int yy_get_next_buffer (void)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{ {
yy_current_state = (int) yy_def[yy_current_state]; yy_current_state = (int) yy_def[yy_current_state];
if ( yy_current_state >= 13 ) if ( yy_current_state >= 14 )
yy_c = yy_meta[yy_c]; yy_c = yy_meta[yy_c];
} }
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
yy_is_jam = (yy_current_state == 12); yy_is_jam = (yy_current_state == 13);
return yy_is_jam ? 0 : yy_current_state; return yy_is_jam ? 0 : yy_current_state;
} }
@ -1752,5 +1759,5 @@ void yyfree (void * ptr )
#define YYTABLES_NAME "yytables" #define YYTABLES_NAME "yytables"
#line 11 "lexer.l" #line 12 "lexer.l"

@ -5,6 +5,7 @@
%% %%
0[xX][0-9a-fA-F]+ { yylval.imm_val = strtoull(yytext, nullptr, 16); return IMM; } 0[xX][0-9a-fA-F]+ { yylval.imm_val = strtoull(yytext, nullptr, 16); return IMM; }
[a-zA-Z0-9_]+: { strcpy(yylval.label_name, yytext); return LABEL; }
[a-zA-Z0-9_]+ { strcpy(yylval.vinstr_name, yytext); return VINSTR; } [a-zA-Z0-9_]+ { strcpy(yylval.vinstr_name, yytext); return VINSTR; }
"\n" { yylineno++; } "\n" { yylineno++; }
[ ?\t\n\r] [ ?\t\n\r]

@ -10,6 +10,7 @@
#include "parser.h" #include "parser.h"
#include "parser.tab.h" #include "parser.tab.h"
#include "vmasm.hpp" #include "vmasm.hpp"
#include "vmprofiler.hpp"
extern FILE *yyin; extern FILE *yyin;
extern "C" int yywrap() extern "C" int yywrap()
@ -87,6 +88,11 @@ int __cdecl main( int argc, const char *argv[] )
return -1; return -1;
} }
std::printf( "> flattened and deobfuscated vm entry...\n" );
vm::util::print( vmctx.vm_entry );
std::printf( "> extracted calc jmp from vm entry...\n" );
vm::util::print( vmctx.calc_jmp );
vm::compiler_t compiler( &vmctx ); vm::compiler_t compiler( &vmctx );
// //
@ -116,19 +122,16 @@ int __cdecl main( int argc, const char *argv[] )
for ( const auto &label : compiled_labels ) for ( const auto &label : compiled_labels )
{ {
std::printf( "> %s must be allocated at = 0x%p\n", label.label_name.c_str(), label.alloc_rva ); std::printf( "> %s must be allocated at = 0x%p, encrypted rva = 0x%p\n", label.label_name.c_str(),
label.alloc_rva, label.enc_alloc_rva );
std::printf( "> " ); std::printf( "> " );
{ {
auto idx = 0u; auto idx = 0u;
for ( auto byte : label.vinstrs ) for ( auto byte : label.vinstrs )
{
std::printf( "0x%x ", byte ); std::printf( "0x%x ", byte );
if ( ++idx == 10 )
{ std::printf( "\n" );
std::printf( "\n" );
idx = 0u;
}
}
} }
} }

@ -7,7 +7,6 @@
struct _vinstr_meta struct _vinstr_meta
{ {
std::string name; std::string name;
bool has_imm; bool has_imm;
std::uintptr_t imm; std::uintptr_t imm;
}; };
@ -30,8 +29,7 @@ class parse_t
void add_vinstr( std::string vinstr_name ); void add_vinstr( std::string vinstr_name );
void add_vinstr( std::string vinstr_name, std::uintptr_t imm_val ); void add_vinstr( std::string vinstr_name, std::uintptr_t imm_val );
bool for_each( callback_t callback ); bool for_each( callback_t callback );
std::vector< _vlabel_meta > virt_labels;
private: private:
parse_t(); parse_t();
std::vector< _vlabel_meta > virt_labels;
}; };

@ -108,8 +108,9 @@ extern int yydebug;
/* Put the tokens into the symbol table, so that GDB and other debuggers /* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */ know about them. */
enum yytokentype { enum yytokentype {
VINSTR = 258, LABEL = 258,
IMM = 259 VINSTR = 259,
IMM = 260
}; };
#endif #endif
@ -121,11 +122,12 @@ typedef union YYSTYPE
#line 10 "parser.y" #line 10 "parser.y"
char vinstr_name[20]; char vinstr_name[20];
char label_name[256];
unsigned long long imm_val; unsigned long long imm_val;
/* Line 387 of yacc.c */ /* Line 387 of yacc.c */
#line 129 "parser.tab.cpp" #line 131 "parser.tab.cpp"
} YYSTYPE; } YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define yystype YYSTYPE /* obsolescent; will be withdrawn */
@ -153,7 +155,7 @@ int yyparse ();
/* Copy the second part of user declarations. */ /* Copy the second part of user declarations. */
/* Line 390 of yacc.c */ /* Line 390 of yacc.c */
#line 157 "parser.tab.cpp" #line 159 "parser.tab.cpp"
#ifdef short #ifdef short
# undef short # undef short
@ -371,22 +373,22 @@ union yyalloc
#endif /* !YYCOPY_NEEDED */ #endif /* !YYCOPY_NEEDED */
/* YYFINAL -- State number of the termination state. */ /* YYFINAL -- State number of the termination state. */
#define YYFINAL 4 #define YYFINAL 3
/* YYLAST -- Last index in YYTABLE. */ /* YYLAST -- Last index in YYTABLE. */
#define YYLAST 6 #define YYLAST 7
/* YYNTOKENS -- Number of terminals. */ /* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS 5 #define YYNTOKENS 6
/* YYNNTS -- Number of nonterminals. */ /* YYNNTS -- Number of nonterminals. */
#define YYNNTS 2 #define YYNNTS 3
/* YYNRULES -- Number of rules. */ /* YYNRULES -- Number of rules. */
#define YYNRULES 5 #define YYNRULES 9
/* YYNRULES -- Number of states. */ /* YYNRULES -- Number of states. */
#define YYNSTATES 7 #define YYNSTATES 10
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2 #define YYUNDEFTOK 2
#define YYMAXUTOK 259 #define YYMAXUTOK 260
#define YYTRANSLATE(YYX) \ #define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@ -419,7 +421,8 @@ static const yytype_uint8 yytranslate[] =
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 1, 2, 3, 4 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
5
}; };
#if YYDEBUG #if YYDEBUG
@ -427,20 +430,21 @@ static const yytype_uint8 yytranslate[] =
YYRHS. */ YYRHS. */
static const yytype_uint8 yyprhs[] = static const yytype_uint8 yyprhs[] =
{ {
0, 0, 3, 5, 8, 11 0, 0, 3, 5, 8, 11, 12, 14, 17, 20
}; };
/* YYRHS -- A `-1'-separated list of the rules' RHS. */ /* YYRHS -- A `-1'-separated list of the rules' RHS. */
static const yytype_int8 yyrhs[] = static const yytype_int8 yyrhs[] =
{ {
6, 0, -1, 3, -1, 3, 4, -1, 6, 3, 7, 0, -1, 3, -1, 7, 3, -1, 7, 8,
-1, 6, 3, 4, -1 -1, -1, 4, -1, 4, 5, -1, 8, 4, -1,
8, 4, 5, -1
}; };
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint8 yyrline[] = static const yytype_uint8 yyrline[] =
{ {
0, 20, 20, 21, 22, 23 0, 22, 22, 23, 24, 25, 29, 30, 31, 32
}; };
#endif #endif
@ -449,7 +453,8 @@ static const yytype_uint8 yyrline[] =
First, the terminals, then, starting at YYNTOKENS, nonterminals. */ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] = static const char *const yytname[] =
{ {
"$end", "error", "$undefined", "VINSTR", "IMM", "$accept", "PROGRAM", YY_NULL "$end", "error", "$undefined", "LABEL", "VINSTR", "IMM", "$accept",
"PROGRAM", "VINSTRS", YY_NULL
}; };
#endif #endif
@ -458,20 +463,20 @@ static const char *const yytname[] =
token YYLEX-NUM. */ token YYLEX-NUM. */
static const yytype_uint16 yytoknum[] = static const yytype_uint16 yytoknum[] =
{ {
0, 256, 257, 258, 259 0, 256, 257, 258, 259, 260
}; };
# endif # endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const yytype_uint8 yyr1[] = static const yytype_uint8 yyr1[] =
{ {
0, 5, 6, 6, 6, 6 0, 6, 7, 7, 7, 7, 8, 8, 8, 8
}; };
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
static const yytype_uint8 yyr2[] = static const yytype_uint8 yyr2[] =
{ {
0, 2, 1, 2, 2, 3 0, 2, 1, 2, 2, 0, 1, 2, 2, 3
}; };
/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
@ -479,27 +484,27 @@ static const yytype_uint8 yyr2[] =
means the default is an error. */ means the default is an error. */
static const yytype_uint8 yydefact[] = static const yytype_uint8 yydefact[] =
{ {
0, 2, 0, 3, 1, 4, 5 5, 2, 0, 1, 3, 6, 4, 7, 8, 9
}; };
/* YYDEFGOTO[NTERM-NUM]. */ /* YYDEFGOTO[NTERM-NUM]. */
static const yytype_int8 yydefgoto[] = static const yytype_int8 yydefgoto[] =
{ {
-1, 2 -1, 2, 6
}; };
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */ STATE-NUM. */
#define YYPACT_NINF -3 #define YYPACT_NINF -4
static const yytype_int8 yypact[] = static const yytype_int8 yypact[] =
{ {
-2, 1, 0, -3, -3, 2, -3 -2, -4, 0, -4, -4, -3, 1, -4, 2, -4
}; };
/* YYPGOTO[NTERM-NUM]. */ /* YYPGOTO[NTERM-NUM]. */
static const yytype_int8 yypgoto[] = static const yytype_int8 yypgoto[] =
{ {
-3, -3 -4, -4, -4
}; };
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
@ -508,25 +513,25 @@ static const yytype_int8 yypgoto[] =
#define YYTABLE_NINF -1 #define YYTABLE_NINF -1
static const yytype_uint8 yytable[] = static const yytype_uint8 yytable[] =
{ {
4, 1, 0, 5, 0, 3, 6 3, 1, 7, 4, 5, 8, 0, 9
}; };
#define yypact_value_is_default(Yystate) \ #define yypact_value_is_default(Yystate) \
(!!((Yystate) == (-3))) (!!((Yystate) == (-4)))
#define yytable_value_is_error(Yytable_value) \ #define yytable_value_is_error(Yytable_value) \
YYID (0) YYID (0)
static const yytype_int8 yycheck[] = static const yytype_int8 yycheck[] =
{ {
0, 3, -1, 3, -1, 4, 4 0, 3, 5, 3, 4, 4, -1, 5
}; };
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */ symbol of state STATE-NUM. */
static const yytype_uint8 yystos[] = static const yytype_uint8 yystos[] =
{ {
0, 3, 6, 4, 0, 3, 4 0, 3, 7, 0, 3, 4, 8, 5, 4, 5
}; };
#define yyerrok (yyerrstatus = 0) #define yyerrok (yyerrstatus = 0)
@ -1328,31 +1333,43 @@ yyreduce:
{ {
case 2: case 2:
/* Line 1792 of yacc.c */ /* Line 1792 of yacc.c */
#line 20 "parser.y" #line 22 "parser.y"
{ parse_t::get_instance()->add_vinstr((yyvsp[(1) - (1)].vinstr_name)); } { parse_t::get_instance()->add_label((yyvsp[(1) - (1)].label_name)); }
break; break;
case 3: case 3:
/* Line 1792 of yacc.c */ /* Line 1792 of yacc.c */
#line 21 "parser.y" #line 23 "parser.y"
{ parse_t::get_instance()->add_label((yyvsp[(2) - (2)].label_name)); }
break;
case 6:
/* Line 1792 of yacc.c */
#line 29 "parser.y"
{ parse_t::get_instance()->add_vinstr((yyvsp[(1) - (1)].vinstr_name)); }
break;
case 7:
/* Line 1792 of yacc.c */
#line 30 "parser.y"
{ parse_t::get_instance()->add_vinstr((yyvsp[(1) - (2)].vinstr_name), (yyvsp[(2) - (2)].imm_val)); } { parse_t::get_instance()->add_vinstr((yyvsp[(1) - (2)].vinstr_name), (yyvsp[(2) - (2)].imm_val)); }
break; break;
case 4: case 8:
/* Line 1792 of yacc.c */ /* Line 1792 of yacc.c */
#line 22 "parser.y" #line 31 "parser.y"
{ parse_t::get_instance()->add_vinstr((yyvsp[(2) - (2)].vinstr_name)); } { parse_t::get_instance()->add_vinstr((yyvsp[(2) - (2)].vinstr_name)); }
break; break;
case 5: case 9:
/* Line 1792 of yacc.c */ /* Line 1792 of yacc.c */
#line 23 "parser.y" #line 32 "parser.y"
{ parse_t::get_instance()->add_vinstr((yyvsp[(2) - (3)].vinstr_name), (yyvsp[(3) - (3)].imm_val)); } { parse_t::get_instance()->add_vinstr((yyvsp[(2) - (3)].vinstr_name), (yyvsp[(3) - (3)].imm_val)); }
break; break;
/* Line 1792 of yacc.c */ /* Line 1792 of yacc.c */
#line 1356 "parser.tab.cpp" #line 1373 "parser.tab.cpp"
default: break; default: break;
} }
/* User semantic actions sometimes alter yychar, and that requires /* User semantic actions sometimes alter yychar, and that requires
@ -1584,4 +1601,4 @@ yyreturn:
/* Line 2055 of yacc.c */ /* Line 2055 of yacc.c */
#line 25 "parser.y" #line 34 "parser.y"

@ -46,8 +46,9 @@ extern int yydebug;
/* Put the tokens into the symbol table, so that GDB and other debuggers /* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */ know about them. */
enum yytokentype { enum yytokentype {
VINSTR = 258, LABEL = 258,
IMM = 259 VINSTR = 259,
IMM = 260
}; };
#endif #endif
@ -59,11 +60,12 @@ typedef union YYSTYPE
#line 10 "parser.y" #line 10 "parser.y"
char vinstr_name[20]; char vinstr_name[20];
char label_name[256];
unsigned long long imm_val; unsigned long long imm_val;
/* Line 2058 of yacc.c */ /* Line 2058 of yacc.c */
#line 67 "parser.tab.h" #line 69 "parser.tab.h"
} YYSTYPE; } YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define yystype YYSTYPE /* obsolescent; will be withdrawn */

@ -9,17 +9,26 @@ extern int yylineno;
%union { %union {
char vinstr_name[20]; char vinstr_name[20];
char label_name[256];
unsigned long long imm_val; unsigned long long imm_val;
} }
%token <label_name> LABEL
%token <vinstr_name> VINSTR %token <vinstr_name> VINSTR
%token <imm_val> IMM %token <imm_val> IMM
%% %%
PROGRAM: PROGRAM:
LABEL { parse_t::get_instance()->add_label($1); }
| PROGRAM LABEL { parse_t::get_instance()->add_label($2); }
| PROGRAM VINSTRS
|
;
VINSTRS:
VINSTR { parse_t::get_instance()->add_vinstr($1); } VINSTR { parse_t::get_instance()->add_vinstr($1); }
| VINSTR IMM { parse_t::get_instance()->add_vinstr($1, $2); } | VINSTR IMM { parse_t::get_instance()->add_vinstr($1, $2); }
| PROGRAM VINSTR { parse_t::get_instance()->add_vinstr($2); } | VINSTRS VINSTR { parse_t::get_instance()->add_vinstr($2); }
| PROGRAM VINSTR IMM { parse_t::get_instance()->add_vinstr($2, $3); } | VINSTRS VINSTR IMM { parse_t::get_instance()->add_vinstr($2, $3); }
; ;
%% %%

@ -1,11 +1,9 @@
SREGQ 0x0 get_hello:
SREGQ 0x10 LCONSTQ 0x10000
SREGQ 0x20 SREGQ 0x10
LCONSTQ 0x10 VMEXIT
LCONSTQ 0x10
ADDQ get_world:
SREGQ 0x0 LCONSTQ 0x10000
SREGQ 0x10 SREGQ 0x10
LREGQ 0x20 VMEXIT
LREGQ 0x10
LREGQ 0x0

Binary file not shown.

Binary file not shown.

@ -44,6 +44,7 @@
<PreprocessorDefinitions>NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
<Optimization>Disabled</Optimization>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>

Binary file not shown.

@ -28,8 +28,8 @@ Global
{88A23124-5640-35A0-B890-311D7A67A7D2}.DBG|x64.Build.0 = Debug MT|x64 {88A23124-5640-35A0-B890-311D7A67A7D2}.DBG|x64.Build.0 = Debug MT|x64
{88A23124-5640-35A0-B890-311D7A67A7D2}.DBG|x86.ActiveCfg = Debug MT|Win32 {88A23124-5640-35A0-B890-311D7A67A7D2}.DBG|x86.ActiveCfg = Debug MT|Win32
{88A23124-5640-35A0-B890-311D7A67A7D2}.DBG|x86.Build.0 = Debug MT|Win32 {88A23124-5640-35A0-B890-311D7A67A7D2}.DBG|x86.Build.0 = Debug MT|Win32
{88A23124-5640-35A0-B890-311D7A67A7D2}.Release|x64.ActiveCfg = Release MD DLL|x64 {88A23124-5640-35A0-B890-311D7A67A7D2}.Release|x64.ActiveCfg = Release MT|x64
{88A23124-5640-35A0-B890-311D7A67A7D2}.Release|x64.Build.0 = Release MD DLL|x64 {88A23124-5640-35A0-B890-311D7A67A7D2}.Release|x64.Build.0 = Release MT|x64
{88A23124-5640-35A0-B890-311D7A67A7D2}.Release|x86.ActiveCfg = Release MT DLL|Win32 {88A23124-5640-35A0-B890-311D7A67A7D2}.Release|x86.ActiveCfg = Release MT DLL|Win32
{88A23124-5640-35A0-B890-311D7A67A7D2}.Release|x86.Build.0 = Release MT DLL|Win32 {88A23124-5640-35A0-B890-311D7A67A7D2}.Release|x86.Build.0 = Release MT DLL|Win32
{D0B6092A-9944-4F24-9486-4B7DAE372619}.DBG|x64.ActiveCfg = DBG|x64 {D0B6092A-9944-4F24-9486-4B7DAE372619}.DBG|x64.ActiveCfg = DBG|x64

Loading…
Cancel
Save