From 8030f76ee2b0a7dc0fc7a3717461f6dcb591c2e6 Mon Sep 17 00:00:00 2001 From: wallds Date: Sat, 1 Apr 2023 09:26:31 +0800 Subject: [PATCH] Bug fix: Argument register will be renamed by `register_renaming_pass`. --- .../optimizer/register_renaming_pass.cpp | 5 +++ VTIL-Tests/dummy.cpp | 40 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/VTIL-Compiler/optimizer/register_renaming_pass.cpp b/VTIL-Compiler/optimizer/register_renaming_pass.cpp index 87b312fd..9c0d68eb 100644 --- a/VTIL-Compiler/optimizer/register_renaming_pass.cpp +++ b/VTIL-Compiler/optimizer/register_renaming_pass.cpp @@ -111,6 +111,11 @@ namespace vtil::optimizer // if ( i->is_volatile() ) return fail(); + + // If source is being accessed by a vxcall instruction, fail. + // + if ( mask && i->base == &ins::vxcall ) + return fail(); } // If destination is used by the instruction, fail. diff --git a/VTIL-Tests/dummy.cpp b/VTIL-Tests/dummy.cpp index 09d4c7c6..104ba197 100644 --- a/VTIL-Tests/dummy.cpp +++ b/VTIL-Tests/dummy.cpp @@ -285,6 +285,46 @@ DOCTEST_TEST_CASE("Optimization register_renaming_pass") CHECK(ins.operands[1].imm().ival == 0x1); } +DOCTEST_TEST_CASE("Optimization register_renaming_pass vxcall") +{ + vtil::logger::log("\n\n>> %s \n", __FUNCTION__); + + auto block = vtil::basic_block::begin(0x1337); + + vtil::register_desc reg_ecx(vtil::register_physical, registers::cx, vtil::arch::bit_count, 0); + + auto sr0 = block->owner->alloc(vtil::arch::bit_count); + + // The ecx register here is a potential function argument, register_renaming_pass should not work here. + block->mov(reg_ecx, (uintptr_t)0x880000); + block->vxcall((uintptr_t)0x10000); + + auto block2 = block->fork(0x2000); + block2->mov(sr0, reg_ecx); + block2->mov(reg_ecx, (uintptr_t)1); + block2->mov(reg_ecx, sr0); + block2->vxcall((uintptr_t)0x10000); + + auto block3 = block2->fork(0x3000); + block3->vexit(0ull); // marks the end of a basic_block + + vtil::logger::log(":: Before:\n"); + vtil::debug::dump(block->owner); + + vtil::optimizer::register_renaming_pass{}(block->owner); + + vtil::logger::log(":: After:\n"); + vtil::debug::dump(block->owner); + + auto ins = (*block)[0]; + + // mov ecx, 0x880000 + CHECK(ins.base == &vtil::ins::mov); + CHECK(ins.operands.size() == 2); + CHECK(ins.operands[0].reg().local_id == registers::cx); + CHECK(ins.operands[1].imm().ival == 0x880000); +} + DOCTEST_TEST_CASE("Optimization symbolic_rewrite_pass") { vtil::logger::log("\n\n>> %s \n", __FUNCTION__);