Files
awesome_anti_virus_engine/ai_anti_malware/sandbox_api_emu.cpp
Huoji's 60c4ef5f58 Update project documentation and enhance malware detection engine
- Completely rewrite README.md with comprehensive project overview and technical details
- Add detailed explanation of antivirus engine architecture and detection strategies
- Implement multi-stage malware detection with machine learning, sandbox, and PE structure analysis
- Update project configuration and add new source files for enhanced detection capabilities
- Integrate XGBoost machine learning model with C++ export functionality
- Improve sandbox environment with advanced module and LDR data table handling
- Remove legacy Python prediction and training scripts in favor of C++ implementation
2025-03-09 21:59:22 +08:00

1606 lines
59 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"
#include "sandbox_api_winhttp.h"
std::string getDllNameFromApiSetMap(const std::string& apiSet);
auto Api_RegOpenKeyExW(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_RegCloseKey(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_AreFileApisANSI(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto Api_WideCharToMultiByte(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto Api_InitializeSListHead(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
;
auto Api_GetEnvironmentStringsW(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
;
auto Api_FreeEnvironmentStringsW(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto Api_GetProcessHeap(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_HeapAlloc(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_HeapFree(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_TlsGetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_SetLastError(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_EnterCriticalSection(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto Api_LeaveCriticalSection(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto Api_GetStartupInfoW(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto Api_GetStdHandle(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_GetFileType(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_HeapCreate(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_GetCommandLineA(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto Api_GetCommandLineW(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto Api_GetACP(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_GetCPInfo(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_MultiByteToWideChar(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto Api_SHGetKnownFolderPath(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto Api_EncodePointer(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_QueryPerformanceCounter(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t return_params_address = 0;
LARGE_INTEGER data;
BOOL origin_return_value = QueryPerformanceCounter(&data);
if (context->GetPeInfo()->isX64) {
uc_reg_read(uc, UC_X86_REG_RCX, &return_params_address);
} else {
uint64_t ebp_address = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &ebp_address);
ebp_address += 0x4;
uc_mem_read(uc, ebp_address, &return_params_address, 0x4);
}
uc_mem_write(uc, return_params_address, &data, sizeof(LARGE_INTEGER));
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&origin_return_value);
}
auto Api_GetSystemTimeAsFileTime(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
uint64_t rcx;
FILETIME file_time;
GetSystemTimeAsFileTime(&file_time);
uc_reg_read(uc, UC_X86_REG_RCX, &rcx);
uc_mem_write(uc, rcx, &file_time, sizeof(FILETIME));
}
void Api_GetCurrentThreadId(void* sandbox, uc_engine* uc, uint64_t address) {
auto context = static_cast<Sandbox*>(sandbox);
if (context->GetPeInfo()->isX64) {
uc_reg_write(uc, UC_X86_REG_RAX,
&context->GetTeb64()->ClientId.UniqueThread);
} else {
uc_reg_write(uc, UC_X86_REG_RAX,
&context->GetTeb32()->ClientId.UniqueThread);
}
}
void Api_GetCurrentProcessId(void* sandbox, uc_engine* uc, uint64_t address) {
auto context = static_cast<Sandbox*>(sandbox);
if (context->GetPeInfo()->isX64) {
uc_reg_write(uc, UC_X86_REG_RAX,
&context->GetTeb64()->ClientId.UniqueProcess);
} else {
uc_reg_write(uc, UC_X86_REG_RAX,
&context->GetTeb32()->ClientId.UniqueProcess);
}
}
auto Api_LoadLibraryA(void* sandbox, uc_engine* uc, uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t params_address = 0;
// 获取参数地址
if (context->GetPeInfo()->isX64) {
uc_reg_read(uc, UC_X86_REG_RCX, &params_address);
} else {
uint64_t ebp_address = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &ebp_address);
ebp_address += 0x4;
uc_mem_read(uc, ebp_address, &params_address, 0x4);
}
uint64_t return_address = 0;
std::string module_name;
char buffer[MAX_PATH];
size_t i = 0;
// 读取模块名称
if (params_address != 0) {
do {
uint8_t byte;
uc_mem_read(uc, params_address + i, &byte, 1);
buffer[i] = byte;
i++;
} while (buffer[i - 1] != 0 && i < MAX_PATH);
if (i > 0 && i < MAX_PATH) {
module_name = std::string(buffer);
// 确保模块名以.dll结尾不区分大小写
if (module_name.length() > 4) {
std::string ext = module_name.substr(module_name.length() - 4);
if (_stricmp(ext.c_str(), ".dll") != 0) {
module_name += ".dll";
}
} else {
module_name += ".dll";
}
std::string fuck_up_api_ms = module_name;
if (fuck_up_api_ms.find("api-ms-") != std::string::npos) {
module_name = getDllNameFromApiSetMap(fuck_up_api_ms);
if (module_name.size() <= 1) __debugbreak();
}
// 从模块列表中查找对应模块
for (const auto& module : context->GetModuleList()) {
if (_stricmp((*module).name, module_name.c_str()) == 0) {
return_address = (*module).base;
break;
}
}
}
}
printf("[*] LoadLibraryA: Module=%s, Base=0x%llx\n", module_name.c_str(),
return_address);
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&return_address);
}
auto Api_LoadLibraryExW(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t module_name_address = 0;
uint64_t flags = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = lpLibFileName, r8 = dwFlags
uc_reg_read(uc, UC_X86_REG_RCX, &module_name_address);
uc_reg_read(uc, UC_X86_REG_R8, &flags);
} else {
// x86: 从栈上读取参数
uint64_t esp_address = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uc_mem_read(uc, esp_address, &module_name_address, 0x4);
esp_address += 0x8; // 跳过hFile参数
uc_mem_read(uc, esp_address, &flags, 0x4);
}
uint64_t return_address = 0;
std::wstring module_name;
wchar_t buffer[MAX_PATH];
size_t i = 0;
bool isApiSetMapMeme = false;
// 读取宽字符模块名称
if (module_name_address != 0) {
do {
uint16_t wchar;
uc_mem_read(uc, module_name_address + (i * 2), &wchar, 2);
buffer[i] = wchar;
i++;
} while (buffer[i - 1] != 0 && i < MAX_PATH);
if (i > 0 && i < MAX_PATH) {
module_name = std::wstring(buffer);
std::string ansi_name(module_name.begin(), module_name.end());
std::string fuck_up_api_ms = ansi_name;
if (ansi_name.length() > 4) {
std::string ext = ansi_name.substr(ansi_name.length() - 4);
if (_stricmp(ext.c_str(), ".dll") != 0) {
ansi_name += ".dll";
}
} else {
ansi_name += ".dll";
}
if (ansi_name.find("api-ms-") != std::string::npos) {
ansi_name = getDllNameFromApiSetMap(ansi_name);
isApiSetMapMeme = true;
// if (ansi_name.size() <= 1) __debugbreak();
}
// 从模块列表中查找对应模块
for (const auto& module : context->GetModuleList()) {
if (_stricmp((*module).name, ansi_name.c_str()) == 0) {
return_address = (*module).base;
break;
}
}
}
}
printf("[*] LoadLibraryExW: Module=%ls, Flags=0x%llx, Base=0x%llx\n",
module_name.c_str(), flags, return_address);
if (return_address == 0 && isApiSetMapMeme) {
// 找不到就不管他了,操
return_address = 0x1337;
}
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&return_address);
}
void Api_GetLastError(void* sandbox, uc_engine* uc, uint64_t address) {
auto context = static_cast<Sandbox*>(sandbox);
DWORD last_error = 0;
// 从TEB中获取LastError
if (context->GetPeInfo()->isX64) {
last_error = context->GetTeb64()->LastErrorValue;
} else {
last_error = context->GetTeb32()->LastErrorValue;
}
printf("[*] GetLastError: LastError=0x%x\n", last_error);
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&last_error);
}
auto Api_InitializeCriticalSectionAndSpinCount(void* sandbox, uc_engine* uc,
uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t lpCriticalSection = 0;
uint32_t dwSpinCount = 0;
BOOL success = TRUE; // 默认返回成功
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = lpCriticalSection, rdx = dwSpinCount
uc_reg_read(uc, UC_X86_REG_RCX, &lpCriticalSection);
uint64_t temp_spin_count = 0;
uc_reg_read(uc, UC_X86_REG_RDX, &temp_spin_count);
dwSpinCount = static_cast<uint32_t>(temp_spin_count);
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uint32_t temp_cs = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uc_mem_read(uc, esp_address, &temp_cs, sizeof(uint32_t));
lpCriticalSection = temp_cs;
esp_address += 0x4;
uc_mem_read(uc, esp_address, &dwSpinCount, sizeof(uint32_t));
}
if (lpCriticalSection != 0) {
// 初始化关键段结构
RTL_CRITICAL_SECTION cs = {0};
cs.LockCount = -1; // 初始未锁定状态
cs.RecursionCount = 0; // 初始递归计数为0
cs.SpinCount = dwSpinCount; // 设置自旋计数
cs.OwningThread = 0; // 初始无拥有线程
cs.LockSemaphore = 0; // 初始信号量为0
// 写入初始化后的结构到目标内存
uc_mem_write(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION));
} else {
success = FALSE;
// 设置LastError
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
}
printf(
"[*] InitializeCriticalSectionAndSpinCount: CS=0x%llx, SpinCount=0x%x, "
"Success=%d\n",
lpCriticalSection, dwSpinCount, success);
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&success);
}
auto Api_InitializeCriticalSectionEx(void* sandbox, uc_engine* uc,
uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t lpCriticalSection = 0;
uint32_t dwSpinCount = 0;
uint32_t dwFlags = 0;
BOOL success = TRUE; // 默认返回成功
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = lpCriticalSection, rdx = dwSpinCount, r8 = dwFlags
uc_reg_read(uc, UC_X86_REG_RCX, &lpCriticalSection);
uint64_t temp_spin_count = 0;
uc_reg_read(uc, UC_X86_REG_RDX, &temp_spin_count);
dwSpinCount = static_cast<uint32_t>(temp_spin_count);
uint64_t temp_flags = 0;
uc_reg_read(uc, UC_X86_REG_R8, &temp_flags);
dwFlags = static_cast<uint32_t>(temp_flags);
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uint32_t temp_cs = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uc_mem_read(uc, esp_address, &temp_cs, sizeof(uint32_t));
lpCriticalSection = temp_cs;
esp_address += 0x4;
uc_mem_read(uc, esp_address, &dwSpinCount, sizeof(uint32_t));
esp_address += 0x4;
uc_mem_read(uc, esp_address, &dwFlags, sizeof(uint32_t));
}
if (lpCriticalSection != 0) {
// 初始化关键段结构
RTL_CRITICAL_SECTION cs = {0};
cs.LockCount = -1; // 初始未锁定状态
cs.RecursionCount = 0; // 初始递归计数为0
cs.SpinCount = dwSpinCount; // 设置自旋计数
cs.OwningThread = 0; // 初始无拥有线程
cs.LockSemaphore = 0; // 初始信号量为0
// 处理特殊标志
// CRITICAL_SECTION_FLAG_NO_DEBUG_INFO = 0x01000000
// CRITICAL_SECTION_FLAG_DYNAMIC_SPIN = 0x02000000
// CRITICAL_SECTION_FLAG_STATIC_INIT = 0x04000000
// CRITICAL_SECTION_FLAG_RESOURCE_TYPE = 0x08000000
// CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO = 0x10000000
// 写入初始化后的结构到目标内存
uc_mem_write(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION));
} else {
success = FALSE;
// 设置LastError
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
}
printf(
"[*] InitializeCriticalSectionEx: CS=0x%llx, SpinCount=0x%x, "
"Flags=0x%x, "
"Success=%d\n",
lpCriticalSection, dwSpinCount, dwFlags, success);
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&success);
}
auto Api_TlsAlloc(void* sandbox, uc_engine* uc, uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
DWORD tls_index = TLS_OUT_OF_INDEXES; // 默认返回失败值
// 获取TEB结构
if (context->GetPeInfo()->isX64) {
auto teb = context->GetTeb64();
// 在TLS槽中查找第一个可用的位置
for (DWORD i = 0; i < 64; i++) { // TEB中TlsSlots数组大小为64
if (teb->TlsSlots[i] == (void*)0x1337ffffff) {
teb->TlsSlots[i] = (void*)0; // 标记为已使用
tls_index = i;
break;
}
}
} else {
auto teb = context->GetTeb32();
// 在TLS槽中查找第一个可用的位置
for (DWORD i = 0; i < 64; i++) { // TEB中TlsSlots数组大小为64
if (teb->TlsSlots[i] == 0x1337) {
teb->TlsSlots[i] = 0; // 标记为已使用
tls_index = i;
break;
}
}
}
if (tls_index == TLS_OUT_OF_INDEXES) {
// 设置LastError为没有可用的TLS索引
DWORD error = ERROR_NO_MORE_ITEMS;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
}
printf("[*] TlsAlloc: Allocated TLS Index=0x%x\n", tls_index);
// 返回分配的TLS索引
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&tls_index);
}
auto Api_TlsSetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint32_t dwTlsIndex = 0;
uint64_t lpTlsValue = 0;
BOOL success = FALSE;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = dwTlsIndex, rdx = lpTlsValue
uint64_t temp_index;
uc_reg_read(uc, UC_X86_REG_RCX, &temp_index);
dwTlsIndex = static_cast<uint32_t>(temp_index);
uc_reg_read(uc, UC_X86_REG_RDX, &lpTlsValue);
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uc_mem_read(uc, esp_address, &dwTlsIndex, sizeof(uint32_t));
esp_address += 0x4;
uint32_t temp_value;
uc_mem_read(uc, esp_address, &temp_value, sizeof(uint32_t));
lpTlsValue = temp_value;
}
// 检查索引是否有效小于64
if (dwTlsIndex < 64) {
if (context->GetPeInfo()->isX64) {
auto teb = context->GetTeb64();
// 检查槽是否已分配不为nullptr
if (teb->TlsSlots[dwTlsIndex] != (void*)0x1337ffffff) {
teb->TlsSlots[dwTlsIndex] = (void*)lpTlsValue;
success = TRUE;
}
} else {
auto teb = context->GetTeb32();
// 检查槽是否已分配不为0
if (teb->TlsSlots[dwTlsIndex] != 0x1337) {
teb->TlsSlots[dwTlsIndex] = static_cast<uint32_t>(lpTlsValue);
success = TRUE;
}
}
}
if (!success) {
// 设置LastError
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
}
printf("[*] TlsSetValue: Index=0x%x, Value=0x%llx, Success=%d\n",
dwTlsIndex, lpTlsValue, success);
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&success);
}
auto Api_DeleteCriticalSection(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t lpCriticalSection = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = lpCriticalSection
uc_reg_read(uc, UC_X86_REG_RCX, &lpCriticalSection);
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uint32_t temp_cs = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uc_mem_read(uc, esp_address, &temp_cs, sizeof(uint32_t));
lpCriticalSection = temp_cs;
}
if (lpCriticalSection != 0) {
// 读取现有的关键段结构
RTL_CRITICAL_SECTION cs;
uc_mem_read(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION));
// 检查是否有线程仍在等待
if (cs.LockCount >= 0) {
// 有线程正在等待,设置错误
DWORD error = ERROR_SEM_IS_SET;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
}
// 清零内存,表示删除
memset(&cs, 0, sizeof(RTL_CRITICAL_SECTION));
uc_mem_write(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION));
}
printf("[*] DeleteCriticalSection: CS=0x%llx\n", lpCriticalSection);
}
auto Api_IsProcessorFeaturePresent(void* sandbox, uc_engine* uc,
uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint32_t feature_number = 0;
BOOL is_supported = FALSE;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = FeatureNumber
uint64_t temp_feature;
uc_reg_read(uc, UC_X86_REG_RCX, &temp_feature);
feature_number = static_cast<uint32_t>(temp_feature);
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uc_mem_read(uc, esp_address, &feature_number, sizeof(uint32_t));
}
// 模拟一些常见的处理器特性
switch (feature_number) {
case PF_FLOATING_POINT_PRECISION_ERRATA: // 0
is_supported = FALSE;
break;
case PF_FLOATING_POINT_EMULATED: // 1
is_supported = FALSE;
break;
case PF_COMPARE_EXCHANGE_DOUBLE: // 2
is_supported = TRUE;
break;
case PF_MMX_INSTRUCTIONS_AVAILABLE: // 3
is_supported = TRUE;
break;
case PF_XMMI_INSTRUCTIONS_AVAILABLE: // 6
is_supported = TRUE;
break;
case PF_3DNOW_INSTRUCTIONS_AVAILABLE: // 7
is_supported = FALSE;
break;
case PF_RDTSC_INSTRUCTION_AVAILABLE: // 8
is_supported = TRUE;
break;
case PF_PAE_ENABLED: // 9
is_supported = TRUE;
break;
case PF_XMMI64_INSTRUCTIONS_AVAILABLE: // 10
is_supported = TRUE;
break;
case PF_SSE_DAZ_MODE_AVAILABLE: // 11
is_supported = TRUE;
break;
case PF_NX_ENABLED: // 12
is_supported = TRUE;
break;
case PF_SSE3_INSTRUCTIONS_AVAILABLE: // 13
is_supported = TRUE;
break;
case PF_COMPARE_EXCHANGE128: // 14
is_supported = TRUE;
break;
case PF_XSAVE_ENABLED: // 17
is_supported = TRUE;
break;
case PF_ARM_VFP_32_REGISTERS_AVAILABLE: // 18
is_supported = FALSE;
break;
default:
is_supported = FALSE;
break;
}
printf("[*] IsProcessorFeaturePresent: Feature=0x%x, Supported=%d\n",
feature_number, is_supported);
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&is_supported);
}
auto Api_GetProcAddress(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t moduleHandle = 0;
uint64_t functionNameAddr = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = hModule, rdx = lpProcName
uc_reg_read(uc, UC_X86_REG_RCX, &moduleHandle);
uc_reg_read(uc, UC_X86_REG_RDX, &functionNameAddr);
} else {
// x86: 从栈上读取参数
uint64_t esp_address = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uint32_t temp_handle = 0;
uint32_t temp_name_addr = 0;
uc_mem_read(uc, esp_address, &temp_handle, sizeof(uint32_t));
uc_mem_read(uc, esp_address + 0x4, &temp_name_addr, sizeof(uint32_t));
moduleHandle = temp_handle;
functionNameAddr = temp_name_addr;
}
uint64_t return_address = 0;
// 读取函数名
if (functionNameAddr == 0) {
__debugbreak();
}
// 通过名称查找
char functionName[256] = {0};
size_t i = 0;
do {
uint8_t byte;
uc_mem_read(uc, functionNameAddr + i, &byte, 1);
functionName[i] = byte;
i++;
} while (functionName[i - 1] != 0 && i < sizeof(functionName));
context->CheckMalwareActive_GetProcAddress(functionName);
// 在模块列表中查找对应模块
for (const auto& module : context->GetModuleList()) {
if (module->base == moduleHandle) {
// 遍历导出函数查找对应名称
for (const auto& exp : module->export_function) {
// 使用 _stricmp 进行大小写不敏感的比较
if (_stricmp(exp->name, functionName) == 0) {
return_address = module->base + exp->function_address;
break;
}
}
break;
}
}
printf("[*] GetProcAddress: Module=0x%llx, Function=%s, Address=0x%llx\n",
moduleHandle, functionName, return_address);
// 设置返回值
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&return_address);
}
auto Sandbox::FreeBlock(uint64_t address) -> bool {
// 查找包含此地址的堆段
HeapSegment* segment = FindHeapSegment(address);
if (!segment) return false;
// 查找对应的块
HeapBlock* current = segment->blocks;
while (current != nullptr) {
if (current->address == address) {
if (current->is_free) return false; // 已经是空闲的
current->is_free = true;
MergeBlocks(current); // 尝试合并相邻的空闲块
return true;
}
current = current->next;
}
return false;
}
auto Sandbox::FindHeapSegment(uint64_t address) -> HeapSegment* {
for (auto& pair : m_heapSegments) {
HeapSegment* segment = pair.second;
if (address >= segment->base &&
address < segment->base + segment->size) {
return segment;
}
}
return nullptr;
}
auto Sandbox::MergeBlocks(HeapBlock* block) -> void {
// 与后一个块合并
if (block->next && block->next->is_free) {
block->size += block->next->size;
HeapBlock* temp = block->next;
block->next = temp->next;
if (block->next) {
block->next->prev = block;
}
delete temp;
}
// 与前一个块合并
if (block->prev && block->prev->is_free) {
block->prev->size += block->size;
block->prev->next = block->next;
if (block->next) {
block->next->prev = block->prev;
}
delete block;
}
}
auto Sandbox::SplitBlock(HeapBlock* block, size_t size) -> void {
size_t remaining_size = block->size - size;
block->size = size;
auto new_block = new HeapBlock();
new_block->address = block->address + size;
new_block->size = remaining_size;
new_block->is_free = true;
new_block->next = block->next;
new_block->prev = block;
if (block->next) {
block->next->prev = new_block;
}
block->next = new_block;
}
auto Sandbox::InitCommandLine(std::string commandLine) -> void {
// 设置默认的命令行字符串
m_commandLine = commandLine;
// 将ANSI命令行字符串写入模拟内存
uc_mem_map(m_ucEngine, CMDLINE_ADDRESS, PAGE_SIZE,
UC_PROT_READ | UC_PROT_WRITE);
uc_mem_write(m_ucEngine, CMDLINE_ADDRESS, m_commandLine.c_str(),
m_commandLine.length() + 1);
// 为宽字符命令行分配内存
uc_mem_map(m_ucEngine, CMDLINEW_ADDRESS, PAGE_SIZE,
UC_PROT_READ | UC_PROT_WRITE);
// 将ANSI字符串转换为宽字符字符串
std::wstring wCommandLine(m_commandLine.begin(), m_commandLine.end());
// 写入宽字符命令行字符串
uc_mem_write(m_ucEngine, CMDLINEW_ADDRESS, wCommandLine.c_str(),
(wCommandLine.length() + 1) * sizeof(wchar_t));
}
auto Api_GetModuleFileNameW(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t hModule = 0;
uint64_t lpFilename = 0;
uint32_t nSize = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = hModule, rdx = lpFilename, r8 = nSize
uc_reg_read(uc, UC_X86_REG_RCX, &hModule);
uc_reg_read(uc, UC_X86_REG_RDX, &lpFilename);
uint64_t temp_size;
uc_reg_read(uc, UC_X86_REG_R8, &temp_size);
nSize = static_cast<uint32_t>(temp_size);
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uint32_t temp_module = 0;
uint32_t temp_filename = 0;
uc_mem_read(uc, esp_address, &temp_module, sizeof(uint32_t));
uc_mem_read(uc, esp_address + 0x4, &temp_filename, sizeof(uint32_t));
uc_mem_read(uc, esp_address + 0x8, &nSize, sizeof(uint32_t));
hModule = temp_module;
lpFilename = temp_filename;
}
uint32_t result = 0;
// 验证参数
if (lpFilename == 0 || nSize == 0) {
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
return;
}
std::wstring modulePath;
if (hModule == 0) {
// 如果hModule为NULL,返回主模块(PE文件)的路径
modulePath = std::wstring(context->GetPeInfo()->inputFilePath.begin(),
context->GetPeInfo()->inputFilePath.end());
} else {
// 在模块列表中查找对应模块
bool found = false;
for (const auto& module : context->GetModuleList()) {
if (module->base == hModule) {
// 构建完整的模块路径
char windowsPath[MAX_PATH];
GetWindowsDirectoryA(windowsPath, sizeof(windowsPath));
// 根据PE架构选择正确的系统目录
const std::string systemDir = context->GetPeInfo()->isX64
? "\\System32\\"
: "\\SysWOW64\\";
std::string fullPath =
std::string(windowsPath) + systemDir + module->name;
modulePath = std::wstring(fullPath.begin(), fullPath.end());
found = true;
break;
}
}
if (!found) {
DWORD error = ERROR_MOD_NOT_FOUND;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
uc_reg_write(
uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
return;
}
}
// 检查缓冲区大小是否足够
if (nSize < modulePath.length() + 1) {
// 缓冲区太小,返回所需大小
result = static_cast<uint32_t>(modulePath.length() + 1);
DWORD error = ERROR_INSUFFICIENT_BUFFER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
} else {
// 写入路径到缓冲区
if (uc_mem_write(uc, lpFilename, modulePath.c_str(),
(modulePath.length() + 1) * sizeof(wchar_t)) ==
UC_ERR_OK) {
result = static_cast<uint32_t>(modulePath.length());
} else {
result = 0;
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
}
}
printf(
"[*] GetModuleFileNameW: Module=0x%llx, Buffer=0x%llx, Size=%u, "
"Result=%u, Path=%ls\n",
hModule, lpFilename, nSize, result, modulePath.c_str());
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
}
// 实现 SetUnhandledExceptionFilter API
auto Api_SetUnhandledExceptionFilter(void* sandbox, uc_engine* uc,
uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t lpTopLevelExceptionFilter = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = lpTopLevelExceptionFilter
uc_reg_read(uc, UC_X86_REG_RCX, &lpTopLevelExceptionFilter);
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uint32_t temp_filter = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uc_mem_read(uc, esp_address, &temp_filter, sizeof(uint32_t));
lpTopLevelExceptionFilter = temp_filter;
}
// 简单实现返回NULL表示没有之前的过滤器
uint64_t prev_filter = 0;
printf("[*] SetUnhandledExceptionFilter: Filter=0x%llx\n",
lpTopLevelExceptionFilter);
// 返回之前的过滤器在这里始终返回NULL
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&prev_filter);
}
// 将Windows VirtualProtect保护标志转换为Unicorn内存保护标志
uint32_t WindowsToUnicornProtect(uint32_t windowsProtect) {
uint32_t unicornProtect = UC_PROT_NONE;
// 转换基本属性
if (windowsProtect & (PAGE_READONLY | PAGE_READWRITE | PAGE_EXECUTE_READ |
PAGE_EXECUTE_READWRITE)) {
unicornProtect |= UC_PROT_READ;
}
if (windowsProtect & (PAGE_READWRITE | PAGE_WRITECOPY |
PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) {
unicornProtect |= UC_PROT_WRITE;
}
if (windowsProtect & (PAGE_EXECUTE | PAGE_EXECUTE_READ |
PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) {
unicornProtect |= UC_PROT_EXEC;
}
// 如果没有有效标志,至少给予读权限以防崩溃
if (unicornProtect == UC_PROT_NONE && windowsProtect != PAGE_NOACCESS) {
unicornProtect = UC_PROT_READ;
}
return unicornProtect;
}
auto Api_VirtualProtect(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t lpAddress = 0;
uint64_t dwSize = 0;
uint32_t flNewProtect = 0;
uint64_t lpflOldProtect = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = lpAddress, rdx = dwSize, r8 = flNewProtect, r9 =
// lpflOldProtect
uc_reg_read(uc, UC_X86_REG_RCX, &lpAddress);
uc_reg_read(uc, UC_X86_REG_RDX, &dwSize);
uint64_t temp_protect;
uc_reg_read(uc, UC_X86_REG_R8, &temp_protect);
flNewProtect = static_cast<uint32_t>(temp_protect);
uc_reg_read(uc, UC_X86_REG_R9, &lpflOldProtect);
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uint32_t temp_address;
uc_mem_read(uc, esp_address, &temp_address, sizeof(uint32_t));
lpAddress = temp_address;
esp_address += 0x4;
uint32_t temp_size;
uc_mem_read(uc, esp_address, &temp_size, sizeof(uint32_t));
dwSize = temp_size;
esp_address += 0x4;
uc_mem_read(uc, esp_address, &flNewProtect, sizeof(uint32_t));
esp_address += 0x4;
uint32_t temp_old_protect;
uc_mem_read(uc, esp_address, &temp_old_protect, sizeof(uint32_t));
lpflOldProtect = temp_old_protect;
}
// 检查参数有效性
if (lpAddress == 0 || dwSize == 0 || lpflOldProtect == 0) {
uint64_t result = 0; // FALSE
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
// 设置错误码 - ERROR_INVALID_PARAMETER
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
return;
}
// 检查地址范围是否已映射
uint32_t unicornProtect = WindowsToUnicornProtect(flNewProtect);
uc_err err = uc_mem_protect(uc, lpAddress, dwSize, unicornProtect);
if (err != UC_ERR_OK) {
uint64_t result = 0; // FALSE
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
// 设置错误码 - ERROR_INVALID_ADDRESS
DWORD error = ERROR_INVALID_ADDRESS;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
return;
}
// 模拟的旧保护属性,这里简化为一个默认值
// 实际应用中,应该从内存映射表中获取
uint32_t oldProtect = PAGE_READWRITE;
// 写入旧保护值到lpflOldProtect指向的内存
uc_mem_write(uc, lpflOldProtect, &oldProtect, sizeof(uint32_t));
// 调试输出
printf(
"[*] VirtualProtect: Address=0x%llx, Size=0x%llx, WindowsProtect=0x%x, "
"UnicornProtect=0x%x, OldProtect=0x%x\n",
lpAddress, dwSize, flNewProtect, unicornProtect, oldProtect);
// 设置返回值为TRUE
uint64_t result = 1; // TRUE
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
}
auto Api___set_app_type(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
int32_t appType = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = appType
uint64_t temp_type;
uc_reg_read(uc, UC_X86_REG_RCX, &temp_type);
appType = static_cast<int32_t>(temp_type);
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uc_mem_read(uc, esp_address, &appType, sizeof(int32_t));
}
// 简单地返回0表示成功
int32_t result = 0;
printf("[*] __set_app_type: AppType=%d\n", appType);
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
}
auto Api___p__fmode(void* sandbox, uc_engine* uc, uint64_t address) -> void {
auto sb = static_cast<Sandbox*>(sandbox);
// 检查是否已经创建了 _fmode 变量
static uint64_t fmode_address = 0;
static int32_t fmode_value = 0; // 默认为文本模式 (_O_TEXT)
if (fmode_address == 0) {
// 为 _fmode 变量分配内存
// 使用特定堆地址,与其他 API 一致
uint64_t heap_handle =
sb->GetPeInfo()->isX64 ? HEAP_ADDRESS_64 : HEAP_ADDRESS_32;
// 在堆上分配空间
HeapSegment* segment = nullptr;
auto it = sb->m_heapSegments.find(heap_handle);
if (it != sb->m_heapSegments.end()) {
segment = it->second;
} else {
// 创建新的堆段
segment = sb->CreateHeapSegment(heap_handle, 0x10000);
sb->m_heapSegments[heap_handle] = segment;
}
if (segment) {
fmode_address = sb->AllocateFromSegment(segment, sizeof(int32_t));
if (fmode_address) {
// 初始化 _fmode 为文本模式
uc_mem_write(uc, fmode_address, &fmode_value, sizeof(int32_t));
printf(
"[*] __p__fmode: Allocated _fmode at 0x%llx with value "
"%d\n",
fmode_address, fmode_value);
}
}
}
// 返回 _fmode 变量的地址
printf("[*] __p__fmode: Returning address 0x%llx\n", fmode_address);
// 设置返回值
if (sb->GetPeInfo()->isX64) {
uc_reg_write(uc, UC_X86_REG_RAX, &fmode_address);
} else {
uint32_t eax = static_cast<uint32_t>(fmode_address);
uc_reg_write(uc, UC_X86_REG_EAX, &eax);
}
}
auto Api_Sleep(void* sandbox, uc_engine* uc, uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t milliseconds;
// 获取参数dwMilliseconds
if (context->GetPeInfo()->isX64) {
// 在x64中参数通过寄存器传递第一个参数在RCX
uc_reg_read(uc, UC_X86_REG_RCX, &milliseconds);
} else {
// 在x86中参数通过栈传递
uint32_t esp;
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
// 返回地址之后的4字节是第一个参数
uc_mem_read(uc, esp + 4, &milliseconds, sizeof(milliseconds));
}
// 打印日志
printf("Sleep API called with %u milliseconds\n", milliseconds);
}
// 内部实现函数,处理实际的模块句柄获取逻辑
auto GetModuleHandleInternal(void* sandbox, const std::wstring& moduleName)
-> HMODULE {
auto* sb = static_cast<Sandbox*>(sandbox);
// 如果模块名为空,返回当前进程的基址
if (moduleName.empty()) {
return reinterpret_cast<HMODULE>(sb->GetPeInfo()->RecImageBase);
}
// 在已加载的模块中查找
for (const auto& module : sb->GetModuleList()) {
std::string currentModuleNameA = module->name;
std::wstring currentModuleName =
std::wstring(currentModuleNameA.begin(), currentModuleNameA.end());
if (_wcsicmp(currentModuleName.c_str(), moduleName.c_str()) == 0) {
return reinterpret_cast<HMODULE>(module->base);
}
}
return nullptr;
}
// GetModuleHandleA的实现
auto Api_GetModuleHandleA(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto* sb = static_cast<Sandbox*>(sandbox);
uint64_t esp = 0, rsp = 0;
HMODULE result = nullptr;
if (sb->GetPeInfo()->isX64) {
// 获取第一个参数 (rcx)
uint64_t moduleNamePtr;
uc_reg_read(uc, UC_X86_REG_RCX, &moduleNamePtr);
uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
std::string moduleName;
if (moduleNamePtr != 0) {
// 读取ANSI字符串
char ch;
size_t i = 0;
do {
if (uc_mem_read(uc, moduleNamePtr + i, &ch, 1) != UC_ERR_OK) {
break;
}
if (ch == 0) break;
moduleName += ch;
i++;
} while (i < MAX_PATH);
}
// 转换为宽字符
std::wstring wModuleName;
if (!moduleName.empty()) {
wModuleName = std::wstring(moduleName.begin(), moduleName.end());
}
// 获取模块句柄
result = GetModuleHandleInternal(sandbox, wModuleName);
// 设置返回值
uc_reg_write(uc, UC_X86_REG_RAX, &result);
} else {
// 32位实现
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
uint32_t moduleNamePtr;
uc_mem_read(uc, esp + 4, &moduleNamePtr, sizeof(moduleNamePtr));
std::string moduleName;
if (moduleNamePtr != 0) {
// 读取ANSI字符串
char ch;
size_t i = 0;
do {
if (uc_mem_read(uc, moduleNamePtr + i, &ch, 1) != UC_ERR_OK) {
break;
}
if (ch == 0) break;
moduleName += ch;
i++;
} while (i < MAX_PATH);
}
// 转换为宽字符
std::wstring wModuleName;
if (!moduleName.empty()) {
wModuleName = std::wstring(moduleName.begin(), moduleName.end());
}
// 获取模块句柄
result = GetModuleHandleInternal(sandbox, wModuleName);
// 设置返回值
uint32_t result32 = reinterpret_cast<uint32_t>(result);
uc_reg_write(uc, UC_X86_REG_EAX, &result32);
}
// 设置错误码
DWORD error = result ? 0 : ERROR_MOD_NOT_FOUND;
if (sb->GetPeInfo()->isX64) {
sb->GetTeb64()->LastErrorValue = error;
} else {
sb->GetTeb32()->LastErrorValue = error;
}
}
// GetModuleHandleW的实现
auto Api_GetModuleHandleW(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto* sb = static_cast<Sandbox*>(sandbox);
uint64_t esp = 0, rsp = 0;
HMODULE result = nullptr;
if (sb->GetPeInfo()->isX64) {
// 获取第一个参数 (rcx)
uint64_t moduleNamePtr;
uc_reg_read(uc, UC_X86_REG_RCX, &moduleNamePtr);
uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
std::wstring moduleName;
if (moduleNamePtr != 0) {
// 读取宽字符串
wchar_t ch;
size_t i = 0;
do {
if (uc_mem_read(uc, moduleNamePtr + (i * 2), &ch, 2) !=
UC_ERR_OK) {
break;
}
if (ch == 0) break;
moduleName += ch;
i++;
} while (i < MAX_PATH);
}
// 获取模块句柄
result = GetModuleHandleInternal(sandbox, moduleName);
// 设置返回值
uc_reg_write(uc, UC_X86_REG_RAX, &result);
} else {
// 32位实现
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
uint32_t moduleNamePtr;
uc_mem_read(uc, esp + 4, &moduleNamePtr, sizeof(moduleNamePtr));
std::wstring moduleName;
if (moduleNamePtr != 0) {
// 读取宽字符串
wchar_t ch;
size_t i = 0;
do {
if (uc_mem_read(uc, moduleNamePtr + (i * 2), &ch, 2) !=
UC_ERR_OK) {
break;
}
if (ch == 0) break;
moduleName += ch;
i++;
} while (i < MAX_PATH);
}
// 获取模块句柄
result = GetModuleHandleInternal(sandbox, moduleName);
// 设置返回值
uint32_t result32 = reinterpret_cast<uint32_t>(result);
uc_reg_write(uc, UC_X86_REG_EAX, &result32);
}
// 设置错误码
DWORD error = result ? 0 : ERROR_MOD_NOT_FOUND;
if (sb->GetPeInfo()->isX64) {
sb->GetTeb64()->LastErrorValue = error;
} else {
sb->GetTeb32()->LastErrorValue = error;
}
}
auto Api_VirtualQuery(void* sandbox, uc_engine* uc, uint64_t address) -> void {
auto* context = static_cast<Sandbox*>(sandbox);
uint64_t lpAddress = 0;
uint64_t lpBuffer = 0;
uint32_t dwLength = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// 64位参数获取
uc_reg_read(uc, UC_X86_REG_RCX, &lpAddress);
uc_reg_read(uc, UC_X86_REG_RDX, &lpBuffer);
uint64_t temp_length = 0;
uc_reg_read(uc, UC_X86_REG_R8, &temp_length);
dwLength = static_cast<uint32_t>(temp_length);
} else {
// 32位参数获取
uint32_t esp = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
esp += 0x4; // 跳过返回地址
uint32_t temp_address = 0;
uint32_t temp_buffer = 0;
uc_mem_read(uc, esp, &temp_address, sizeof(uint32_t));
uc_mem_read(uc, esp + 0x4, &temp_buffer, sizeof(uint32_t));
uc_mem_read(uc, esp + 0x8, &dwLength, sizeof(uint32_t));
lpAddress = temp_address;
lpBuffer = temp_buffer;
}
// 构造MEMORY_BASIC_INFORMATION结构
MEMORY_BASIC_INFORMATION mbi = {};
mbi.BaseAddress =
reinterpret_cast<void*>(static_cast<uintptr_t>(lpAddress));
mbi.AllocationBase = mbi.BaseAddress;
mbi.AllocationProtect = PAGE_EXECUTE_READWRITE; // 默认保护属性
mbi.RegionSize = 0x1000; // 默认页大小
mbi.State = MEM_COMMIT;
mbi.Protect = PAGE_EXECUTE_READWRITE;
mbi.Type = MEM_PRIVATE;
// 写入查询结果
uint64_t return_value = 0;
if (lpBuffer != 0 && dwLength >= sizeof(MEMORY_BASIC_INFORMATION)) {
uc_mem_write(uc, lpBuffer, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
return_value = sizeof(MEMORY_BASIC_INFORMATION);
}
// 设置返回值
if (context->GetPeInfo()->isX64) {
uc_reg_write(uc, UC_X86_REG_RAX, &return_value);
} else {
uint32_t return_value_32 = static_cast<uint32_t>(return_value);
uc_reg_write(uc, UC_X86_REG_EAX, &return_value_32);
}
}
auto Sandbox::InitApiHooks() -> void {
auto FakeApi_GetSystemTimeAsFileTime =
_fakeApi{.func = Api_GetSystemTimeAsFileTime, .paramCount = 1};
auto FakeApi_GetCurrentThreadId =
_fakeApi{.func = Api_GetCurrentThreadId, .paramCount = 0};
auto FakeApi_GetCurrentProcessId =
_fakeApi{.func = Api_GetCurrentProcessId, .paramCount = 0};
auto FakeApi_QueryPerformanceCounter =
_fakeApi{.func = Api_QueryPerformanceCounter, .paramCount = 1};
auto FakeApi_LoadLibraryA =
_fakeApi{.func = Api_LoadLibraryA, .paramCount = 1};
auto FakeApi_LoadLibraryExW =
_fakeApi{.func = Api_LoadLibraryExW, .paramCount = 3};
auto FakeApi_GetLastError =
_fakeApi{.func = Api_GetLastError, .paramCount = 0};
auto FakeApi_InitializeCriticalSectionAndSpinCount = _fakeApi{
.func = Api_InitializeCriticalSectionAndSpinCount, .paramCount = 2};
auto FakeApi_InitializeCriticalSectionEx =
_fakeApi{.func = Api_InitializeCriticalSectionEx, .paramCount = 3};
auto FakeApi_DeleteCriticalSection =
_fakeApi{.func = Api_DeleteCriticalSection, .paramCount = 1};
auto FakeApi_TlsAlloc = _fakeApi{.func = Api_TlsAlloc, .paramCount = 0};
auto FakeApi_TlsSetValue =
_fakeApi{.func = Api_TlsSetValue, .paramCount = 2};
auto FakeApi_IsProcessorFeaturePresent =
_fakeApi{.func = Api_IsProcessorFeaturePresent, .paramCount = 1};
auto FakeApi_GetProcAddress =
_fakeApi{.func = Api_GetProcAddress, .paramCount = 2};
auto FakeApi_GetProcessHeap =
_fakeApi{.func = Api_GetProcessHeap, .paramCount = 0};
auto FakeApi_HeapAlloc = _fakeApi{.func = Api_HeapAlloc, .paramCount = 3};
auto FakeApi_HeapFree = _fakeApi{.func = Api_HeapFree, .paramCount = 3};
auto FakeApi_TlsGetValue =
_fakeApi{.func = Api_TlsGetValue, .paramCount = 1};
auto FakeApi_SetLastError =
_fakeApi{.func = Api_SetLastError, .paramCount = 1};
auto FakeApi_EnterCriticalSection =
_fakeApi{.func = Api_EnterCriticalSection, .paramCount = 1};
auto FakeApi_LeaveCriticalSection =
_fakeApi{.func = Api_LeaveCriticalSection, .paramCount = 1};
auto FakeApi_GetStartupInfoW =
_fakeApi{.func = Api_GetStartupInfoW, .paramCount = 1};
auto FakeApi_GetStdHandle =
_fakeApi{.func = Api_GetStdHandle, .paramCount = 1};
auto FakeApi_GetFileType =
_fakeApi{.func = Api_GetFileType, .paramCount = 1};
auto FakeApi_GetCommandLineA =
_fakeApi{.func = Api_GetCommandLineA, .paramCount = 0};
auto FakeApi_GetCommandLineW =
_fakeApi{.func = Api_GetCommandLineW, .paramCount = 0};
auto FakeApi_GetACP = _fakeApi{.func = Api_GetACP, .paramCount = 0};
auto FakeApi_GetCPInfo = _fakeApi{.func = Api_GetCPInfo, .paramCount = 2};
auto FakeApi_MultiByteToWideChar =
_fakeApi{.func = Api_MultiByteToWideChar, .paramCount = 6};
auto FakeApi_GetModuleFileNameW =
_fakeApi{.func = Api_GetModuleFileNameW, .paramCount = 3};
auto FakeApi_AreFileApisANSI =
_fakeApi{.func = Api_AreFileApisANSI, .paramCount = 0};
auto FakeApi_WideCharToMultiByte =
_fakeApi{.func = Api_WideCharToMultiByte, .paramCount = 8};
auto FakeApi_InitializeSListHead =
_fakeApi{.func = Api_InitializeSListHead, .paramCount = 1};
auto FakeApi_GetEnvironmentStringsW =
_fakeApi{.func = Api_GetEnvironmentStringsW, .paramCount = 0};
auto FakeApi_FreeEnvironmentStringsW =
_fakeApi{.func = Api_FreeEnvironmentStringsW, .paramCount = 1};
auto FakeApi_SetUnhandledExceptionFilter =
_fakeApi{.func = Api_SetUnhandledExceptionFilter, .paramCount = 1};
auto FakeApi_VirtualProtect =
_fakeApi{.func = Api_VirtualProtect, .paramCount = 4};
auto FakeApi_RegOpenKeyExW =
_fakeApi{.func = Api_RegOpenKeyExW, .paramCount = 5};
auto FakeApi_RegCloseKey =
_fakeApi{.func = Api_RegCloseKey, .paramCount = 1};
auto FakeApi___set_app_type =
_fakeApi{.func = Api___set_app_type, .paramCount = 1};
auto FakeApi___p__fmode = _fakeApi{.func = Api___p__fmode, .paramCount = 0};
auto FakeApi_Sleep = _fakeApi{.func = Api_Sleep, .paramCount = 1};
auto FakeApi_SHGetKnownFolderPath =
_fakeApi{.func = Api_SHGetKnownFolderPath, .paramCount = 4};
// 添加新的Internet API函数
auto FakeApi_InternetOpenA =
_fakeApi{.func = Api_InternetOpenA, .paramCount = 5};
auto FakeApi_InternetOpenUrlA =
_fakeApi{.func = Api_InternetOpenUrlA, .paramCount = 6};
auto FakeApi_InternetCloseHandle =
_fakeApi{.func = Api_InternetCloseHandle, .paramCount = 1};
auto FakeApi_InternetReadFile =
_fakeApi{.func = Api_InternetReadFile, .paramCount = 4};
auto FakeApi_EncodePointer =
_fakeApi{.func = Api_EncodePointer, .paramCount = 1};
auto FakeApi_HeapCreate = _fakeApi{.func = Api_HeapCreate, .paramCount = 3};
auto FakeApi_GetModuleHandleA =
_fakeApi{.func = Api_GetModuleHandleA, .paramCount = 1};
auto FakeApi_GetModuleHandleW =
_fakeApi{.func = Api_GetModuleHandleW, .paramCount = 1};
auto FakeApi_VirtualQuery =
_fakeApi{.func = Api_VirtualQuery, .paramCount = 3};
api_map = {
{"GetSystemTimeAsFileTime",
std::make_shared<_fakeApi>(FakeApi_GetSystemTimeAsFileTime)},
{"GetCurrentThreadId",
std::make_shared<_fakeApi>(FakeApi_GetCurrentThreadId)},
{"GetCurrentProcessId",
std::make_shared<_fakeApi>(FakeApi_GetCurrentProcessId)},
{"QueryPerformanceCounter",
std::make_shared<_fakeApi>(FakeApi_QueryPerformanceCounter)},
{"LoadLibraryA", std::make_shared<_fakeApi>(FakeApi_LoadLibraryA)},
{"LoadLibraryExW", std::make_shared<_fakeApi>(FakeApi_LoadLibraryExW)},
{"GetLastError", std::make_shared<_fakeApi>(FakeApi_GetLastError)},
{"InitializeCriticalSectionAndSpinCount",
std::make_shared<_fakeApi>(
FakeApi_InitializeCriticalSectionAndSpinCount)},
{"InitializeCriticalSectionEx",
std::make_shared<_fakeApi>(FakeApi_InitializeCriticalSectionEx)},
{"DeleteCriticalSection",
std::make_shared<_fakeApi>(FakeApi_DeleteCriticalSection)},
{"TlsAlloc", std::make_shared<_fakeApi>(FakeApi_TlsAlloc)},
{"TlsSetValue", std::make_shared<_fakeApi>(FakeApi_TlsSetValue)},
{"IsProcessorFeaturePresent",
std::make_shared<_fakeApi>(FakeApi_IsProcessorFeaturePresent)},
{"GetProcAddress", std::make_shared<_fakeApi>(FakeApi_GetProcAddress)},
{"GetProcessHeap", std::make_shared<_fakeApi>(FakeApi_GetProcessHeap)},
{"HeapAlloc", std::make_shared<_fakeApi>(FakeApi_HeapAlloc)},
{"HeapFree", std::make_shared<_fakeApi>(FakeApi_HeapFree)},
{"TlsGetValue", std::make_shared<_fakeApi>(FakeApi_TlsGetValue)},
{"SetLastError", std::make_shared<_fakeApi>(FakeApi_SetLastError)},
{"EnterCriticalSection",
std::make_shared<_fakeApi>(FakeApi_EnterCriticalSection)},
{"LeaveCriticalSection",
std::make_shared<_fakeApi>(FakeApi_LeaveCriticalSection)},
{"GetStartupInfoW",
std::make_shared<_fakeApi>(FakeApi_GetStartupInfoW)},
{"GetStdHandle", std::make_shared<_fakeApi>(FakeApi_GetStdHandle)},
{"GetFileType", std::make_shared<_fakeApi>(FakeApi_GetFileType)},
{"GetCommandLineA",
std::make_shared<_fakeApi>(FakeApi_GetCommandLineA)},
{"GetCommandLineW",
std::make_shared<_fakeApi>(FakeApi_GetCommandLineW)},
{"GetACP", std::make_shared<_fakeApi>(FakeApi_GetACP)},
{"GetCPInfo", std::make_shared<_fakeApi>(FakeApi_GetCPInfo)},
{"MultiByteToWideChar",
std::make_shared<_fakeApi>(FakeApi_MultiByteToWideChar)},
{"GetModuleFileNameW",
std::make_shared<_fakeApi>(FakeApi_GetModuleFileNameW)},
{"AreFileApisANSI",
std::make_shared<_fakeApi>(FakeApi_AreFileApisANSI)},
{"WideCharToMultiByte",
std::make_shared<_fakeApi>(FakeApi_WideCharToMultiByte)},
{"InitializeSListHead",
std::make_shared<_fakeApi>(FakeApi_InitializeSListHead)},
{"GetEnvironmentStringsW",
std::make_shared<_fakeApi>(FakeApi_GetEnvironmentStringsW)},
{"FreeEnvironmentStringsW",
std::make_shared<_fakeApi>(FakeApi_FreeEnvironmentStringsW)},
{"SetUnhandledExceptionFilter",
std::make_shared<_fakeApi>(FakeApi_SetUnhandledExceptionFilter)},
{"VirtualProtect", std::make_shared<_fakeApi>(FakeApi_VirtualProtect)},
{"RegOpenKeyExW", std::make_shared<_fakeApi>(FakeApi_RegOpenKeyExW)},
{"RegCloseKey", std::make_shared<_fakeApi>(FakeApi_RegCloseKey)},
{"_set_app_type", std::make_shared<_fakeApi>(FakeApi___set_app_type)},
{"_p__fmode", std::make_shared<_fakeApi>(FakeApi___p__fmode)},
{"Sleep", std::make_shared<_fakeApi>(FakeApi_Sleep)},
{"SHGetKnownFolderPath",
std::make_shared<_fakeApi>(FakeApi_SHGetKnownFolderPath)},
// 添加新的Internet API映射
{"InternetOpenA", std::make_shared<_fakeApi>(FakeApi_InternetOpenA)},
{"InternetOpenUrlA",
std::make_shared<_fakeApi>(FakeApi_InternetOpenUrlA)},
{"InternetCloseHandle",
std::make_shared<_fakeApi>(FakeApi_InternetCloseHandle)},
{"InternetReadFile",
std::make_shared<_fakeApi>(FakeApi_InternetReadFile)},
{"EncodePointer", std::make_shared<_fakeApi>(FakeApi_EncodePointer)},
{"HeapCreate", std::make_shared<_fakeApi>(FakeApi_HeapCreate)},
{"GetModuleHandleA",
std::make_shared<_fakeApi>(FakeApi_GetModuleHandleA)},
{"GetModuleHandleW",
std::make_shared<_fakeApi>(FakeApi_GetModuleHandleW)},
{"VirtualQuery", std::make_shared<_fakeApi>(FakeApi_VirtualQuery)},
};
}
auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip,
std::string ApiName) -> void {
auto it = api_map.find(ApiName);
if (it != api_map.end()) {
it->second->func(this, uc, address);
this->ApiCallList.push_back(ApiName);
// 获取参数数量
int paramCount = it->second->paramCount;
uint32_t esp;
uint64_t rsp;
// 从栈上读取返回地址
uint64_t return_address;
if (this->GetPeInfo()->isX64) { // 64位系统
uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
// 读取8字节的返回地址
uc_mem_read(uc, rsp, &return_address, 8);
// x64下前4个参数通过寄存器传递超过的部分通过栈传递
// int stack_params = (paramCount > 4) ? (paramCount - 4) : 0;
// 调整栈指针每个参数8字节 + 返回地址8字节
// rsp += (stack_params * 8) + 8;
rsp += 8;
// 设置RIP为返回地址
uc_reg_write(uc, UC_X86_REG_RIP, &return_address);
} else { // 32位系统
// 读取4字节的返回地址
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
uc_mem_read(uc, esp, &return_address, 4);
uint32_t return_address_32;
uc_mem_read(uc, esp, &return_address_32, 4);
printf("return_address_32: %x\n", return_address_32);
// x86下所有参数都通过栈传递
// 调整栈指针每个参数4字节 + 返回地址4字节
esp += (paramCount * 4) + 4;
// 设置EIP为返回地址
uc_reg_write(uc, UC_X86_REG_EIP, &return_address_32);
}
if (this->GetPeInfo()->isX64) {
uc_reg_write(uc, UC_X86_REG_RSP, &rsp);
} else {
uc_reg_write(uc, UC_X86_REG_ESP, &esp);
}
return;
}
printf("ApiName: %s not found\n", ApiName.c_str());
uc_emu_stop(uc);
return;
}