diff --git a/src/compiler.cpp b/src/compiler.cpp index 9294e2f..964c5b4 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -5,19 +5,26 @@ namespace vm compiler_t::compiler_t( vm::ctx_t *vmctx ) : vmctx( vmctx ) { if ( !parse_t::get_instance()->for_each( [ & ]( _vlabel_meta *label_data ) -> bool { - for ( const auto &vinstr : label_data->vinstrs ) - { - std::printf( "> vinstr name = %s, has imm = %d, imm = 0x%p\n", vinstr.name.c_str(), vinstr.has_imm, - vinstr.imm ); - - for ( auto &vm_handler : vmctx->vm_handlers ) - if ( vm_handler.profile && vm_handler.profile->name == vinstr.name ) - return true; - - std::printf( "[!] this vm protected file does not have the vm handler for: %s...\n", - vinstr.name.c_str() ); - } - return false; + std::printf( "> checking label %s for invalid instructions... number of instructions = %d\n", + label_data->label_name.c_str(), label_data->vinstrs.size() ); + + const auto result = std::find_if( + label_data->vinstrs.begin(), label_data->vinstrs.end(), + [ & ]( const _vinstr_meta &vinstr ) -> bool { + std::printf( "> vinstr name = %s, has imm = %d, imm = 0x%p\n", vinstr.name.c_str(), + vinstr.has_imm, vinstr.imm ); + + for ( auto &vm_handler : vmctx->vm_handlers ) + if ( vm_handler.profile && vm_handler.profile->name == vinstr.name ) + 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" ); @@ -46,15 +53,15 @@ namespace vm std::vector< vlabel_data > *compiler_t::encode() { 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 ( 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 ) { 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; } } @@ -75,8 +82,10 @@ namespace vm std::uintptr_t decrypt_key = end_of_module, start_addr; if ( vmctx->exec_type == vmp2::exec_type_t::backward ) { - std::for_each( virt_labels.begin(), virt_labels.end(), [ & ]( const vinstr_data &vinstr ) { - ( ++decrypt_key ) += vinstr.imm_size ? vinstr.imm_size / 8 : 0; + std::for_each( virt_labels.begin(), virt_labels.end(), [ & ]( const vlabel_data &label ) { + 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; @@ -92,8 +101,6 @@ namespace vm for ( auto &vinstr : label.vinstrs ) { - std::printf( "> decrypt key = 0x%p\n", decrypt_key ); - auto vm_handler_idx = vinstr.vm_handler; std::tie( 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::printf( "> encrypt virtual instruction rva transformations:\n" ); - for ( auto &transform : encrypt_vinstrs_rva ) - vm::util::print( transform ); - for ( auto &instr : encrypt_vinstrs_rva ) rva = vm::transform::apply( instr.operands[ 0 ].size, instr.mnemonic, rva, transform::has_imm( &instr ) ? instr.operands[ 1 ].imm.value.u : 0 ); - std::printf( "> encrypted rva = 0x%p\n", rva ); return rva; } } // namespace vm \ No newline at end of file diff --git a/src/gen_header_template.h b/src/gen_header_template.h new file mode 100644 index 0000000..4a1904a --- /dev/null +++ b/src/gen_header_template.h @@ -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( vm::calls::get_hello ); + +} \ No newline at end of file diff --git a/src/lexer.flex.cpp b/src/lexer.flex.cpp index 043f22d..c649eb4 100644 --- a/src/lexer.flex.cpp +++ b/src/lexer.flex.cpp @@ -352,8 +352,8 @@ static void yynoreturn yy_fatal_error ( const char* msg ); (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 5 -#define YY_END_OF_BUFFER 6 +#define YY_NUM_RULES 6 +#define YY_END_OF_BUFFER 7 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -361,10 +361,10 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static const flex_int16_t yy_accept[13] = +static const flex_int16_t yy_accept[14] = { 0, - 0, 0, 6, 5, 4, 3, 2, 2, 2, 2, - 1, 0 + 0, 0, 7, 6, 5, 4, 3, 3, 3, 2, + 3, 1, 0 } ; 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, 2, 1, 1, 1, 1, 1, 1, 1, 1, 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, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 7, 6, 6, - 1, 1, 1, 1, 6, 1, 5, 5, 5, 5, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 8, 7, 7, + 1, 1, 1, 1, 7, 1, 5, 5, 5, 5, - 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, - 6, 6, 1, 1, 1, 1, 1, 1, 1, 1, + 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, + 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, @@ -399,33 +399,35 @@ static const YY_CHAR yy_ec[256] = 1, 1, 1, 1, 1 } ; -static const YY_CHAR yy_meta[8] = +static const YY_CHAR yy_meta[9] = { 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, 12, 13, 13, 13, 4, 0, 0, 4, - 0, 13, 8 + 0, 0, 15, 16, 16, 16, 3, 8, 0, 16, + 8, 0, 16, 8 } ; -static const flex_int16_t yy_def[14] = +static const flex_int16_t yy_def[15] = { 0, - 12, 1, 12, 12, 12, 12, 13, 13, 13, 13, - 10, 0, 12 + 13, 1, 13, 13, 13, 13, 14, 14, 8, 13, + 8, 11, 0, 13 } ; -static const flex_int16_t yy_nxt[21] = +static const flex_int16_t yy_nxt[25] = { 0, - 4, 5, 6, 7, 8, 8, 8, 11, 11, 9, - 10, 12, 3, 12, 12, 12, 12, 12, 12, 12 + 4, 5, 6, 7, 8, 4, 8, 8, 10, 9, + 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, - 1, 1, 1, 1, 1, 1, 1, 10, 10, 13, - 7, 3, 12, 12, 12, 12, 12, 12, 12, 12 + 1, 1, 1, 1, 1, 1, 1, 1, 7, 14, + 7, 11, 11, 8, 3, 13, 13, 13, 13, 13, + 13, 13, 13, 13 } ; static yy_state_type yy_last_accepting_state; @@ -446,8 +448,8 @@ char *yytext; #line 2 "lexer.l" #include "parser.tab.h" #include -#line 449 "lexer.flex.cpp" -#line 450 "lexer.flex.cpp" +#line 451 "lexer.flex.cpp" +#line 452 "lexer.flex.cpp" #define INITIAL 0 @@ -663,7 +665,7 @@ YY_DECL { #line 6 "lexer.l" -#line 666 "lexer.flex.cpp" +#line 668 "lexer.flex.cpp" 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 ) { 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_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 13 ); + while ( yy_base[yy_current_state] != 16 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -728,26 +730,31 @@ YY_RULE_SETUP case 2: YY_RULE_SETUP #line 8 "lexer.l" -{ strcpy(yylval.vinstr_name, yytext); return VINSTR; } +{ strcpy(yylval.label_name, yytext); return LABEL; } YY_BREAK case 3: -/* rule 3 can match eol */ YY_RULE_SETUP #line 9 "lexer.l" -{ yylineno++; } +{ strcpy(yylval.vinstr_name, yytext); return VINSTR; } YY_BREAK case 4: /* rule 4 can match eol */ YY_RULE_SETUP #line 10 "lexer.l" - +{ yylineno++; } YY_BREAK case 5: +/* rule 5 can match eol */ YY_RULE_SETUP #line 11 "lexer.l" + + YY_BREAK +case 6: +YY_RULE_SETUP +#line 12 "lexer.l" ECHO; YY_BREAK -#line 750 "lexer.flex.cpp" +#line 757 "lexer.flex.cpp" case YY_STATE_EOF(INITIAL): 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 ) { 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_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 ) { 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_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; } @@ -1752,5 +1759,5 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 11 "lexer.l" +#line 12 "lexer.l" diff --git a/src/lexer.l b/src/lexer.l index ed0701e..6995a4b 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -5,6 +5,7 @@ %% 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; } "\n" { yylineno++; } [ ?\t\n\r] diff --git a/src/main.cpp b/src/main.cpp index a27cd89..b32840c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,6 +10,7 @@ #include "parser.h" #include "parser.tab.h" #include "vmasm.hpp" +#include "vmprofiler.hpp" extern FILE *yyin; extern "C" int yywrap() @@ -87,6 +88,11 @@ int __cdecl main( int argc, const char *argv[] ) 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 ); // @@ -116,19 +122,16 @@ int __cdecl main( int argc, const char *argv[] ) 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( "> " ); { auto idx = 0u; for ( auto byte : label.vinstrs ) - { std::printf( "0x%x ", byte ); - if ( ++idx == 10 ) - { - std::printf( "\n" ); - idx = 0u; - } - } + + std::printf( "\n" ); } } diff --git a/src/parser.h b/src/parser.h index 173ff70..944e5fd 100644 --- a/src/parser.h +++ b/src/parser.h @@ -7,7 +7,6 @@ struct _vinstr_meta { std::string name; - bool has_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, std::uintptr_t imm_val ); bool for_each( callback_t callback ); - + std::vector< _vlabel_meta > virt_labels; private: parse_t(); - std::vector< _vlabel_meta > virt_labels; }; \ No newline at end of file diff --git a/src/parser.tab.cpp b/src/parser.tab.cpp index 86b7956..ff8b8b0 100644 --- a/src/parser.tab.cpp +++ b/src/parser.tab.cpp @@ -108,8 +108,9 @@ extern int yydebug; /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { - VINSTR = 258, - IMM = 259 + LABEL = 258, + VINSTR = 259, + IMM = 260 }; #endif @@ -121,11 +122,12 @@ typedef union YYSTYPE #line 10 "parser.y" char vinstr_name[20]; +char label_name[256]; unsigned long long imm_val; /* Line 387 of yacc.c */ -#line 129 "parser.tab.cpp" +#line 131 "parser.tab.cpp" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ @@ -153,7 +155,7 @@ int yyparse (); /* Copy the second part of user declarations. */ /* Line 390 of yacc.c */ -#line 157 "parser.tab.cpp" +#line 159 "parser.tab.cpp" #ifdef short # undef short @@ -371,22 +373,22 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 4 +#define YYFINAL 3 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 6 +#define YYLAST 7 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 5 +#define YYNTOKENS 6 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 2 +#define YYNNTS 3 /* YYNRULES -- Number of rules. */ -#define YYNRULES 5 +#define YYNRULES 9 /* YYNRULES -- Number of states. */ -#define YYNSTATES 7 +#define YYNSTATES 10 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 259 +#define YYMAXUTOK 260 #define YYTRANSLATE(YYX) \ ((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, 1, 2, 3, 4 + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5 }; #if YYDEBUG @@ -427,20 +430,21 @@ static const yytype_uint8 yytranslate[] = YYRHS. */ 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. */ static const yytype_int8 yyrhs[] = { - 6, 0, -1, 3, -1, 3, 4, -1, 6, 3, - -1, 6, 3, 4, -1 + 7, 0, -1, 3, -1, 7, 3, -1, 7, 8, + -1, -1, 4, -1, 4, 5, -1, 8, 4, -1, + 8, 4, 5, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 20, 20, 21, 22, 23 + 0, 22, 22, 23, 24, 25, 29, 30, 31, 32 }; #endif @@ -449,7 +453,8 @@ static const yytype_uint8 yyrline[] = First, the terminals, then, starting at YYNTOKENS, nonterminals. */ 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 @@ -458,20 +463,20 @@ static const char *const yytname[] = token YYLEX-NUM. */ static const yytype_uint16 yytoknum[] = { - 0, 256, 257, 258, 259 + 0, 256, 257, 258, 259, 260 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ 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. */ 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. @@ -479,27 +484,27 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ 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]. */ static const yytype_int8 yydefgoto[] = { - -1, 2 + -1, 2, 6 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -3 +#define YYPACT_NINF -4 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]. */ static const yytype_int8 yypgoto[] = { - -3, -3 + -4, -4, -4 }; /* 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 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) \ - (!!((Yystate) == (-3))) + (!!((Yystate) == (-4))) #define yytable_value_is_error(Yytable_value) \ YYID (0) 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 symbol of state STATE-NUM. */ 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) @@ -1328,31 +1333,43 @@ yyreduce: { case 2: /* Line 1792 of yacc.c */ -#line 20 "parser.y" - { parse_t::get_instance()->add_vinstr((yyvsp[(1) - (1)].vinstr_name)); } +#line 22 "parser.y" + { parse_t::get_instance()->add_label((yyvsp[(1) - (1)].label_name)); } break; case 3: /* 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)); } break; - case 4: + case 8: /* Line 1792 of yacc.c */ -#line 22 "parser.y" +#line 31 "parser.y" { parse_t::get_instance()->add_vinstr((yyvsp[(2) - (2)].vinstr_name)); } break; - case 5: + case 9: /* 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)); } break; /* Line 1792 of yacc.c */ -#line 1356 "parser.tab.cpp" +#line 1373 "parser.tab.cpp" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1584,4 +1601,4 @@ yyreturn: /* Line 2055 of yacc.c */ -#line 25 "parser.y" +#line 34 "parser.y" diff --git a/src/parser.tab.h b/src/parser.tab.h index f5d7ed0..4c6cbe0 100644 --- a/src/parser.tab.h +++ b/src/parser.tab.h @@ -46,8 +46,9 @@ extern int yydebug; /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { - VINSTR = 258, - IMM = 259 + LABEL = 258, + VINSTR = 259, + IMM = 260 }; #endif @@ -59,11 +60,12 @@ typedef union YYSTYPE #line 10 "parser.y" char vinstr_name[20]; +char label_name[256]; unsigned long long imm_val; /* Line 2058 of yacc.c */ -#line 67 "parser.tab.h" +#line 69 "parser.tab.h" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ diff --git a/src/parser.y b/src/parser.y index 9ae154a..b57c91d 100644 --- a/src/parser.y +++ b/src/parser.y @@ -9,17 +9,26 @@ extern int yylineno; %union { char vinstr_name[20]; +char label_name[256]; unsigned long long imm_val; } +%token LABEL %token VINSTR %token IMM %% 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 IMM { parse_t::get_instance()->add_vinstr($1, $2); } - | PROGRAM VINSTR { parse_t::get_instance()->add_vinstr($2); } - | PROGRAM VINSTR IMM { parse_t::get_instance()->add_vinstr($2, $3); } + | VINSTRS VINSTR { parse_t::get_instance()->add_vinstr($2); } + | VINSTRS VINSTR IMM { parse_t::get_instance()->add_vinstr($2, $3); } ; %% \ No newline at end of file diff --git a/src/test.vasm b/src/test.vasm index d11cf46..31e2782 100644 --- a/src/test.vasm +++ b/src/test.vasm @@ -1,11 +1,9 @@ -SREGQ 0x0 -SREGQ 0x10 -SREGQ 0x20 -LCONSTQ 0x10 -LCONSTQ 0x10 -ADDQ -SREGQ 0x0 -SREGQ 0x10 -LREGQ 0x20 -LREGQ 0x10 -LREGQ 0x0 \ No newline at end of file +get_hello: + LCONSTQ 0x10000 + SREGQ 0x10 + VMEXIT + +get_world: + LCONSTQ 0x10000 + SREGQ 0x10 + VMEXIT \ No newline at end of file diff --git a/src/test.vmasm b/src/test.vmasm deleted file mode 100644 index d36a5e0..0000000 Binary files a/src/test.vmasm and /dev/null differ diff --git a/src/vmassembler.exe b/src/vmassembler.exe new file mode 100644 index 0000000..340eb6e Binary files /dev/null and b/src/vmassembler.exe differ diff --git a/src/vmassembler.vcxproj b/src/vmassembler.vcxproj index 182b488..9632f43 100644 --- a/src/vmassembler.vcxproj +++ b/src/vmassembler.vcxproj @@ -44,6 +44,7 @@ NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true stdcpp17 + Disabled Console diff --git a/src/vmptest9.vmp.exe b/src/vmptest9.vmp.exe new file mode 100644 index 0000000..37244a2 Binary files /dev/null and b/src/vmptest9.vmp.exe differ diff --git a/vmassembler.sln b/vmassembler.sln index 0866bb4..d652c6a 100644 --- a/vmassembler.sln +++ b/vmassembler.sln @@ -28,8 +28,8 @@ Global {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.Build.0 = Debug MT|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release|x64.ActiveCfg = Release MD DLL|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release|x64.Build.0 = 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 MT|x64 {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 {D0B6092A-9944-4F24-9486-4B7DAE372619}.DBG|x64.ActiveCfg = DBG|x64