#include "sandbox.h" std::string getDllNameFromApiSetMap(const std::string& apiSet); auto Api_QueryPerformanceCounter(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(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); 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); 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); uint64_t params_address = 0; // 获取参数地址 if (context->GetPeInfo()->isX64) { uc_reg_read(uc, UC_X86_REG_RCX, ¶ms_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, ¶ms_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); 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); 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); 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(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_TlsAlloc(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(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); 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(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(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); 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); 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(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); 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)); // 在模块列表中查找对应模块 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 Api_GetProcessHeap(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); // 返回默认堆句柄(使用堆基址作为句柄) uint64_t heap_handle = context->GetPeInfo()->isX64 ? HEAP_ADDRESS_64 : HEAP_ADDRESS_32; printf("[*] GetProcessHeap: Handle=0x%llx\n", heap_handle); // 返回堆句柄 uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &heap_handle); } // 实现HeapAlloc API auto Api_HeapAlloc(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); uint64_t hHeap = 0; uint32_t dwFlags = 0; uint64_t dwBytes = 0; // 获取参数 if (context->GetPeInfo()->isX64) { // x64: rcx = hHeap, rdx = dwFlags, r8 = dwBytes uc_reg_read(uc, UC_X86_REG_RCX, &hHeap); uint64_t temp_flags; uc_reg_read(uc, UC_X86_REG_RDX, &temp_flags); dwFlags = static_cast(temp_flags); uc_reg_read(uc, UC_X86_REG_R8, &dwBytes); } else { // x86: 从栈上读取参数 uint32_t esp_address = 0; uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); esp_address += 0x4; // 跳过返回地址 uint32_t temp_heap; uc_mem_read(uc, esp_address, &temp_heap, sizeof(uint32_t)); hHeap = temp_heap; esp_address += 0x4; uc_mem_read(uc, esp_address, &dwFlags, sizeof(uint32_t)); esp_address += 0x4; uint32_t temp_bytes; uc_mem_read(uc, esp_address, &temp_bytes, sizeof(uint32_t)); dwBytes = temp_bytes; } // 检查堆句柄是否有效 uint64_t expected_handle = context->GetPeInfo()->isX64 ? HEAP_ADDRESS_64 : HEAP_ADDRESS_32; if (hHeap != expected_handle) { uint64_t null_ptr = 0; uc_reg_write( uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &null_ptr); return; } // 获取或创建堆段 HeapSegment* segment = nullptr; auto it = context->m_heapSegments.find(hHeap); if (it == context->m_heapSegments.end()) { segment = context->CreateHeapSegment( hHeap, context->GetPeInfo()->isX64 ? HEAP_SIZE_64 : HEAP_SIZE_32); context->m_heapSegments[hHeap] = segment; } else { segment = it->second; } // 分配内存 uint64_t allocated_address = context->AllocateFromSegment(segment, dwBytes); printf( "[*] HeapAlloc: Handle=0x%llx, Flags=0x%x, Size=0x%llx, " "Address=0x%llx\n", hHeap, dwFlags, dwBytes, allocated_address); // 返回分配的地址 uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &allocated_address); } // 实现HeapFree API auto Api_HeapFree(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); uint64_t hHeap = 0; uint32_t dwFlags = 0; uint64_t lpMem = 0; // 获取参数 if (context->GetPeInfo()->isX64) { // x64: rcx = hHeap, rdx = dwFlags, r8 = lpMem uc_reg_read(uc, UC_X86_REG_RCX, &hHeap); uint64_t temp_flags; uc_reg_read(uc, UC_X86_REG_RDX, &temp_flags); dwFlags = static_cast(temp_flags); uc_reg_read(uc, UC_X86_REG_R8, &lpMem); } else { // x86: 从栈上读取参数 uint32_t esp_address = 0; uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); esp_address += 0x4; // 跳过返回地址 uint32_t temp_heap; uc_mem_read(uc, esp_address, &temp_heap, sizeof(uint32_t)); hHeap = temp_heap; esp_address += 0x4; uc_mem_read(uc, esp_address, &dwFlags, sizeof(uint32_t)); esp_address += 0x4; uint32_t temp_mem; uc_mem_read(uc, esp_address, &temp_mem, sizeof(uint32_t)); lpMem = temp_mem; } // 释放内存 bool success = context->FreeBlock(lpMem); printf( "[*] HeapFree: Handle=0x%llx, Flags=0x%x, Address=0x%llx, Success=%d\n", hHeap, dwFlags, lpMem, success); // 返回操作是否成功 uint64_t result = success ? 1 : 0; uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result); } // 实现TlsGetValue API auto Api_TlsGetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); uint32_t dwTlsIndex = 0; uint64_t return_value = 0; // 获取参数 if (context->GetPeInfo()->isX64) { // x64: rcx = dwTlsIndex uint64_t temp_index; uc_reg_read(uc, UC_X86_REG_RCX, &temp_index); dwTlsIndex = static_cast(temp_index); } 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)); } // 检查索引是否有效(小于64) if (dwTlsIndex < 64) { if (context->GetPeInfo()->isX64) { auto teb = context->GetTeb64(); // 检查槽是否已分配(不为nullptr) if (teb->TlsSlots[dwTlsIndex] != (void*)0x1337ffffff) { return_value = reinterpret_cast(teb->TlsSlots[dwTlsIndex]); } else { // 槽未分配,设置LastError DWORD error = ERROR_INVALID_PARAMETER; teb->LastErrorValue = error; } } else { auto teb = context->GetTeb32(); // 检查槽是否已分配(不为0) if (teb->TlsSlots[dwTlsIndex] != 0x1337) { return_value = teb->TlsSlots[dwTlsIndex]; } else { // 槽未分配,设置LastError DWORD error = ERROR_INVALID_PARAMETER; teb->LastErrorValue = error; } } } else { // 索引无效,设置LastError DWORD error = ERROR_INVALID_PARAMETER; if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = error; } else { context->GetTeb32()->LastErrorValue = error; } } printf("[*] TlsGetValue: Index=0x%x, Value=0x%llx\n", dwTlsIndex, return_value); // 返回TLS槽中的值 uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &return_value); } auto Api_SetLastError(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); uint32_t dwErrCode = 0; // 获取参数 if (context->GetPeInfo()->isX64) { // x64: rcx = dwErrCode uint64_t temp_error; uc_reg_read(uc, UC_X86_REG_RCX, &temp_error); dwErrCode = static_cast(temp_error); } 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, &dwErrCode, sizeof(uint32_t)); } // 设置LastError值 if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = dwErrCode; } else { context->GetTeb32()->LastErrorValue = dwErrCode; } printf("[*] SetLastError: Error=0x%x\n", dwErrCode); } auto Api_EnterCriticalSection(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(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)); // 获取当前线程ID HANDLE currentThreadHandle = nullptr; if (context->GetPeInfo()->isX64) { currentThreadHandle = (HANDLE)(ULONG_PTR)context->GetTeb64()->ClientId.UniqueThread; } else { currentThreadHandle = (HANDLE)(ULONG_PTR)context->GetTeb32()->ClientId.UniqueThread; } // 如果当前线程已经拥有锁,增加递归计数 if (cs.OwningThread == currentThreadHandle) { cs.RecursionCount++; } else { // 如果没有线程拥有锁,获取它 if (cs.LockCount == -1) { cs.OwningThread = currentThreadHandle; cs.RecursionCount = 1; cs.LockCount = 0; } else { // 在实际情况下这里应该自旋等待,但在模拟环境中我们直接获取锁 cs.OwningThread = currentThreadHandle; cs.RecursionCount = 1; cs.LockCount++; } } // 写回更新后的关键段结构 uc_mem_write(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION)); } printf("[*] EnterCriticalSection: CS=0x%llx\n", lpCriticalSection); } auto Api_LeaveCriticalSection(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(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)); // 获取当前线程ID HANDLE currentThreadHandle = nullptr; if (context->GetPeInfo()->isX64) { currentThreadHandle = (HANDLE)(ULONG_PTR)context->GetTeb64()->ClientId.UniqueThread; } else { currentThreadHandle = (HANDLE)(ULONG_PTR)context->GetTeb32()->ClientId.UniqueThread; } // 检查当前线程是否拥有锁 if (cs.OwningThread == currentThreadHandle) { cs.RecursionCount--; if (cs.RecursionCount == 0) { // 完全释放锁 cs.OwningThread = nullptr; cs.LockCount = -1; } // 写回更新后的关键段结构 uc_mem_write(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION)); } } printf("[*] LeaveCriticalSection: CS=0x%llx\n", lpCriticalSection); } auto Api_GetStartupInfoW(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); uint64_t lpStartupInfo = 0; // 获取参数 if (context->GetPeInfo()->isX64) { // x64: rcx = lpStartupInfo uc_reg_read(uc, UC_X86_REG_RCX, &lpStartupInfo); } else { // x86: 从栈上读取参数 uint32_t esp_address = 0; uint32_t temp_info = 0; uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); esp_address += 0x4; // 跳过返回地址 uc_mem_read(uc, esp_address, &temp_info, sizeof(uint32_t)); lpStartupInfo = temp_info; } if (lpStartupInfo != 0) { // 创建一个默认的 STARTUPINFOW 结构 STARTUPINFOW si = {0}; si.cb = sizeof(STARTUPINFOW); si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_SHOWNORMAL; si.lpDesktop = nullptr; si.lpTitle = nullptr; si.dwX = 0; si.dwY = 0; si.dwXSize = 0; si.dwYSize = 0; si.dwXCountChars = 0; si.dwYCountChars = 0; si.dwFillAttribute = 0; si.cbReserved2 = 0; si.lpReserved2 = nullptr; si.hStdInput = nullptr; si.hStdOutput = nullptr; si.hStdError = nullptr; // 写入结构到目标内存 uc_mem_write(uc, lpStartupInfo, &si, sizeof(STARTUPINFOW)); } printf("[*] GetStartupInfoW: lpStartupInfo=0x%llx\n", lpStartupInfo); } // 实现 GetStdHandle API auto Api_GetStdHandle(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); int32_t nStdHandle = 0; HANDLE handle = INVALID_HANDLE_VALUE; // 获取参数 if (context->GetPeInfo()->isX64) { // x64: rcx = nStdHandle uint64_t temp_handle; uc_reg_read(uc, UC_X86_REG_RCX, &temp_handle); nStdHandle = static_cast(temp_handle); } 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, &nStdHandle, sizeof(int32_t)); } // 根据请求的标准句柄类型返回相应的句柄 switch ((unsigned long)nStdHandle) { case STD_INPUT_HANDLE: // -10 handle = reinterpret_cast(0x1000); // 模拟标准输入句柄 break; case STD_OUTPUT_HANDLE: // -11 handle = reinterpret_cast(0x2000); // 模拟标准输出句柄 break; // End of Selection break; case STD_ERROR_HANDLE: // -12 handle = reinterpret_cast(0x3000); // 模拟标准错误句柄 break; default: handle = INVALID_HANDLE_VALUE; // 设置错误码 if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = ERROR_INVALID_PARAMETER; } else { context->GetTeb32()->LastErrorValue = ERROR_INVALID_PARAMETER; } break; } printf("[*] GetStdHandle: Type=%d, Handle=0x%p\n", nStdHandle, handle); // 返回句柄值 uint64_t return_value = reinterpret_cast(handle); uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &return_value); } // 实现 GetFileType API auto Api_GetFileType(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); HANDLE hFile = nullptr; // 获取参数 if (context->GetPeInfo()->isX64) { // x64: rcx = hFile uint64_t temp_handle; uc_reg_read(uc, UC_X86_REG_RCX, &temp_handle); hFile = reinterpret_cast(temp_handle); } else { // x86: 从栈上读取参数 uint32_t esp_address = 0; uint32_t temp_handle = 0; uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); esp_address += 0x4; // 跳过返回地址 uc_mem_read(uc, esp_address, &temp_handle, sizeof(uint32_t)); hFile = reinterpret_cast(static_cast(temp_handle)); } DWORD file_type = FILE_TYPE_UNKNOWN; // 根据标准句柄类型返回相应的文件类型 if (hFile == reinterpret_cast(0x1000) || // STD_INPUT_HANDLE hFile == reinterpret_cast(0x2000) || // STD_OUTPUT_HANDLE hFile == reinterpret_cast(0x3000)) { // STD_ERROR_HANDLE file_type = FILE_TYPE_CHAR; // 控制台句柄通常是字符设备 } else { // 对于无效句柄,设置错误码 if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = ERROR_INVALID_HANDLE; } else { context->GetTeb32()->LastErrorValue = ERROR_INVALID_HANDLE; } file_type = FILE_TYPE_UNKNOWN; } printf("[*] GetFileType: Handle=0x%p, Type=0x%x\n", hFile, file_type); // 返回文件类型 uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &file_type); } // 实现 GetCommandLineA API auto Api_GetCommandLineA(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); printf("[*] GetCommandLineA: CommandLine=%s\n", context->GetCommandLine()); // 返回命令行字符串的地址 uint64_t return_value = context->GetCommandLineAddress(); uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &return_value); } // 实现 GetCommandLineW API auto Api_GetCommandLineW(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); printf("[*] GetCommandLineW: CommandLine=%s\n", context->GetCommandLine()); // 返回宽字符命令行字符串的地址 uint64_t return_value = context->GetCommandLineWAddress(); uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &return_value); } auto Sandbox::CreateHeapSegment(uint64_t base, size_t size) -> HeapSegment* { auto segment = new HeapSegment(); segment->base = base; segment->size = size; // 创建初始空闲块 auto block = new HeapBlock(); block->address = base; block->size = size; block->is_free = true; block->next = nullptr; block->prev = nullptr; segment->blocks = block; return segment; } auto Sandbox::AllocateFromSegment(HeapSegment* segment, size_t size) -> uint64_t { // 对齐大小到16字节 size = (size + 15) & ~15; // 查找合适的空闲块 HeapBlock* current = segment->blocks; while (current != nullptr) { if (current->is_free && current->size >= size) { // 如果块太大,分割它 if (current->size > size + 32) { // 32字节为最小块大小 SplitBlock(current, size); } current->is_free = false; return current->address; } current = current->next; } return 0; // 分配失败 } 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 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_TlsAlloc = _fakeApi{.func = Api_TlsAlloc, .paramCount = 0}; auto FakeApi_TlsSetValue = _fakeApi{.func = Api_TlsSetValue, .paramCount = 2}; auto FakeApi_DeleteCriticalSection = _fakeApi{.func = Api_DeleteCriticalSection, .paramCount = 1}; 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}; 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)}, {"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)}}; } 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()) { // 调用API函数 it->second->func(this, uc, address); // 获取参数数量 int paramCount = it->second->paramCount; // 获取当前的栈指针 uint64_t rsp; uc_reg_read(uc, this->GetPeInfo()->isX64 ? UC_X86_REG_RSP : UC_X86_REG_ESP, &rsp); // 从栈上读取返回地址 uint64_t return_address; if (this->GetPeInfo()->isX64) { // 64位系统 // 读取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; // 设置RIP为返回地址 uc_reg_write(uc, UC_X86_REG_RIP, &return_address); } else { // 32位系统 // 读取4字节的返回地址 uint32_t return_address_32; uc_mem_read(uc, rsp, &return_address_32, 4); // x86下,所有参数都通过栈传递 // 调整栈指针:每个参数4字节 + 返回地址4字节 rsp += (paramCount * 4) + 4; // 设置EIP为返回地址 uc_reg_write(uc, UC_X86_REG_EIP, &return_address_32); } // 更新栈指针,使用正确的寄存器 uc_reg_write(uc, this->GetPeInfo()->isX64 ? UC_X86_REG_RSP : UC_X86_REG_ESP, &rsp); return; } printf("ApiName: %s not found\n", ApiName.c_str()); uc_emu_stop(uc); return; }