fixed an issue with the unpacker

master
_xeroxz 2 years ago
parent baf6e2d80d
commit c636737116

@ -1,18 +1,4 @@
--- ---
BasedOnStyle: Microsoft BasedOnStyle: Chromium
AlignAfterOpenBracket: Align
AllowAllArgumentsOnNextLine: 'true'
AllowAllParametersOfDeclarationOnNextLine: 'true'
AllowShortIfStatementsOnASingleLine: Never
BreakBeforeBraces: Allman
IndentWidth: '4'
Language: Cpp
NamespaceIndentation: All
SpacesInAngles: 'true'
SpacesInCStyleCastParentheses: 'true'
SpacesInContainerLiterals: 'true'
SpacesInParentheses: 'true'
SpacesInSquareBrackets: 'true'
UseTab: Never
... ...

@ -32,6 +32,8 @@
#define UNMAP_VIEW_OF_FILE_VECTOR 11 #define UNMAP_VIEW_OF_FILE_VECTOR 11
#define CLOSE_HANDLE_VECTOR 12 #define CLOSE_HANDLE_VECTOR 12
#define VIRTUAL_PROTECT_VECTOR 13 #define VIRTUAL_PROTECT_VECTOR 13
#define IS_DEBUGGER_PRESENT_VECTOR 14
#define IS_REMOTE_DEBUGGER_PRESENT_VECTOR 15
#define MOV_RAX_0_SIG "\x48\xB8\x00\x00\x00\x00\x00\x00\x00\x00" #define MOV_RAX_0_SIG "\x48\xB8\x00\x00\x00\x00\x00\x00\x00\x00"
#define MOV_RAX_0_MASK "xxxxxxxxxx" #define MOV_RAX_0_MASK "xxxxxxxxxx"
@ -71,19 +73,29 @@ class unpack_t {
static void unmap_view_of_file_hook(uc_engine*, unpack_t*); static void unmap_view_of_file_hook(uc_engine*, unpack_t*);
static void close_handle_hook(uc_engine*, unpack_t*); static void close_handle_hook(uc_engine*, unpack_t*);
static void virtual_protect_hook(uc_engine*, unpack_t*); static void virtual_protect_hook(uc_engine*, unpack_t*);
static void is_debugger_present_hook(uc_engine*, unpack_t*);
static void uc_strcpy(uc_engine* uc, char* buff, std::uintptr_t addr); static void uc_strcpy(uc_engine* uc, char* buff, std::uintptr_t addr);
static void uc_strcpy(uc_engine* uc, std::uintptr_t addr, char* buff); static void uc_strcpy(uc_engine* uc, std::uintptr_t addr, char* buff);
static bool iat_dispatcher(uc_engine *uc, uint64_t address, uint32_t size, static bool iat_dispatcher(uc_engine* uc,
uint64_t address,
uint32_t size,
unpack_t* unpack); unpack_t* unpack);
static bool unpack_section_callback(uc_engine *uc, uc_mem_type type, static bool unpack_section_callback(uc_engine* uc,
uint64_t address, int size, int64_t value, uc_mem_type type,
uint64_t address,
int size,
int64_t value,
unpack_t* unpack); unpack_t* unpack);
static void invalid_mem(uc_engine *uc, uc_mem_type type, uint64_t address, static void invalid_mem(uc_engine* uc,
int size, int64_t value, unpack_t *unpack); uc_mem_type type,
uint64_t address,
int size,
int64_t value,
unpack_t* unpack);
std::map<std::string, std::uintptr_t> loaded_modules; std::map<std::string, std::uintptr_t> loaded_modules;
std::map<std::string, std::pair<std::uint32_t, iat_hook_t> > iat_hooks = { std::map<std::string, std::pair<std::uint32_t, iat_hook_t> > iat_hooks = {
@ -100,6 +112,10 @@ class unpack_t {
{"UnmapViewOfFile", {"UnmapViewOfFile",
{UNMAP_VIEW_OF_FILE_VECTOR, &unmap_view_of_file_hook}}, {UNMAP_VIEW_OF_FILE_VECTOR, &unmap_view_of_file_hook}},
{"CloseHandle", {CLOSE_HANDLE_VECTOR, &close_handle_hook}}, {"CloseHandle", {CLOSE_HANDLE_VECTOR, &close_handle_hook}},
{"VirtualProtect", {VIRTUAL_PROTECT_VECTOR, &virtual_protect_hook}}}; {"VirtualProtect", {VIRTUAL_PROTECT_VECTOR, &virtual_protect_hook}},
{"IsDebuggerPresent",
{IS_DEBUGGER_PRESENT_VECTOR, &is_debugger_present_hook}},
{"CheckRemoteDebuggerPresent",
{IS_REMOTE_DEBUGGER_PRESENT_VECTOR, &is_debugger_present_hook}}};
}; };
} // namespace engine } // namespace engine

@ -48,9 +48,16 @@ class emu_t {
uc_err create_entry(vmp2::v2::entry_t* entry); uc_err create_entry(vmp2::v2::entry_t* entry);
static void int_callback(uc_engine* uc, std::uint32_t intno, emu_t* obj); static void int_callback(uc_engine* uc, std::uint32_t intno, emu_t* obj);
static bool code_exec_callback(uc_engine *uc, uint64_t address, uint32_t size, static bool code_exec_callback(uc_engine* uc,
uint64_t address,
uint32_t size,
emu_t* obj);
static void invalid_mem(uc_engine* uc,
uc_mem_type type,
uint64_t address,
int size,
int64_t value,
emu_t* obj); emu_t* obj);
static void invalid_mem(uc_engine *uc, uc_mem_type type, uint64_t address,
int size, int64_t value, emu_t *obj);
}; };
} // namespace vm } // namespace vm

@ -361,8 +361,7 @@ int __cdecl main(int argc, const char *argv[]) {
code_block.vinstrs.size() * sizeof(vm::instrs::virt_instr_t); code_block.vinstrs.size() * sizeof(vm::instrs::virt_instr_t);
vmp2::v4::code_block_t* _code_block = vmp2::v4::code_block_t* _code_block =
reinterpret_cast<vmp2::v4::code_block_t *>( reinterpret_cast<vmp2::v4::code_block_t*>(malloc(_code_block_size));
malloc(_code_block_size));
// serialize block meta data... // serialize block meta data...
_code_block->vip_begin = code_block.vip_begin; _code_block->vip_begin = code_block.vip_begin;

@ -15,10 +15,12 @@ unpack_t::unpack_t(const std::string &module_name,
} }
unpack_t::~unpack_t(void) { unpack_t::~unpack_t(void) {
if (uc_ctx) uc_close(uc_ctx); if (uc_ctx)
uc_close(uc_ctx);
for (auto& ptr : uc_hooks) for (auto& ptr : uc_hooks)
if (ptr) delete ptr; if (ptr)
delete ptr;
} }
bool unpack_t::init(void) { bool unpack_t::init(void) {
@ -110,7 +112,8 @@ bool unpack_t::init(void) {
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 + map_bin.data()); import_dir->rva_first_thunk + map_bin.data());
iat_thunk->address; ++iat_thunk) { iat_thunk->address; ++iat_thunk) {
if (iat_thunk->is_ordinal) continue; if (iat_thunk->is_ordinal)
continue;
auto iat_name = reinterpret_cast<win::image_named_import_t*>( auto iat_name = reinterpret_cast<win::image_named_import_t*>(
iat_thunk->address + map_bin.data()); iat_thunk->address + map_bin.data());
@ -258,7 +261,8 @@ bool unpack_t::unpack(std::vector<std::uint8_t> &output) {
win::reloc_block_t* reloc_block = &reloc_dir->first_block; win::reloc_block_t* reloc_block = &reloc_dir->first_block;
while (reloc_block->base_rva && reloc_block->size_block) { while (reloc_block->base_rva && reloc_block->size_block) {
if (reloc_block->base_rva == page) return true; if (reloc_block->base_rva == page)
return true;
reloc_block = reloc_block->next(); reloc_block = reloc_block->next();
} }
@ -317,7 +321,8 @@ bool unpack_t::unpack(std::vector<std::uint8_t> &output) {
// add new relocs to the .reloc section... // add new relocs to the .reloc section...
for (const auto& [reloc_rva, relocs] : new_relocs) { for (const auto& [reloc_rva, relocs] : new_relocs) {
if (has_reloc_page(reloc_rva)) continue; if (has_reloc_page(reloc_rva))
continue;
win::reloc_block_t* reloc_block = &reloc_dir->first_block; win::reloc_block_t* reloc_block = &reloc_dir->first_block;
while (reloc_block->base_rva && reloc_block->size_block) while (reloc_block->base_rva && reloc_block->size_block)
@ -363,6 +368,11 @@ void unpack_t::local_alloc_hook(uc_engine *uc_ctx, unpack_t *obj) {
} }
} }
void unpack_t::is_debugger_present_hook(uc_engine* uc, unpack_t* obj) {
std::uintptr_t rax = 0ull;
uc_reg_write(uc, UC_X86_REG_RAX, &rax);
}
void unpack_t::local_free_hook(uc_engine* uc_ctx, unpack_t* obj) { void unpack_t::local_free_hook(uc_engine* uc_ctx, unpack_t* obj) {
uc_err err; uc_err err;
std::uintptr_t rax = 0ull; std::uintptr_t rax = 0ull;
@ -527,6 +537,10 @@ void unpack_t::load_library_hook(uc_engine *uc_ctx, unpack_t *obj) {
const auto alloc_addr = module_base & ~0xFFFull; const auto alloc_addr = module_base & ~0xFFFull;
obj->loaded_modules[buff] = alloc_addr; obj->loaded_modules[buff] = alloc_addr;
auto dir = reinterpret_cast<win::import_directory_t*>(
img->get_directory(win::directory_id::directory_entry_import));
if (dir) {
// install iat hooks... // install iat hooks...
for (auto import_dir = reinterpret_cast<win::import_directory_t*>( for (auto import_dir = reinterpret_cast<win::import_directory_t*>(
img->get_directory(win::directory_id::directory_entry_import) img->get_directory(win::directory_id::directory_entry_import)
@ -536,13 +550,15 @@ void unpack_t::load_library_hook(uc_engine *uc_ctx, unpack_t *obj) {
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 + module_base); import_dir->rva_first_thunk + module_base);
iat_thunk->address; ++iat_thunk) { iat_thunk->address; ++iat_thunk) {
if (iat_thunk->is_ordinal) continue; if (iat_thunk->is_ordinal)
continue;
auto iat_name = reinterpret_cast<win::image_named_import_t*>( auto iat_name = reinterpret_cast<win::image_named_import_t*>(
iat_thunk->address + module_base); iat_thunk->address + module_base);
if (obj->iat_hooks.find(iat_name->name) != obj->iat_hooks.end()) { if (obj->iat_hooks.find(iat_name->name) != obj->iat_hooks.end()) {
std::printf("> iat hooking %s to vector table %p\n", iat_name->name, std::printf(
"> iat hooking %s to vector table %p\n", iat_name->name,
obj->iat_hooks[iat_name->name].first + IAT_VECTOR_TABLE); obj->iat_hooks[iat_name->name].first + IAT_VECTOR_TABLE);
iat_thunk->function = iat_thunk->function =
@ -550,6 +566,7 @@ void unpack_t::load_library_hook(uc_engine *uc_ctx, unpack_t *obj) {
} }
} }
} }
}
if ((err = uc_mem_map(uc_ctx, alloc_addr, image_size, UC_PROT_ALL))) { if ((err = uc_mem_map(uc_ctx, alloc_addr, image_size, UC_PROT_ALL))) {
std::printf("> failed to load library... reason = %d\n", err); std::printf("> failed to load library... reason = %d\n", err);
@ -600,7 +617,9 @@ void unpack_t::uc_strcpy(uc_engine *uc, std::uintptr_t addr, char *buff) {
} }
} }
bool unpack_t::iat_dispatcher(uc_engine *uc, uint64_t address, uint32_t size, bool unpack_t::iat_dispatcher(uc_engine* uc,
uint64_t address,
uint32_t size,
unpack_t* unpack) { unpack_t* unpack) {
auto vec = address - IAT_VECTOR_TABLE; auto vec = address - IAT_VECTOR_TABLE;
for (auto& [iat_name, iat_hook_data] : unpack->iat_hooks) { for (auto& [iat_name, iat_hook_data] : unpack->iat_hooks) {
@ -612,9 +631,12 @@ bool unpack_t::iat_dispatcher(uc_engine *uc, uint64_t address, uint32_t size,
return false; return false;
} }
bool unpack_t::unpack_section_callback(uc_engine *uc, uc_mem_type type, bool unpack_t::unpack_section_callback(uc_engine* uc,
uint64_t address, int size, uc_mem_type type,
int64_t value, unpack_t *unpack) { uint64_t address,
int size,
int64_t value,
unpack_t* unpack) {
if (address == unpack->pack_section_offset + unpack->img_base) { if (address == unpack->pack_section_offset + unpack->img_base) {
std::printf("> last byte written to unpack section... dumping...\n"); std::printf("> last byte written to unpack section... dumping...\n");
uc_emu_stop(uc); uc_emu_stop(uc);
@ -623,8 +645,12 @@ bool unpack_t::unpack_section_callback(uc_engine *uc, uc_mem_type type,
return true; return true;
} }
void unpack_t::invalid_mem(uc_engine *uc, uc_mem_type type, uint64_t address, void unpack_t::invalid_mem(uc_engine* uc,
int size, int64_t value, unpack_t *unpack) { uc_mem_type type,
uint64_t address,
int size,
int64_t value,
unpack_t* unpack) {
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);

@ -8,7 +8,8 @@ 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) uc_close(uc_ctx); if (uc_ctx)
uc_close(uc_ctx);
} }
bool emu_t::init() { bool emu_t::init() {
@ -52,7 +53,8 @@ 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) continue; if (iat_thunk->is_ordinal)
continue;
iat_thunk->function = IAT_VECTOR_TABLE; iat_thunk->function = IAT_VECTOR_TABLE;
} }
} }
@ -120,13 +122,15 @@ bool emu_t::get_trace(std::vector<vm::instrs::code_block_t> &entries) {
return false; return false;
} }
if (cc_block) code_blocks.push_back(code_block); if (cc_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) continue; if (!_code_block.code_block.jcc.has_jcc)
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: {
@ -375,7 +379,9 @@ 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, uint64_t address, uint32_t size, 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;
vmp2::v2::entry_t vinstr_entry; vmp2::v2::entry_t vinstr_entry;
@ -491,7 +497,8 @@ bool emu_t::code_exec_callback(uc_engine *uc, uint64_t address, uint32_t size,
} }
if (!vm_handler.profile) { if (!vm_handler.profile) {
if (!g_force_emu) obj->cc_block = nullptr; if (!g_force_emu)
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) +
@ -500,7 +507,8 @@ bool emu_t::code_exec_callback(uc_engine *uc, uint64_t address, uint32_t size,
vm::util::print(vm_handler.instrs); vm::util::print(vm_handler.instrs);
std::printf("\n\n"); std::printf("\n\n");
if (!g_force_emu) exit(0); if (!g_force_emu)
exit(0);
} }
auto vinstr = vm::instrs::get(*obj->g_vm_ctx, vinstr_entry); auto vinstr = vm::instrs::get(*obj->g_vm_ctx, vinstr_entry);
@ -662,8 +670,12 @@ void emu_t::int_callback(uc_engine *uc, std::uint32_t intno, emu_t *obj) {
} }
} }
void emu_t::invalid_mem(uc_engine *uc, uc_mem_type type, uint64_t address, void emu_t::invalid_mem(uc_engine* uc,
int size, int64_t value, emu_t *obj) { uc_mem_type type,
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