diff --git a/VTIL-Architecture/arch/operands.hpp b/VTIL-Architecture/arch/operands.hpp index f6f586a..6325301 100644 --- a/VTIL-Architecture/arch/operands.hpp +++ b/VTIL-Architecture/arch/operands.hpp @@ -54,6 +54,10 @@ namespace vtil { intptr_t ival; uintptr_t uval; +#if _M_X64 || __x86_64__ + int64_t i64; + uint64_t u64; +#endif }; // Number of bits it is expressed in. diff --git a/VTIL-SymEx/directives/transformer.hpp b/VTIL-SymEx/directives/transformer.hpp index 98b0b64..3083853 100644 --- a/VTIL-SymEx/directives/transformer.hpp +++ b/VTIL-SymEx/directives/transformer.hpp @@ -69,7 +69,7 @@ namespace vtil::symbolic // Log the translation. // log( "Translating [%s] => [%s]:\n", *from, *to ); - from->enum_variables( [ & ] ( const instance& ins ) + from->enum_variables( [ & ] ( const directive::instance& ins ) { log( " %s: %s\n", ins.id, *match.translate( ins ) ); } ); diff --git a/VTIL-SymEx/expressions/expression.cpp b/VTIL-SymEx/expressions/expression.cpp index e376fdf..4f68ec2 100644 --- a/VTIL-SymEx/expressions/expression.cpp +++ b/VTIL-SymEx/expressions/expression.cpp @@ -546,6 +546,19 @@ namespace vtil::symbolic rhs.resize( value.size(), false ); break; } + case math::operator_id::shift_left: + case math::operator_id::shift_right: + { + rhs.resize( sizeof(uintptr_t), false ); + break; + } + + case math::operator_id::rotate_left: + case math::operator_id::rotate_right: + { + rhs.resize( sizeof(uintptr_t), false ); + break; + } case math::operator_id::multiply_high: case math::operator_id::multiply: case math::operator_id::divide: diff --git a/VTIL-SymEx/simplifier/simplifier.cpp b/VTIL-SymEx/simplifier/simplifier.cpp index c45c3f3..7879555 100644 --- a/VTIL-SymEx/simplifier/simplifier.cpp +++ b/VTIL-SymEx/simplifier/simplifier.cpp @@ -639,7 +639,7 @@ namespace vtil::symbolic // Log the input. // scope_padding _p( 1 ); - if ( !state::get()->padding ) log( "\n" ); + log( "\n" ); log( "[Input] = %s ", *exp ); log( "(Hash: %s)\n", exp->hash() ); #endif diff --git a/VTIL-Tests/dummy.cpp b/VTIL-Tests/dummy.cpp index d45ede5..548fb47 100644 --- a/VTIL-Tests/dummy.cpp +++ b/VTIL-Tests/dummy.cpp @@ -28,6 +28,69 @@ DOCTEST_TEST_CASE("dummy") CHECK(1 == 1); } +DOCTEST_TEST_CASE("Expression hash") +{ + vtil::logger::log("\n\n>> %s \n", __FUNCTION__); + auto const_a = vtil::symbolic::expression{ 123 }; + auto const_b = (vtil::symbolic::expression{ 123 } + 1 - 1).simplify( true ); + CHECK( const_a.hash() == const_b.hash() ); + + auto block = vtil::basic_block::begin( 0x1234 ); + block->push( 0 ); + auto variable_a = vtil::symbolic::variable{ block->begin(), vtil::REG_FLAGS }; + auto variable_b = vtil::symbolic::variable{ block->begin(), vtil::REG_FLAGS }; + // vtil::logger::log( "variable_a: %s \n", variable_a.to_string().c_str() ); + CHECK( variable_a.hash() == variable_b.hash() ); + + + // simple shift_right + { + auto exp_a = vtil::symbolic::expression{ (uint32_t)123 } >> (uint8_t)6; + auto exp_b = vtil::symbolic::expression{ (uint32_t)123 } >> (uint32_t)6; + + exp_a = exp_a.simplify( true ); + exp_b = exp_b.simplify( true ); + + vtil::logger::log("exp_a: %s \n", exp_a.to_string().c_str()); + vtil::logger::log("exp_b: %s \n", exp_b.to_string().c_str()); + CHECK(exp_a.hash() == exp_b.hash()); + } + + // Simple const shift_right + { + auto exp_a = variable_a.to_expression() >> (uint8_t)6; + auto exp_b = variable_a.to_expression() >> (uint32_t)6; + + exp_a = exp_a.simplify(true); + exp_b = exp_b.simplify(true); + + vtil::logger::log("exp_a: %s \n", exp_a.to_string().c_str()); + vtil::logger::log("exp_b: %s \n", exp_b.to_string().c_str()); + CHECK(exp_a.hash() == exp_b.hash()); + } + + // advanced shift_right + { + // eax@6:1 + vtil::register_desc temp_6(vtil::register_local, 1, 1, 6); + auto exp_a = vtil::symbolic::variable{ block->begin(), temp_6 }.to_expression(); + exp_a.resize( vtil::arch::bit_count ); + exp_a = exp_a.simplify( true ); + vtil::logger::log( "exp_a.size: %d \n", exp_a.value.size() ); + vtil::logger::log( "exp_a: %s \n", exp_a.to_string().c_str() ); + + // eax >> 6 & 1 + vtil::register_desc temp(vtil::register_local, 1, vtil::arch::bit_count, 0); + auto exp_b = vtil::symbolic::variable{ block->begin(), temp }.to_expression(); + exp_b >>= (uint8_t)6; + exp_b &= (uint8_t)1; + exp_b = exp_b.simplify( true ); + vtil::logger::log( "exp_b.size: %d \n", exp_b.value.size() ); + vtil::logger::log( "exp_b: %s \n", exp_b.to_string().c_str() ); + CHECK(exp_a.hash() == exp_b.hash()); + } +} + DOCTEST_TEST_CASE("Optimization vtil file") { vtil::logger::log("\n\n>> %s \n", __FUNCTION__); @@ -384,7 +447,7 @@ DOCTEST_TEST_CASE("Optimization dead_code_elimination_pass") auto block3 = block1->fork( 0x3000 ); { - // mov ecx, [esp - 8] + // mov eax, [esp - 8] block3->ldd( reg_eax, vtil::REG_SP, -8 ); // sp -= 0x10 block3->shift_sp( 0x10 );