|
|
@ -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);
|
|
|
|