made an optimization

master
IDontCode 2 years ago
parent c636737116
commit 6c1680e812

@ -8,8 +8,7 @@ emu_t::emu_t(vm::ctx_t* vm_ctx)
img_size(vm_ctx->image_size) {} img_size(vm_ctx->image_size) {}
emu_t::~emu_t() { emu_t::~emu_t() {
if (uc_ctx) if (uc_ctx) uc_close(uc_ctx);
uc_close(uc_ctx);
} }
bool emu_t::init() { bool emu_t::init() {
@ -53,8 +52,7 @@ bool emu_t::init() {
for (auto iat_thunk = reinterpret_cast<win::image_thunk_data_t<>*>( for (auto iat_thunk = reinterpret_cast<win::image_thunk_data_t<>*>(
import_dir->rva_first_thunk + g_vm_ctx->module_base); import_dir->rva_first_thunk + g_vm_ctx->module_base);
iat_thunk->address; ++iat_thunk) { iat_thunk->address; ++iat_thunk) {
if (iat_thunk->is_ordinal) if (iat_thunk->is_ordinal) continue;
continue;
iat_thunk->function = IAT_VECTOR_TABLE; iat_thunk->function = IAT_VECTOR_TABLE;
} }
} }
@ -122,15 +120,13 @@ bool emu_t::get_trace(std::vector<vm::instrs::code_block_t>& entries) {
return false; return false;
} }
if (cc_block) if (cc_block) code_blocks.push_back(code_block);
code_blocks.push_back(code_block);
// code_blocks.size() will continue to grow as all branches are traced... // code_blocks.size() will continue to grow as all branches are traced...
// when idx is > code_blocks.size() then we have traced all branches... // when idx is > code_blocks.size() then we have traced all branches...
for (auto idx = 0u; idx < code_blocks.size(); ++idx) { for (auto idx = 0u; idx < code_blocks.size(); ++idx) {
const auto _code_block = code_blocks[idx]; const auto _code_block = code_blocks[idx];
if (!_code_block.code_block.jcc.has_jcc) if (!_code_block.code_block.jcc.has_jcc) continue;
continue;
switch (_code_block.code_block.jcc.type) { switch (_code_block.code_block.jcc.type) {
case vm::instrs::jcc_type::branching: { case vm::instrs::jcc_type::branching: {
@ -379,9 +375,7 @@ uc_err emu_t::create_entry(vmp2::v2::entry_t* entry) {
return UC_ERR_OK; return UC_ERR_OK;
} }
bool emu_t::code_exec_callback(uc_engine* uc, bool emu_t::code_exec_callback(uc_engine* uc, uint64_t address, uint32_t size,
uint64_t address,
uint32_t size,
emu_t* obj) { emu_t* obj) {
uc_err err; uc_err err;
vmp2::v2::entry_t vinstr_entry; vmp2::v2::entry_t vinstr_entry;
@ -497,8 +491,7 @@ bool emu_t::code_exec_callback(uc_engine* uc,
} }
if (!vm_handler.profile) { if (!vm_handler.profile) {
if (!g_force_emu) if (!g_force_emu) obj->cc_block = nullptr;
obj->cc_block = nullptr;
std::printf("> please define virtual machine handler (%p): \n\n", std::printf("> please define virtual machine handler (%p): \n\n",
(vm_handler_addr - obj->g_vm_ctx->module_base) + (vm_handler_addr - obj->g_vm_ctx->module_base) +
@ -507,8 +500,7 @@ bool emu_t::code_exec_callback(uc_engine* uc,
vm::util::print(vm_handler.instrs); vm::util::print(vm_handler.instrs);
std::printf("\n\n"); std::printf("\n\n");
if (!g_force_emu) if (!g_force_emu) exit(0);
exit(0);
} }
auto vinstr = vm::instrs::get(*obj->g_vm_ctx, vinstr_entry); auto vinstr = vm::instrs::get(*obj->g_vm_ctx, vinstr_entry);
@ -554,6 +546,7 @@ bool emu_t::code_exec_callback(uc_engine* uc,
// emulated... // emulated...
auto jcc_data = auto jcc_data =
vm::instrs::get_jcc_data(*obj->g_vm_ctx, obj->cc_block->code_block); vm::instrs::get_jcc_data(*obj->g_vm_ctx, obj->cc_block->code_block);
obj->cc_block->code_block.jcc = jcc_data.value(); obj->cc_block->code_block.jcc = jcc_data.value();
// allocate space for the cpu context and stack... // allocate space for the cpu context and stack...
@ -638,22 +631,17 @@ bool emu_t::code_exec_callback(uc_engine* uc,
void emu_t::int_callback(uc_engine* uc, std::uint32_t intno, emu_t* obj) { void emu_t::int_callback(uc_engine* uc, std::uint32_t intno, emu_t* obj) {
uc_err err; uc_err err;
std::uintptr_t rip = 0ull; std::uintptr_t rip = 0ull;
static ZydisDecoder decoder; static thread_local ZydisDecodedInstruction instr;
static ZydisDecodedInstruction instr;
if (static std::atomic<bool> once{false}; !once.exchange(true))
ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64,
ZYDIS_ADDRESS_WIDTH_64);
if ((err = uc_reg_read(uc, UC_X86_REG_RIP, &rip))) { if ((err = uc_reg_read(uc, UC_X86_REG_RIP, &rip))) {
std::printf("> failed to read rip... reason = %d\n", err); std::printf("> failed to read rip... reason = %d\n", err);
return; return;
} }
if (!ZYAN_SUCCESS(ZydisDecoderDecodeBuffer( if (!ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(vm::util::g_decoder.get(),
&decoder, reinterpret_cast<void*>(rip), PAGE_4KB, &instr))) { reinterpret_cast<void*>(rip),
PAGE_4KB, &instr))) {
std::printf("> failed to decode instruction at = 0x%p\n", rip); std::printf("> failed to decode instruction at = 0x%p\n", rip);
if ((err = uc_emu_stop(uc))) { if ((err = uc_emu_stop(uc))) {
std::printf("> failed to stop emulation, exiting... reason = %d\n", err); std::printf("> failed to stop emulation, exiting... reason = %d\n", err);
exit(0); exit(0);
@ -661,7 +649,8 @@ void emu_t::int_callback(uc_engine* uc, std::uint32_t intno, emu_t* obj) {
return; return;
} }
// advance rip over the instruction that caused the exception... // advance rip over the instruction that caused the exception... this is
// usually a division by 0...
rip += instr.length; rip += instr.length;
if ((err = uc_reg_write(uc, UC_X86_REG_RIP, &rip))) { if ((err = uc_reg_write(uc, UC_X86_REG_RIP, &rip))) {
@ -670,12 +659,8 @@ void emu_t::int_callback(uc_engine* uc, std::uint32_t intno, emu_t* obj) {
} }
} }
void emu_t::invalid_mem(uc_engine* uc, void emu_t::invalid_mem(uc_engine* uc, uc_mem_type type, uint64_t address,
uc_mem_type type, int size, int64_t value, emu_t* obj) {
uint64_t address,
int size,
int64_t value,
emu_t* obj) {
switch (type) { switch (type) {
case UC_MEM_READ_UNMAPPED: { case UC_MEM_READ_UNMAPPED: {
uc_mem_map(uc, address & ~0xFFFull, PAGE_4KB, UC_PROT_ALL); uc_mem_map(uc, address & ~0xFFFull, PAGE_4KB, UC_PROT_ALL);

Loading…
Cancel
Save