按照样本优化了一下

This commit is contained in:
Huoji's
2025-04-23 03:48:16 +08:00
parent 8cfd24ab43
commit 785f0da7fe
11 changed files with 747 additions and 329 deletions

View File

@@ -111,7 +111,8 @@ public:
// 遍历所有已加载的模块
for (const auto& module : m_sandbox->m_moduleList) {
// 检查模块名是否匹配
if (_stricmp(module->name, lib_name) == 0) {
if (module->name == std::string(lib_name) == 0) {
// 遍历该模块的导出函数
for (const auto& exp : module->export_function) {
// 检查函数名是否匹配
@@ -144,7 +145,7 @@ public:
}
//序号导出,非常癌症的修复.
if (strcmp(module->name, lib_name) == 0) {
if (std::string(lib_name) == module->name) {
int ordinalNum = std::atoi(func_name);
if (exp->ordinal == ordinalNum) {
auto newBase = reinterpret_cast<FARPROC>(
@@ -263,7 +264,7 @@ auto Sandbox::PushModuleToVM(const char* dllName, uint64_t moduleBase, uint64_t
}
}
auto Sandbox::CreateModuleInfo(const char* dllName, uint64_t moduleBase,
auto Sandbox::CreateModuleInfo(std::string dllName, uint64_t moduleBase,
uint64_t realModuleBase, uint64_t bufferAddress)
-> std::shared_ptr<struct_moudle> {
// 解析PE头
@@ -283,9 +284,8 @@ auto Sandbox::CreateModuleInfo(const char* dllName, uint64_t moduleBase,
reinterpret_cast<PUCHAR>(ntHeaders) + sizeof(ntHeaders->Signature) +
sizeof(ntHeaders->FileHeader) +
ntHeaders->FileHeader.SizeOfOptionalHeader);
struct_moudle newModule{};
strncpy(newModule.name, dllName, strlen(dllName));
newModule.name = dllName.c_str();
newModule.base = moduleBase;
newModule.real_base = realModuleBase;
newModule.entry = ntHeaders->OptionalHeader.AddressOfEntryPoint;
@@ -396,8 +396,16 @@ auto Sandbox::ResolveImportExports() -> void {
}
}
auto Sandbox::mapSystemModuleToVmByName(std::string systemName) -> void {
std::string tempMatchName = systemName;
std::transform(tempMatchName.begin(), tempMatchName.end(), tempMatchName.begin(),
[](unsigned char c) { return std::toupper(c); });
for (auto module : m_moduleList) {
if (strcmp(module->name, systemName.c_str()) == 0) {
std::string listModuleName = module->name;
std::transform(listModuleName.begin(), listModuleName.end(), listModuleName.begin(),
[](unsigned char c) { return std::toupper(c); });
if (tempMatchName == listModuleName) {
if (LOG_LEVEL > 0) {
printf("skip module name: %s (already loaded)\n", module->name);
}
@@ -428,8 +436,11 @@ auto Sandbox::mapSystemModuleToVmByName(std::string systemName) -> void {
PushModuleToVM(systemName.c_str(), moduleBase, mappedPeSize);
}
auto Sandbox::processImportModule(const moudle_import* importModule) -> void {
std::string impModule = importModule->dll_name;
std::transform(impModule.begin(), impModule.end(), impModule.begin(),
[](unsigned char c) { return std::toupper(c); });
mapSystemModuleToVmByName(importModule->dll_name);
mapSystemModuleToVmByName(impModule);
}
auto Sandbox::ResoveImport() -> void {
// 处理延迟导入
@@ -453,194 +464,7 @@ auto Sandbox::ResoveImport() -> void {
mapSystemModuleToVmByName(importModule->dll_name);
}
}
auto Sandbox::SetupVirtualMachine() -> void {
SegmentSelector cs = {0};
cs.fields.index = 1;
uc_reg_write(m_ucEngine, UC_X86_REG_CS, &cs.all);
SegmentSelector ds = {0};
ds.fields.index = 2;
uc_reg_write(m_ucEngine, UC_X86_REG_DS, &ds.all);
SegmentSelector ss = {0};
ss.fields.index = 2;
uc_reg_write(m_ucEngine, UC_X86_REG_SS, &ss.all);
SegmentSelector es = {0};
es.fields.index = 2;
uc_reg_write(m_ucEngine, UC_X86_REG_ES, &es.all);
SegmentSelector gs = {0};
gs.fields.index = 2;
uc_reg_write(m_ucEngine, UC_X86_REG_GS, &gs.all);
FlagRegister eflags = {0};
eflags.fields.id = 1;
eflags.fields.intf = 1;
eflags.fields.reserved1 = 1;
uc_reg_write(m_ucEngine, UC_X86_REG_EFLAGS, &eflags.all);
uint64_t cr8 = 0;
uc_reg_write(m_ucEngine, UC_X86_REG_CR8, &cr8);
/*
映射 m_KSharedUserDataBase
*/
m_KSharedUserDataBase = 0x7FFE0000;
uint64_t m_KSharedUserDataEnd = 0x7FFE0FFF; // 0x7FFE2000
m_KSharedUserDataSize = AlignToSectionAlignment(
m_KSharedUserDataEnd - m_KSharedUserDataBase, PAGE_SIZE);
uc_mem_map(m_ucEngine, m_KSharedUserDataBase, m_KSharedUserDataSize,
UC_PROT_READ);
uc_mem_write(m_ucEngine, m_KSharedUserDataBase,
(void*)m_KSharedUserDataBase, m_KSharedUserDataSize);
m_tebBase = TEB_BASE; // 进程TEB地址
m_pebBase = PEB_BASE; // 进程PEB地址
m_envBlockBase = ENV_BLOCK_BASE; // 环境变量块地址
// stack
m_stackBase = AlignToSectionAlignment(
this->m_peInfo->isX64 ? STACK_BASE_64 : STACK_BASE_32, 16);
m_stackSize = AlignToSectionAlignment(
this->m_peInfo->isX64 ? STACK_SIZE_64 : STACK_SIZE_32, 16);
m_stackEnd = m_stackBase + m_stackSize;
// heap
m_heapBase = this->m_peInfo->isX64 ? HEAP_ADDRESS_64 : HEAP_ADDRESS_32;
m_heapSize = this->m_peInfo->isX64 ? HEAP_SIZE_64 : HEAP_SIZE_32;
m_heapEnd = m_heapBase + m_heapSize;
// 根据PE文件类型设置PEB和TEB
if (this->m_peInfo->isX64) {
// 设置64位PEB
m_peb64.ImageBaseAddress = m_peInfo->RecImageBase;
m_pebEnd =
m_pebBase + AlignToSectionAlignment(sizeof(X64PEB), PAGE_SIZE);
m_tebEnd =
m_tebBase + AlignToSectionAlignment(sizeof(X64TEB), PAGE_SIZE);
// 设置64位TEB
m_teb64.ClientId.UniqueProcess = GetCurrentProcessId();
m_teb64.ClientId.UniqueThread = GetCurrentThreadId();
m_teb64.ProcessEnvironmentBlock = reinterpret_cast<X64PEB*>(m_pebBase);
m_teb64.NtTib.StackBase = (DWORD64)m_stackBase;
m_teb64.NtTib.StackLimit = (DWORD64)m_stackSize;
// 设置堆
m_peb64.ProcessHeap = m_heapBase;
// 设置GS基址结构
m_gsBaseStruct.teb = m_tebBase;
m_gsBaseStruct.peb = m_pebBase;
uint64_t gsAllocSize =
AlignToSectionAlignment(sizeof(struct_gs_base), PAGE_SIZE);
// 映射PEB到虚拟内存
uc_mem_map(m_ucEngine, m_pebBase, m_pebEnd - m_pebBase,
UC_PROT_READ | UC_PROT_WRITE);
uc_mem_write(m_ucEngine, m_pebBase, &m_peb64, sizeof(X64PEB));
// 映射TEB到虚拟内存
uc_mem_map(m_ucEngine, m_tebBase, m_tebEnd - m_tebBase,
UC_PROT_READ | UC_PROT_WRITE);
uc_mem_write(m_ucEngine, m_tebBase, &m_teb64, sizeof(X64TEB));
// 映射GS基址结构到虚拟内存
uc_mem_map(m_ucEngine, m_gsBase, gsAllocSize, UC_PROT_READ);
uc_mem_write(m_ucEngine, m_gsBase, &m_gsBaseStruct,
sizeof(struct_gs_base));
// 设置GS基址MSR
uc_x86_msr msr;
msr.rid = static_cast<uint32_t>(Msr::kIa32GsBase);
msr.value = m_gsBase;
uc_reg_write(m_ucEngine, UC_X86_REG_MSR, &msr);
} else {
// 设置32位PEB
m_peb32.ImageBaseAddress = static_cast<ULONG>(m_peInfo->RecImageBase);
m_pebEnd =
m_pebBase + AlignToSectionAlignment(sizeof(X32PEB), PAGE_SIZE);
m_tebEnd =
m_tebBase + AlignToSectionAlignment(sizeof(X32TEB), PAGE_SIZE);
// 设置32位TEB
m_teb32.ClientId.UniqueProcess = GetCurrentProcessId();
m_teb32.ClientId.UniqueThread = GetCurrentThreadId();
m_teb32.ProcessEnvironmentBlock = static_cast<ULONG>(m_pebBase);
m_teb32.NtTib.StackBase = static_cast<ULONG>(m_stackBase);
m_teb32.NtTib.StackLimit = static_cast<ULONG>(m_stackSize);
// 初始化NT_TIB结构的其余部分
m_teb32.NtTib.Self =
static_cast<ULONG>(m_tebBase); // 关键设置Self指针指向TEB本身
m_teb32.NtTib.ExceptionList = 0xFFFFFFFF; // 初始异常链表指向特殊值
m_teb32.NtTib.Version = 0;
m_teb32.NtTib.FiberData = 0;
m_teb32.NtTib.ArbitraryUserPointer = 0;
// 设置堆
m_peb32.ProcessHeap = static_cast<ULONG>(m_heapBase);
// 映射PEB到虚拟内存
uc_mem_map(m_ucEngine, m_pebBase, m_pebEnd - m_pebBase,
UC_PROT_READ | UC_PROT_WRITE);
uc_mem_write(m_ucEngine, m_pebBase, &m_peb32, sizeof(X32PEB));
// 映射TEB到虚拟内存
uc_mem_map(m_ucEngine, m_tebBase, m_tebEnd - m_tebBase,
UC_PROT_READ | UC_PROT_WRITE);
uc_mem_write(m_ucEngine, m_tebBase, &m_teb32, sizeof(X32TEB));
// 对于32位我们需要设置FS段寄存器指向TEB
SegmentSelector fs = {0};
fs.fields.index = 3;
// 不需要设置present和dpl因为SegmentSelector结构体中没有这些字段
uc_reg_write(m_ucEngine, UC_X86_REG_FS, &fs.all);
// 设置FS基址MSR
uc_x86_msr msr;
msr.rid = static_cast<uint32_t>(Msr::kIa32FsBase);
msr.value = m_tebBase;
uc_reg_write(m_ucEngine, UC_X86_REG_MSR, &msr);
// 确保TEB中关键字段被正确初始化
// 特别是FS:18h (0x18)处应该指向自身
// 根据Native_Struct.h中X32TEB定义偏移0x18处是SelfTeb
uint32_t self_teb_ptr = static_cast<uint32_t>(m_tebBase);
// 在NT_TIB中设置SelfTeb (offset 0x18)
uc_mem_write(m_ucEngine, m_tebBase + 0x18, &self_teb_ptr,
sizeof(uint32_t));
// 确保TEB中的ProcessEnvironmentBlock字段指向PEB
uint32_t peb_ptr = static_cast<uint32_t>(m_pebBase);
// 偏移0x30处是ProcessEnvironmentBlock
uc_mem_write(m_ucEngine, m_tebBase + 0x30, &peb_ptr, sizeof(uint32_t));
}
// 映射新的内存区域
size_t envSize =
AlignToSectionAlignment(this->GetEnvStringsSize(), PAGE_SIZE);
printf("env block size: %llx\n", envSize); // 添加调试输出
uc_err envErr = uc_mem_map(m_ucEngine, m_envBlockBase, envSize,
UC_PROT_READ | UC_PROT_WRITE);
if (envErr != UC_ERR_OK) {
throw std::runtime_error("Failed to map environment block");
}
auto envData = this->GetEnvString();
envErr = uc_mem_write(m_ucEngine, m_envBlockBase, envData.data(),
envData.size() * sizeof(wchar_t));
if (envErr != UC_ERR_OK) {
throw std::runtime_error("Failed to write environment block");
}
for (DWORD i = 0; i < 64; i++) {
GetTeb64()->TlsSlots[i] = (void*)0x1337ffffff;
}
for (DWORD i = 0; i < 64; i++) {
GetTeb32()->TlsSlots[i] = 0x1337;
}
}
/*
// 在InitEnv函数之前添加这个函数
void Sandbox::RegisterComApis() {
@@ -672,10 +496,13 @@ auto Sandbox::InitEnv(std::shared_ptr<BasicPeInfo> peInfo) -> void {
cs_close(&m_csHandle); // 清理已分配的capstone资源
throw std::runtime_error("Failed to initialize Unicorn");
}
SetupVirtualMachine();
// 一定要确保他是第一个.
auto newModule = CreateModuleInfo(
"huoji.exe", m_peInfo->RecImageBase, m_peInfo->RecImageBase,
reinterpret_cast<uint64_t>(m_peInfo->peBuffer));
_ASSERTE(m_moduleList.size() == 0);
m_moduleList.push_back(newModule);
@@ -692,7 +519,35 @@ auto Sandbox::InitEnv(std::shared_ptr<BasicPeInfo> peInfo) -> void {
if (!peconv::load_imports(m_peInfo->peBuffer, &importFixer)) {
throw std::runtime_error("Failed to fix imports");
}
//检查有没有ntdll
bool isFoundNtdll = false;
bool isFoundKernelBase = false;
for (const auto& module : this->GetModuleList()) {
//我tm也不知道为什么 有些病毒这玩意找小写....然后kernel32.dll找大写.wtf is that?
if (module->name == "ntdll.dll") {
isFoundNtdll = true;
}
//真的很懒了,这个是按TAB一键出来的
if (module->name == "KERNELBASE.dll") {
isFoundKernelBase = true;
}
if (isFoundKernelBase && isFoundNtdll) {
break;
}
}
if (isFoundNtdll == false) {
if (LOG_LEVEL > 4) {
printf("Not ntdll.dll Found, manual map it \n");
}
mapSystemModuleToVmByName("ntdll.dll");
}
if (isFoundKernelBase == false) {
if (LOG_LEVEL > 4) {
printf("Not kernelbase.dll Found, manual map it \n");
}
mapSystemModuleToVmByName("kernelbase.dll");
}
// 给所有导入表加c3
for (const auto& module : this->GetModuleList()) {
// 遍历导出函数查找对应名称
@@ -710,7 +565,6 @@ auto Sandbox::InitEnv(std::shared_ptr<BasicPeInfo> peInfo) -> void {
m_peInfo->peSize);
printf("map file to vm file: %llx\n", m_peInfo->RecImageBase);
printf("map file to vm size: %llx\n", m_peInfo->peSize);
SetupVirtualMachine();
InitCommandLine(peInfo->inputFilePath);
}
@@ -811,7 +665,8 @@ auto Sandbox::Run(uint64_t address) -> void {
std::cout << "Starting execution at " << std::hex << entryPoint
<< std::endl;
uint64_t timeout = 2 * 60 * 1000 * 1000;
//uint64_t timeout = 2 * 60 * 1000 * 1000;
uint64_t timeout = 0;
// 1.入口点是必须跑的
if (m_peInfo->isDll) {
// 给rcx和rdx设置dll应该设置的
@@ -853,7 +708,7 @@ auto Sandbox::Run(uint64_t address) -> void {
std::cerr << "Entry Point Emulation error: " << uc_strerror(err)
<< std::endl;
if (address != 0) {
err = uc_emu_start(m_ucEngine, address, m_peInfo->imageEnd, timeout, 0);
err = uc_emu_start(m_ucEngine, address + MAIN_MODULE_BASE, m_peInfo->imageEnd, timeout, 0);
std::cerr << "Custom Emulation error: " << uc_strerror(err)
<< std::endl;
}