|
|
@ -1,3 +1,6 @@
|
|
|
|
|
|
|
|
#include <filesystem>
|
|
|
|
|
|
|
|
#include <fstream>
|
|
|
|
|
|
|
|
#include <sstream>
|
|
|
|
#include <string>
|
|
|
|
#include <string>
|
|
|
|
#include <vmemu_t.hpp>
|
|
|
|
#include <vmemu_t.hpp>
|
|
|
|
|
|
|
|
|
|
|
@ -20,6 +23,17 @@ bool emu_t::init() {
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((err = uc_mem_map(uc, STRING_POOL, STRING_POOL_SIZE, UC_PROT_ALL))) {
|
|
|
|
|
|
|
|
std::printf("> uc_mem_map stack err, reason = %d\n", err);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::uintptr_t str_pool_addr = STRING_POOL;
|
|
|
|
|
|
|
|
uc_reg_write(uc, UC_X86_REG_RAX, &str_pool_addr);
|
|
|
|
|
|
|
|
uc_reg_write(uc, UC_X86_REG_RBP, &str_pool_addr);
|
|
|
|
|
|
|
|
uc_reg_write(uc, UC_X86_REG_RDX, &str_pool_addr);
|
|
|
|
|
|
|
|
uc_reg_write(uc, UC_X86_REG_RSI, &str_pool_addr);
|
|
|
|
|
|
|
|
|
|
|
|
if ((err = uc_mem_map(uc, m_vm->m_module_base, m_vm->m_image_size,
|
|
|
|
if ((err = uc_mem_map(uc, m_vm->m_module_base, m_vm->m_image_size,
|
|
|
|
UC_PROT_ALL))) {
|
|
|
|
UC_PROT_ALL))) {
|
|
|
|
std::printf("> map memory failed, reason = %d\n", err);
|
|
|
|
std::printf("> map memory failed, reason = %d\n", err);
|
|
|
@ -140,7 +154,6 @@ bool emu_t::emulate(std::uint32_t vmenter_rva, vm::instrs::vrtn_t& vrtn) {
|
|
|
|
std::for_each(vrtn.m_blks.begin(), vrtn.m_blks.end(),
|
|
|
|
std::for_each(vrtn.m_blks.begin(), vrtn.m_blks.end(),
|
|
|
|
[&](vm::instrs::vblk_t& blk) {
|
|
|
|
[&](vm::instrs::vblk_t& blk) {
|
|
|
|
if (blk.m_jmp.ctx) uc_context_free(blk.m_jmp.ctx);
|
|
|
|
if (blk.m_jmp.ctx) uc_context_free(blk.m_jmp.ctx);
|
|
|
|
|
|
|
|
|
|
|
|
if (blk.m_jmp.stack) delete[] blk.m_jmp.stack;
|
|
|
|
if (blk.m_jmp.stack) delete[] blk.m_jmp.stack;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
@ -321,6 +334,8 @@ bool emu_t::code_exec_callback(uc_engine* uc, uint64_t address, uint32_t size,
|
|
|
|
emu_t* obj) {
|
|
|
|
emu_t* obj) {
|
|
|
|
uc_err err;
|
|
|
|
uc_err err;
|
|
|
|
static thread_local zydis_decoded_instr_t instr;
|
|
|
|
static thread_local zydis_decoded_instr_t instr;
|
|
|
|
|
|
|
|
static thread_local unsigned instr_cnt = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (!ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(vm::utils::g_decoder.get(),
|
|
|
|
if (!ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(vm::utils::g_decoder.get(),
|
|
|
|
reinterpret_cast<void*>(address),
|
|
|
|
reinterpret_cast<void*>(address),
|
|
|
|
PAGE_4KB, &instr))) {
|
|
|
|
PAGE_4KB, &instr))) {
|
|
|
@ -332,6 +347,11 @@ bool emu_t::code_exec_callback(uc_engine* uc, uint64_t address, uint32_t size,
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (instr_cnt > 500) {
|
|
|
|
|
|
|
|
instr_cnt = 0;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (instr.mnemonic == ZYDIS_MNEMONIC_INVALID) return false;
|
|
|
|
if (instr.mnemonic == ZYDIS_MNEMONIC_INVALID) return false;
|
|
|
|
|
|
|
|
|
|
|
|
uc_context* ctx;
|
|
|
|
uc_context* ctx;
|
|
|
@ -421,8 +441,8 @@ bool emu_t::code_exec_callback(uc_engine* uc, uint64_t address, uint32_t size,
|
|
|
|
obj->m_vm->m_image_base);
|
|
|
|
obj->m_vm->m_image_base);
|
|
|
|
|
|
|
|
|
|
|
|
vm::utils::print(inst_stream);
|
|
|
|
vm::utils::print(inst_stream);
|
|
|
|
uc_emu_stop(uc);
|
|
|
|
// uc_emu_stop(uc);
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (obj->cc_blk->m_vinstrs.size()) {
|
|
|
|
if (obj->cc_blk->m_vinstrs.size()) {
|
|
|
@ -454,6 +474,31 @@ bool emu_t::code_exec_callback(uc_engine* uc, uint64_t address, uint32_t size,
|
|
|
|
if (vinstr.mnemonic == vm::instrs::mnemonic_t::jmp ||
|
|
|
|
if (vinstr.mnemonic == vm::instrs::mnemonic_t::jmp ||
|
|
|
|
vinstr.mnemonic == vm::instrs::mnemonic_t::vmexit)
|
|
|
|
vinstr.mnemonic == vm::instrs::mnemonic_t::vmexit)
|
|
|
|
uc_emu_stop(obj->uc);
|
|
|
|
uc_emu_stop(obj->uc);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (vinstr.mnemonic == vm::instrs::mnemonic_t::vmexit) {
|
|
|
|
|
|
|
|
std::stringstream fname, cmd;
|
|
|
|
|
|
|
|
fname << std::hex << std::showbase
|
|
|
|
|
|
|
|
<< obj->m_vm->m_vm_entry_rva + obj->m_vm->m_image_base << "_"
|
|
|
|
|
|
|
|
<< "stack.bin";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::uint8_t* buff = new std::uint8_t[STACK_SIZE];
|
|
|
|
|
|
|
|
std::ofstream file(fname.str(), std::ios::binary);
|
|
|
|
|
|
|
|
uc_mem_read(uc, STACK_BASE, buff, STACK_SIZE);
|
|
|
|
|
|
|
|
file.write((char*)buff, STACK_SIZE);
|
|
|
|
|
|
|
|
uc_mem_read(uc, STRING_POOL, buff, STRING_POOL_SIZE);
|
|
|
|
|
|
|
|
file.write((char*)buff, STRING_POOL_SIZE);
|
|
|
|
|
|
|
|
file.close();
|
|
|
|
|
|
|
|
delete[] buff;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cmd << "strings -e b " << fname.str() << " >> BEDaisy.strings.txt";
|
|
|
|
|
|
|
|
system(cmd.str().c_str());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cmd.str("");
|
|
|
|
|
|
|
|
cmd << "strings " << fname.str() << " >> BEDaisy.strings.txt";
|
|
|
|
|
|
|
|
system(cmd.str().c_str());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::filesystem::remove(fname.str());
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
obj->cc_blk->m_vinstrs.push_back(vinstr);
|
|
|
|
obj->cc_blk->m_vinstrs.push_back(vinstr);
|
|
|
|