Files
awesome_anti_virus_engine/ai_anti_malware/sandbox.cpp
2025-03-07 19:27:05 +08:00

705 lines
27 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "sandbox.h"
#include "sandbox_callbacks.h"
std::string getDllNameFromApiSetMap(const std::string& apiSet) {
const std::wstring wApiSet(apiSet.begin(), apiSet.end());
// 获取系统版本信息
using RtlGetVersionFunc = LONG(__stdcall*)(PRTL_OSVERSIONINFOW);
const auto pRtlGetVersion = reinterpret_cast<RtlGetVersionFunc>(
GetProcAddress(LoadLibraryA("ntdll.dll"), "RtlGetVersion"));
RTL_OSVERSIONINFOEXW verInfo{};
verInfo.dwOSVersionInfoSize = sizeof(verInfo);
pRtlGetVersion(reinterpret_cast<PRTL_OSVERSIONINFOW>(&verInfo));
const ULONG verShort = (verInfo.dwMajorVersion << 8) |
(verInfo.dwMinorVersion << 4) |
verInfo.wServicePackMajor;
if (verShort >= static_cast<ULONG>(WinVer::kWin10)) {
const auto apiSetMap = reinterpret_cast<API_SET_NAMESPACE_ARRAY_10*>(
reinterpret_cast<X64PEB*>(__readgsqword(0x60))->ApiSetMap);
const auto apiSetMapAsNumber = reinterpret_cast<ULONG_PTR>(apiSetMap);
auto nsEntry = reinterpret_cast<PAPI_SET_NAMESPACE_ENTRY_10>(
apiSetMap->Start + apiSetMapAsNumber);
// 遍历API集合查找匹配项
for (ULONG i = 0; i < apiSetMap->Count; i++) {
UNICODE_STRING nameString{}, valueString{};
nameString.MaximumLength = static_cast<USHORT>(nsEntry->NameLength);
nameString.Length = static_cast<USHORT>(nsEntry->NameLength);
nameString.Buffer = reinterpret_cast<PWCHAR>(apiSetMapAsNumber +
nsEntry->NameOffset);
const std::wstring name(nameString.Buffer,
nameString.Length / sizeof(WCHAR));
const std::wstring fullName = name + L".dll";
if (_wcsicmp(wApiSet.c_str(), fullName.c_str()) == 0) {
if (nsEntry->ValueCount == 0) {
return "";
}
const auto valueEntry =
reinterpret_cast<PAPI_SET_VALUE_ENTRY_10>(
apiSetMapAsNumber + nsEntry->ValueOffset);
valueString.Buffer = reinterpret_cast<PWCHAR>(
apiSetMapAsNumber + valueEntry->ValueOffset);
valueString.MaximumLength =
static_cast<USHORT>(valueEntry->ValueLength);
valueString.Length =
static_cast<USHORT>(valueEntry->ValueLength);
const std::wstring value(valueString.Buffer,
valueString.Length / sizeof(WCHAR));
return {value.begin(), value.end()};
}
++nsEntry;
}
} else {
// 不支持Windows 10以下版本
throw std::runtime_error("Unsupported Windows version");
}
return "";
}
class ImportResolver : public peconv::t_function_resolver {
public:
explicit ImportResolver(std::map<std::string, uint64_t> context)
: _functionMap(std::move(context)) {}
FARPROC resolve_func(LPSTR libName, LPSTR funcName) override {
return reinterpret_cast<FARPROC>(_functionMap[std::string(funcName)]);
}
private:
std::map<std::string, uint64_t> _functionMap;
};
class cListImportNames : public peconv::ImportThunksCallback {
public:
cListImportNames(BYTE* _modulePtr, size_t _moduleSize,
std::vector<std::shared_ptr<moudle_import>>& name_to_addr)
: ImportThunksCallback(_modulePtr, _moduleSize),
nameToAddr(name_to_addr) {}
virtual bool processThunks(LPSTR lib_name, ULONG_PTR origFirstThunkPtr,
ULONG_PTR firstThunkPtr) {
if (this->is64b) {
IMAGE_THUNK_DATA64* desc =
reinterpret_cast<IMAGE_THUNK_DATA64*>(origFirstThunkPtr);
ULONGLONG* call_via = reinterpret_cast<ULONGLONG*>(firstThunkPtr);
return processThunks_tpl<ULONGLONG, IMAGE_THUNK_DATA64>(
lib_name, desc, call_via, IMAGE_ORDINAL_FLAG64);
}
IMAGE_THUNK_DATA32* desc =
reinterpret_cast<IMAGE_THUNK_DATA32*>(origFirstThunkPtr);
DWORD* call_via = reinterpret_cast<DWORD*>(firstThunkPtr);
return processThunks_tpl<DWORD, IMAGE_THUNK_DATA32>(
lib_name, desc, call_via, IMAGE_ORDINAL_FLAG32);
}
protected:
template <typename T_FIELD, typename T_IMAGE_THUNK_DATA>
bool processThunks_tpl(LPSTR lib_name, T_IMAGE_THUNK_DATA* desc,
T_FIELD* call_via, T_FIELD ordinal_flag) {
DWORD call_via_rva = static_cast<DWORD>((ULONG_PTR)call_via -
(ULONG_PTR)this->modulePtr);
LPSTR func_name = NULL;
if ((desc->u1.Ordinal & ordinal_flag) == 0) {
PIMAGE_IMPORT_BY_NAME by_name =
(PIMAGE_IMPORT_BY_NAME)((ULONGLONG)modulePtr +
desc->u1.AddressOfData);
func_name = reinterpret_cast<LPSTR>(by_name->Name);
std::string fuck_up_api_ms = lib_name;
if (fuck_up_api_ms.find("api-ms-") != std::string::npos) {
fuck_up_api_ms = getDllNameFromApiSetMap(fuck_up_api_ms);
if (fuck_up_api_ms.size() <= 1) __debugbreak();
}
auto import_data = std::make_shared<moudle_import>();
memcpy(import_data->name, func_name, strlen(func_name));
memcpy(import_data->dll_name, fuck_up_api_ms.c_str(),
fuck_up_api_ms.size());
import_data->function_address = call_via_rva;
import_data->is_delayed_import = false;
nameToAddr.push_back(import_data);
}
return true;
}
std::vector<std::shared_ptr<moudle_import>>& nameToAddr;
};
class cFixImprot : public peconv::t_function_resolver {
public:
// 构造函数接收Sandbox实例的引用
explicit cFixImprot(Sandbox* sandbox) : m_sandbox(sandbox) {}
// 实现导入函数解析
virtual FARPROC resolve_func(LPSTR lib_name, LPSTR func_name) override {
// 遍历所有已加载的模块
for (const auto& module : m_sandbox->m_moduleList) {
// 检查模块名是否匹配
if (_stricmp(module->name, lib_name) == 0) {
// 遍历模块的导出函数
for (const auto& exp : m_sandbox->m_exportFuncDict) {
// 检查函数名是否匹配
if (strcmp(exp->name, func_name) == 0) {
auto newBase = reinterpret_cast<FARPROC>(
module->base + exp->function_address);
printf("fix import: %s => %llx \n", func_name, newBase);
// 返回在模拟器中的虚拟地址
return newBase;
}
}
}
}
__debugbreak();
return nullptr;
}
private:
Sandbox* m_sandbox; // Sandbox实例的指针
};
Sandbox::Sandbox() {}
Sandbox::~Sandbox() {}
auto Sandbox::PushModuleToVM(const char* dllName, uint64_t moduleBase) -> void {
for (auto module : m_moduleList) {
if (module->real_base == moduleBase) {
printf("skip module name: %s (already loaded)\n", module->name);
return;
}
}
// 解析PE头
auto* dosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(moduleBase);
auto* ntHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(
reinterpret_cast<LPBYTE>(moduleBase) + dosHeader->e_lfanew);
// 获取区段对齐值
DWORD sectionAlignment =
(ntHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
? reinterpret_cast<PIMAGE_NT_HEADERS64>(ntHeaders)
->OptionalHeader.SectionAlignment
: ntHeaders->OptionalHeader.SectionAlignment;
// 获取区段头
auto* sectionHeader = reinterpret_cast<PIMAGE_SECTION_HEADER>(
reinterpret_cast<PUCHAR>(ntHeaders) + sizeof(ntHeaders->Signature) +
sizeof(ntHeaders->FileHeader) +
ntHeaders->FileHeader.SizeOfOptionalHeader);
// 创建新模块
struct_moudle newModule{};
strncpy(newModule.name, dllName, strlen(dllName));
newModule.base =
this->m_peInfo->isX64 ? moduleBase : static_cast<uint32_t>(moduleBase);
newModule.real_base = moduleBase;
newModule.entry = ntHeaders->OptionalHeader.AddressOfEntryPoint;
newModule.size = ntHeaders->OptionalHeader.SizeOfImage;
// 处理区段
for (WORD i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++) {
const auto& section = sectionHeader[i];
// if (!(section.Characteristics &
// (IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE))) {
// continue;
// }
// 设置区段保护属性
int protection = UC_PROT_READ;
if (section.Characteristics & IMAGE_SCN_MEM_EXECUTE)
protection |= UC_PROT_EXEC;
if (section.Characteristics & IMAGE_SCN_MEM_WRITE)
protection |= UC_PROT_WRITE;
// 计算区段大小
auto sectionSize =
AlignSize(max(section.Misc.VirtualSize, section.SizeOfRawData),
sectionAlignment);
// 创建区段信息
moudle_section newSection{};
strncpy(newSection.name, reinterpret_cast<const char*>(section.Name),
8);
newSection.base = section.VirtualAddress;
newSection.size = sectionSize;
newSection.protect_flag = protection;
newModule.sections.push_back(
std::make_shared<moudle_section>(newSection));
std::cout << "[PE] " << dllName << " Section found: " << newSection.name
<< '\n';
}
m_moduleList.push_back(std::make_shared<struct_moudle>(newModule));
printf("push `%s` module to vm base: %llx vm size: %llx\n", newModule.name,
newModule.base, newModule.size);
uc_mem_map(m_ucEngine, newModule.base, newModule.size,
UC_PROT_READ | UC_PROT_EXEC);
uc_mem_write(m_ucEngine, newModule.base, (void*)moduleBase, newModule.size);
if (peconv::relocate_module((BYTE*)moduleBase, newModule.size,
newModule.base) == false) {
throw std::runtime_error("Failed to relocate module");
}
}
auto Sandbox::ResolveExport(uint64_t moduleBase)
-> std::vector<std::shared_ptr<moudle_export>> {
DWORD exportSize = 0;
static RtlImageDirectoryEntryToDataFn fnRtlImageDirectoryEntryToData;
if (fnRtlImageDirectoryEntryToData == nullptr) {
fnRtlImageDirectoryEntryToData =
reinterpret_cast<RtlImageDirectoryEntryToDataFn>(GetProcAddress(
GetModuleHandleA("ntdll.dll"), "RtlImageDirectoryEntryToData"));
}
// 获取导出表
PIMAGE_EXPORT_DIRECTORY exportDirectory =
static_cast<PIMAGE_EXPORT_DIRECTORY>(fnRtlImageDirectoryEntryToData(
reinterpret_cast<PUCHAR>(moduleBase), TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT, &exportSize));
if (exportDirectory) {
const DWORD numberOfNames = exportDirectory->NumberOfNames;
PDWORD addressOfFunctions =
reinterpret_cast<PDWORD>(reinterpret_cast<PUCHAR>(moduleBase) +
exportDirectory->AddressOfFunctions);
PDWORD addressOfNames =
reinterpret_cast<PDWORD>(reinterpret_cast<PUCHAR>(moduleBase) +
exportDirectory->AddressOfNames);
PWORD addressOfNameOrdinals =
reinterpret_cast<PWORD>(reinterpret_cast<PUCHAR>(moduleBase) +
exportDirectory->AddressOfNameOrdinals);
// 遍历导出函数
for (size_t i = 0; i < numberOfNames; i++) {
PCHAR functionName = reinterpret_cast<PCHAR>(
reinterpret_cast<PUCHAR>(moduleBase) + addressOfNames[i]);
// 获取函数RVA
const DWORD functionRva =
addressOfFunctions[addressOfNameOrdinals[i]];
// 创建导出数据结构
moudle_export exportData{};
memcpy(exportData.name, functionName, strlen(functionName));
exportData.function_address = functionRva;
exportData.ordinal = static_cast<WORD>(
addressOfNameOrdinals[i] + exportDirectory->Base); // 设置序号
m_exportFuncDict.push_back(
std::make_shared<moudle_export>(exportData));
}
}
return m_exportFuncDict;
}
auto Sandbox::ResolveImportExports() -> void {
for (auto module : m_moduleList) {
const auto exports = ResolveExport(module->real_base);
for (const auto item : exports) {
printf("import export: [%s] %s => %llx\n", module->name, item->name,
item->function_address);
module->export_function.push_back(item);
}
}
}
auto Sandbox::processImportModule(const moudle_import* importModule) -> void {
for (auto module : m_moduleList) {
if (strcmp(module->name, importModule->dll_name) == 0) {
printf("skip module name: %s (already loaded)\n", module->name);
return;
}
}
// 构建模块路径
const std::string systemDir =
m_peInfo->isX64 ? "\\System32\\" : "\\SysWOW64\\";
char windowsPath[MAX_PATH];
if (!GetWindowsDirectoryA(windowsPath, sizeof(windowsPath))) {
throw std::runtime_error("Failed to get Windows directory");
}
const std::string modulePath =
std::string(windowsPath) + systemDir + importModule->dll_name;
// 加载PE模块
size_t mappedPeSize = 0;
const auto moduleBase = reinterpret_cast<uint64_t>(
peconv::load_pe_module(modulePath.c_str(), mappedPeSize, false, false));
if (!moduleBase) {
return;
}
// 添加到虚拟机
PushModuleToVM(importModule->dll_name, moduleBase);
}
auto Sandbox::ResoveImport() -> void {
// 处理延迟导入
peconv::load_delayed_imports(static_cast<BYTE*>(m_peInfo->peBuffer), 0);
// 解析导入表
cListImportNames importCallback(static_cast<BYTE*>(m_peInfo->peBuffer),
m_peInfo->peSize, m_impFuncDict);
if (!peconv::process_import_table(static_cast<BYTE*>(m_peInfo->peBuffer),
m_peInfo->peSize, &importCallback)) {
throw std::runtime_error("Failed to process import table");
}
// 处理每个导入模块
for (const auto& importModule : m_impFuncDict) {
processImportModule(importModule.get());
}
}
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
*/
uint64_t m_KSharedUserDataBase = 0x7FFE0000;
uint64_t m_KSharedUserDataEnd = 0x7FFE0FFF; // 0x7FFE2000
uint64_t m_KSharedUserDataSize =
AlignSize(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 =
AlignSize(this->m_peInfo->isX64 ? STACK_BASE_64 : STACK_BASE_32, 16);
m_stackSize =
AlignSize(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 + AlignSize(sizeof(X64PEB), PAGE_SIZE);
m_tebEnd = m_tebBase + AlignSize(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 = AlignSize(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 + AlignSize(sizeof(X32PEB), PAGE_SIZE);
m_tebEnd = m_tebBase + AlignSize(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);
// 设置堆
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;
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);
}
// 映射新的内存区域
size_t envSize = AlignSize(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;
}
}
auto Sandbox::InitEnv(std::shared_ptr<BasicPeInfo> peInfo) -> void {
m_peInfo = peInfo;
if (cs_open(CS_ARCH_X86, peInfo->isX64 ? CS_MODE_64 : CS_MODE_32,
&m_csHandle) != CS_ERR_OK) {
throw std::runtime_error("Failed to initialize Capstone");
}
if (uc_open(UC_ARCH_X86, peInfo->isX64 ? UC_MODE_64 : UC_MODE_32,
&m_ucEngine) != UC_ERR_OK) {
cs_close(&m_csHandle); // 清理已分配的capstone资源
throw std::runtime_error("Failed to initialize Unicorn");
}
ResoveImport();
ResolveImportExports();
// 修复导入表
cFixImprot importFixer(this);
if (!peconv::load_imports(m_peInfo->peBuffer, &importFixer)) {
throw std::runtime_error("Failed to fix imports");
}
uc_err ucErr = uc_mem_map(m_ucEngine, m_peInfo->RecImageBase,
m_peInfo->peSize, UC_PROT_ALL);
if (ucErr != UC_ERR_OK) {
throw std::runtime_error("Failed to map memory");
}
uc_mem_write(m_ucEngine, m_peInfo->RecImageBase, m_peInfo->peBuffer,
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);
}
auto Sandbox::Run() -> void {
// 初始化堆栈
uc_err err = uc_mem_map(m_ucEngine, m_stackBase, m_stackSize,
UC_PROT_READ | UC_PROT_WRITE);
if (err != UC_ERR_OK) {
throw std::runtime_error("Failed to map stack memory");
}
// 初始化堆
err = uc_mem_map(m_ucEngine, m_heapBase, m_heapSize,
UC_PROT_READ | UC_PROT_WRITE);
if (err != UC_ERR_OK) {
throw std::runtime_error("Failed to map heap memory");
}
// 设置寄存器
uint64_t rsp = m_stackEnd - 256;
err = uc_reg_write(m_ucEngine,
m_peInfo->isX64 ? UC_X86_REG_RSP : UC_X86_REG_ESP, &rsp);
if (err != UC_ERR_OK) {
throw std::runtime_error("Failed to write stack pointer");
}
uint64_t rbp =
rsp - (m_peInfo->isX64 ? sizeof(uint64_t) : sizeof(uint32_t));
uc_reg_write(m_ucEngine, m_peInfo->isX64 ? UC_X86_REG_RBP : UC_X86_REG_EBP,
&rbp);
// 设置入口点
uint64_t entryPoint = m_peInfo->RecImageBase + m_peInfo->entryPoint;
// 添加钩子
uc_hook hook_code, hook_mem, hook_mem_unmap, hook_mem_write, hook_syscall;
// 代码执行钩子
err = uc_hook_add(m_ucEngine, &hook_code, UC_HOOK_CODE,
reinterpret_cast<void*>(sandboxCallbacks::handleCodeRun),
this, 1, 0);
if (err != UC_ERR_OK) {
throw std::runtime_error("Failed to add code hook");
}
// 内存读取钩子
err =
uc_hook_add(m_ucEngine, &hook_mem, UC_HOOK_MEM_READ | UC_HOOK_MEM_FETCH,
reinterpret_cast<void*>(sandboxCallbacks::handleMemoryRead),
this, 1, 0);
if (err != UC_ERR_OK) {
throw std::runtime_error("Failed to add memory read hook");
}
// 未映射内存访问钩子
err = uc_hook_add(
m_ucEngine, &hook_mem_unmap,
UC_HOOK_MEM_FETCH_UNMAPPED | UC_HOOK_MEM_READ_UNMAPPED |
UC_HOOK_MEM_WRITE_UNMAPPED | UC_HOOK_MEM_FETCH_PROT,
reinterpret_cast<void*>(sandboxCallbacks::handleMemoryUnmapRead), this,
1, 0);
if (err != UC_ERR_OK) {
throw std::runtime_error("Failed to add unmapped memory hook");
}
// 内存写入钩子
err = uc_hook_add(
m_ucEngine, &hook_mem_write, UC_HOOK_MEM_WRITE | UC_HOOK_MEM_WRITE_PROT,
reinterpret_cast<void*>(sandboxCallbacks::handleMemoryWrite), this, 1,
0);
if (err != UC_ERR_OK) {
throw std::runtime_error("Failed to add memory write hook");
}
// 系统调用钩子
err = uc_hook_add(m_ucEngine, &hook_syscall, UC_HOOK_INTR | UC_HOOK_INSN,
reinterpret_cast<void*>(sandboxCallbacks::handleSyscall),
this, 1, 0, UC_X86_INS_SYSCALL);
if (err != UC_ERR_OK) {
throw std::runtime_error("Failed to add syscall hook");
}
// 设置EIP/RIP
err = uc_reg_write(m_ucEngine,
m_peInfo->isX64 ? UC_X86_REG_RIP : UC_X86_REG_EIP,
&entryPoint);
if (err != UC_ERR_OK) {
throw std::runtime_error("Failed to set entry point");
}
InitApiHooks();
std::cout << "Starting execution at " << std::hex << entryPoint
<< std::endl;
err = uc_emu_start(m_ucEngine, entryPoint, m_peInfo->imageEnd, 0, 0);
if (err != UC_ERR_OK) {
std::cerr << "Emulation error: " << uc_strerror(err) << std::endl;
// 32位环境下的错误处理
if (!m_peInfo->isX64) {
uint32_t eip;
uc_reg_read(m_ucEngine, UC_X86_REG_EIP, &eip);
std::cerr << "Error occurred at EIP: 0x" << std::hex << eip
<< std::endl;
// 尝试读取当前指令
uint8_t instruction[16];
if (uc_mem_read(m_ucEngine, eip, instruction,
sizeof(instruction)) == UC_ERR_OK) {
std::cerr << "Instruction bytes: ";
for (int i = 0; i < 16; i++) {
printf("%02X ", instruction[i]);
}
std::cerr << std::endl;
}
}
}
}
auto Sandbox::GetEnvString() -> std::vector<wchar_t> {
std::vector<wchar_t> envBlock;
// 添加一些基本的环境变量
const std::wstring vars[] = {
L"ALLUSERSPROFILE=C:\\ProgramData",
L"APPDATA=C:\\Users\\User\\AppData\\Roaming",
L"CommonProgramFiles=C:\\Program Files\\Common Files",
L"COMPUTERNAME=DESKTOP",
L"ComSpec=C:\\Windows\\system32\\cmd.exe",
L"HOMEDRIVE=C:",
L"HOMEPATH=\\Users\\User",
L"LOCALAPPDATA=C:\\Users\\User\\AppData\\Local",
L"NUMBER_OF_PROCESSORS=8",
L"OS=Windows_NT",
L"Path=C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem",
L"PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC",
L"PROCESSOR_ARCHITECTURE=AMD64",
L"ProgramData=C:\\ProgramData",
L"ProgramFiles=C:\\Program Files",
L"PROMPT=$P$G",
L"SystemDrive=C:",
L"SystemRoot=C:\\Windows",
L"TEMP=C:\\Users\\User\\AppData\\Local\\Temp",
L"TMP=C:\\Users\\User\\AppData\\Local\\Temp",
L"USERDOMAIN=DESKTOP",
L"USERNAME=User",
L"USERPROFILE=C:\\Users\\User",
L"windir=C:\\Windows"};
// 将环境变量添加到块中
for (const auto& var : vars) {
envBlock.insert(envBlock.end(), var.begin(), var.end());
envBlock.push_back(L'\0'); // 每个变量以null结尾
}
envBlock.push_back(L'\0'); // 环境块以额外的null结尾
return envBlock;
}
auto Sandbox::GetEnvStringsSize() -> size_t {
return GetEnvString().size() * sizeof(wchar_t);
}