#include "sandbox.h" #include "sandbox_callbacks.h" // 实现 AreFileApisANSI API auto Api_AreFileApisANSI(void* sandbox, uc_engine* uc, uint64_t address) -> void { // 默认返回TRUE,表示使用ANSI字符集 BOOL isAnsi = TRUE; printf("[*] AreFileApisANSI: IsAnsi=%d\n", isAnsi); // 返回结果 uc_reg_write(uc, static_cast(sandbox)->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &isAnsi); } auto Api_WideCharToMultiByte(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); uint32_t CodePage = 0; uint32_t dwFlags = 0; uint64_t lpWideCharStr = 0; int32_t cchWideChar = 0; uint64_t lpMultiByteStr = 0; int32_t cbMultiByte = 0; uint64_t lpDefaultChar = 0; uint64_t lpUsedDefaultChar = 0; // 获取参数 if (context->GetPeInfo()->isX64) { // x64: rcx, rdx, r8, r9, [rsp+0x28], [rsp+0x30], [rsp+0x38], [rsp+0x40] uint64_t temp_codepage = 0; uint64_t temp_flags = 0; uint64_t temp_widechar = 0; uint64_t temp_cchwidechar = 0; uc_reg_read(uc, UC_X86_REG_RCX, &temp_codepage); uc_reg_read(uc, UC_X86_REG_RDX, &temp_flags); uc_reg_read(uc, UC_X86_REG_R8, &temp_widechar); uc_reg_read(uc, UC_X86_REG_R9, &temp_cchwidechar); CodePage = static_cast(temp_codepage); dwFlags = static_cast(temp_flags); lpWideCharStr = temp_widechar; cchWideChar = static_cast(temp_cchwidechar); // 获取栈上的参数 uint64_t rsp = 0; uc_reg_read(uc, UC_X86_REG_RSP, &rsp); uint64_t shadow_space = 0x20; uc_mem_read(uc, rsp + shadow_space + 0x8, &lpMultiByteStr, sizeof(uint64_t)); uc_mem_read(uc, rsp + shadow_space + 0x10, &cbMultiByte, sizeof(int32_t)); uc_mem_read(uc, rsp + shadow_space + 0x18, &lpDefaultChar, sizeof(uint64_t)); uc_mem_read(uc, rsp + shadow_space + 0x20, &lpUsedDefaultChar, sizeof(uint64_t)); } 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, &CodePage, sizeof(uint32_t)); uc_mem_read(uc, esp_address + 0x4, &dwFlags, sizeof(uint32_t)); uc_mem_read(uc, esp_address + 0x8, &lpWideCharStr, sizeof(uint32_t)); uc_mem_read(uc, esp_address + 0xC, &cchWideChar, sizeof(int32_t)); uc_mem_read(uc, esp_address + 0x10, &lpMultiByteStr, sizeof(uint32_t)); uc_mem_read(uc, esp_address + 0x14, &cbMultiByte, sizeof(int32_t)); uc_mem_read(uc, esp_address + 0x18, &lpDefaultChar, sizeof(uint32_t)); uc_mem_read(uc, esp_address + 0x1C, &lpUsedDefaultChar, sizeof(uint32_t)); } // 基本参数验证 if (lpWideCharStr == 0 || cchWideChar == 0) { DWORD error = ERROR_INVALID_PARAMETER; if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = error; } else { context->GetTeb32()->LastErrorValue = error; } int result = 0; uc_reg_write( uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result); return; } // 读取源宽字符串 std::vector srcBuffer; size_t actualWideLength = 0; if (cchWideChar == -1) { // 如果长度为-1,则源字符串以null结尾 wchar_t ch = 0; do { if (uc_mem_read(uc, lpWideCharStr + (actualWideLength * 2), &ch, 2) != UC_ERR_OK) { break; } srcBuffer.push_back(ch); actualWideLength++; } while (ch != 0 && actualWideLength < MAX_PATH); if (actualWideLength >= MAX_PATH) { DWORD error = ERROR_INSUFFICIENT_BUFFER; if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = error; } else { context->GetTeb32()->LastErrorValue = error; } int result = 0; uc_reg_write( uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result); return; } } else { // 使用指定长度 if (cchWideChar > 0 && cchWideChar <= MAX_PATH) { srcBuffer.resize(cchWideChar); if (uc_mem_read(uc, lpWideCharStr, srcBuffer.data(), cchWideChar * 2) != UC_ERR_OK) { DWORD error = ERROR_INVALID_PARAMETER; if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = error; } else { context->GetTeb32()->LastErrorValue = error; } int result = 0; uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result); return; } actualWideLength = cchWideChar; } else { DWORD error = ERROR_INVALID_PARAMETER; if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = error; } else { context->GetTeb32()->LastErrorValue = error; } int result = 0; uc_reg_write( uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result); return; } } // 读取默认字符和使用默认字符标志 char defaultChar = '?'; BOOL usedDefaultChar = FALSE; if (lpDefaultChar != 0) { uc_mem_read(uc, lpDefaultChar, &defaultChar, 1); } // 计算所需的多字节缓冲区大小 int requiredSize = WideCharToMultiByte( CodePage, dwFlags, srcBuffer.data(), static_cast(actualWideLength), nullptr, 0, lpDefaultChar ? &defaultChar : nullptr, lpUsedDefaultChar ? &usedDefaultChar : nullptr); if (requiredSize == 0) { // 获取并设置错误码 DWORD error = GetLastError(); if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = error; } else { context->GetTeb32()->LastErrorValue = error; } int result = 0; uc_reg_write( uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result); return; } // 如果只是查询所需缓冲区大小 if (lpMultiByteStr == 0 || cbMultiByte == 0) { uc_reg_write( uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &requiredSize); return; } // 检查目标缓冲区大小是否足够 if (cbMultiByte < requiredSize) { DWORD error = ERROR_INSUFFICIENT_BUFFER; if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = error; } else { context->GetTeb32()->LastErrorValue = error; } int result = 0; uc_reg_write( uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result); return; } // 执行实际转换 std::vector multiByteBuffer(requiredSize); int result = WideCharToMultiByte( CodePage, dwFlags, srcBuffer.data(), static_cast(actualWideLength), multiByteBuffer.data(), requiredSize, lpDefaultChar ? &defaultChar : nullptr, lpUsedDefaultChar ? &usedDefaultChar : nullptr); if (result > 0) { // 写入转换后的字符串到目标内存 if (uc_mem_write(uc, lpMultiByteStr, multiByteBuffer.data(), result) != UC_ERR_OK) { DWORD error = ERROR_INVALID_PARAMETER; if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = error; } else { context->GetTeb32()->LastErrorValue = error; } result = 0; } // 如果需要,写回使用默认字符标志 if (lpUsedDefaultChar != 0) { uc_mem_write(uc, lpUsedDefaultChar, &usedDefaultChar, sizeof(BOOL)); } } else { // 获取并设置错误码 DWORD error = GetLastError(); if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = error; } else { context->GetTeb32()->LastErrorValue = error; } } printf( "[*] WideCharToMultiByte: CodePage=%u, Flags=0x%x, WideStr=%p, " "WideLen=%d, MultiStr=%p, MultiLen=%d, Result=%d\n", CodePage, dwFlags, (void*)lpWideCharStr, cchWideChar, (void*)lpMultiByteStr, cbMultiByte, result); uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result); } // 实现 InitializeSListHead API auto Api_InitializeSListHead(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); uint64_t ListHead = 0; // 获取参数 if (context->GetPeInfo()->isX64) { // x64: rcx = ListHead uc_reg_read(uc, UC_X86_REG_RCX, &ListHead); } else { // x86: 从栈上读取参数 uint32_t esp_address = 0; uint32_t temp_listhead = 0; uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); esp_address += 0x4; // 跳过返回地址 uc_mem_read(uc, esp_address, &temp_listhead, sizeof(uint32_t)); ListHead = temp_listhead; } if (ListHead != 0) { if (context->GetPeInfo()->isX64) { // 64位系统的SLIST_HEADER结构 (16字节对齐) struct SLIST_HEADER64 { union { struct { ULONGLONG Alignment; ULONGLONG Region; } DUMMYSTRUCTNAME; struct { ULONGLONG Depth : 16; ULONGLONG Sequence : 48; ULONGLONG Reserved : 4; ULONGLONG NextEntry : 60; } HeaderX64; }; } header = {0}; // 初始化Depth和Sequence为0 header.HeaderX64.Depth = 0; header.HeaderX64.Sequence = 0; header.HeaderX64.Reserved = 0; header.HeaderX64.NextEntry = 0; // 写入初始化的结构 uc_mem_write(uc, ListHead, &header, sizeof(SLIST_HEADER64)); } else { // 32位系统的SLIST_HEADER结构 (8字节) struct SLIST_HEADER32 { union { ULONGLONG Alignment; struct { SLIST_ENTRY* Next; WORD Depth; WORD Sequence; } Header32; }; } header = {0}; // 初始化Next、Depth和Sequence为0 header.Header32.Next = nullptr; header.Header32.Depth = 0; header.Header32.Sequence = 0; // 写入初始化的结构 uc_mem_write(uc, ListHead, &header, sizeof(SLIST_HEADER32)); } } printf("[*] InitializeSListHead: ListHead=0x%llx\n", ListHead); } // 实现 GetEnvironmentStringsW API auto Api_GetEnvironmentStringsW(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); uint64_t envBlock = context->GetEnvBlockBase(); uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &envBlock); } // 实现 FreeEnvironmentStringsW API auto Api_FreeEnvironmentStringsW(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); uint64_t lpszEnvironmentBlock = 0; // 获取参数 if (context->GetPeInfo()->isX64) { // x64: rcx = lpszEnvironmentBlock uc_reg_read(uc, UC_X86_REG_RCX, &lpszEnvironmentBlock); } else { // x86: 从栈上读取参数 uint32_t esp_address = 0; uint32_t temp_block = 0; uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); esp_address += 0x4; // 跳过返回地址 uc_mem_read(uc, esp_address, &temp_block, sizeof(uint32_t)); lpszEnvironmentBlock = temp_block; } // 检查传入的地址是否是我们之前分配的环境块地址 BOOL success = (lpszEnvironmentBlock == context->GetEnvBlockBase()); if (!success) { // 如果地址无效,设置错误码 DWORD error = ERROR_INVALID_PARAMETER; if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = error; } else { context->GetTeb32()->LastErrorValue = error; } } printf("[*] FreeEnvironmentStringsW: Block=0x%llx, Success=%d\n", lpszEnvironmentBlock, success); // 返回操作是否成功 uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &success); } // 实现HeapCreate API auto Api_HeapCreate(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); uint32_t flOptions = 0; uint64_t dwInitialSize = 0; uint64_t dwMaximumSize = 0; // 获取参数 if (context->GetPeInfo()->isX64) { // x64: rcx = flOptions, rdx = dwInitialSize, r8 = dwMaximumSize uint64_t temp_options; uc_reg_read(uc, UC_X86_REG_RCX, &temp_options); flOptions = static_cast(temp_options); uc_reg_read(uc, UC_X86_REG_RDX, &dwInitialSize); uc_reg_read(uc, UC_X86_REG_R8, &dwMaximumSize); } 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, &flOptions, sizeof(uint32_t)); esp_address += 0x4; uint32_t temp_initial; uc_mem_read(uc, esp_address, &temp_initial, sizeof(uint32_t)); dwInitialSize = temp_initial; esp_address += 0x4; uint32_t temp_maximum; uc_mem_read(uc, esp_address, &temp_maximum, sizeof(uint32_t)); dwMaximumSize = temp_maximum; } // 如果初始大小为0,使用默认大小 if (dwInitialSize == 0) { dwInitialSize = context->GetPeInfo()->isX64 ? HEAP_SIZE_64 : HEAP_SIZE_32; } // 如果最大大小小于初始大小,将其设置为初始大小 if (dwMaximumSize < dwInitialSize) { dwMaximumSize = dwInitialSize; } // 生成新的堆基址 uint64_t heapBase = context->GetPeInfo()->isX64 ? (HEAP_ADDRESS_64 + (context->GetHeapBlocks().size() * HEAP_SIZE_64)) : (HEAP_ADDRESS_32 + (context->GetHeapBlocks().size() * HEAP_SIZE_32)); // 创建新的堆段 HeapSegment* segment = context->CreateHeapSegment(heapBase, dwInitialSize); if (segment == nullptr) { uint64_t null_handle = 0; uc_reg_write( uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &null_handle); return; } // 将新堆段添加到堆映射表中 context->m_heapSegments[heapBase] = segment; // 映射堆内存 uc_err err = uc_mem_map(uc, heapBase, dwInitialSize, UC_PROT_READ | UC_PROT_WRITE); if (err != UC_ERR_OK) { uint64_t null_handle = 0; uc_reg_write( uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &null_handle); return; } printf( "[*] HeapCreate: Options=0x%x, InitialSize=0x%llx, MaximumSize=0x%llx, " "Handle=0x%llx\n", flOptions, dwInitialSize, dwMaximumSize, heapBase); // 返回堆句柄(使用堆基址作为句柄) uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &heapBase); } // 实现 SHGetKnownFolderPath API auto Api_SHGetKnownFolderPath(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); uint64_t rfid = 0; // REFKNOWNFOLDERID uint64_t dwFlags = 0; // DWORD uint64_t hToken = 0; // HANDLE uint64_t ppszPath = 0; // PWSTR* uint64_t result = 0; // 返回值 // 获取参数 if (context->GetPeInfo()->isX64) { // x64: rcx = rfid, rdx = dwFlags, r8 = hToken, r9 = ppszPath uc_reg_read(uc, UC_X86_REG_RCX, &rfid); uc_reg_read(uc, UC_X86_REG_RDX, &dwFlags); uc_reg_read(uc, UC_X86_REG_R8, &hToken); uc_reg_read(uc, UC_X86_REG_R9, &ppszPath); } else { // x86: 从栈上读取参数 uint32_t esp_address = 0; uint32_t temp_rfid = 0; uint32_t temp_flags = 0; uint32_t temp_token = 0; uint32_t temp_path = 0; uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); esp_address += 0x4; // 跳过返回地址 uc_mem_read(uc, esp_address, &temp_rfid, sizeof(uint32_t)); esp_address += 0x4; uc_mem_read(uc, esp_address, &temp_flags, sizeof(uint32_t)); esp_address += 0x4; uc_mem_read(uc, esp_address, &temp_token, sizeof(uint32_t)); esp_address += 0x4; uc_mem_read(uc, esp_address, &temp_path, sizeof(uint32_t)); rfid = temp_rfid; dwFlags = temp_flags; hToken = temp_token; ppszPath = temp_path; } // 根据已知文件夹ID分配不同的路径 std::wstring folderPath; // 常见已知文件夹GUID的16进制值映射表 std::map knownFolders = { // FOLDERID_Desktop = {B4BFCC3A-DB2C-424C-B029-7FE99A87C641} {0xB4BFCC3A, L"C:\\Users\\User\\Desktop"}, // FOLDERID_Documents = {FDD39AD0-238F-46AF-ADB4-6C85480369C7} {0xFDD39AD0, L"C:\\Users\\User\\Documents"}, // FOLDERID_Downloads = {374DE290-123F-4565-9164-39C4925E467B} {0x374DE290, L"C:\\Users\\User\\Downloads"}, // FOLDERID_ProgramFiles = {905e63b6-c1bf-494e-b29c-65b732d3d21a} {0x905e63b6, L"C:\\Program Files"}, // FOLDERID_ProgramFilesX86 = {7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E} {0x7C5A40EF, L"C:\\Program Files (x86)"}, // FOLDERID_Windows = {F38BF404-1D43-42F2-9305-67DE0B28FC23} {0xF38BF404, L"C:\\Windows"}, // FOLDERID_System = {1AC14E77-02E7-4E5D-B744-2EB1AE5198B7} {0x1AC14E77, L"C:\\Windows\\System32"}, // FOLDERID_SystemX86 = {D65231B0-B2F1-4857-A4CE-A8E7C6EA7D27} {0xD65231B0, L"C:\\Windows\\SysWOW64"}, // FOLDERID_ProgramData = {62AB5D82-FDC1-4DC3-A9DD-070D1D495D97} {0x62AB5D82, L"C:\\ProgramData"}, // FOLDERID_LocalAppData = {F1B32785-6FBA-4FCF-9D55-7B8E7F157091} {0xF1B32785, L"C:\\Users\\User\\AppData\\Local"}, // FOLDERID_RoamingAppData = {3EB685DB-65F9-4CF6-A03A-E3EF65729F3D} {0x3EB685DB, L"C:\\Users\\User\\AppData\\Roaming"}, // FOLDERID_Startup = {B97D20BB-F46A-4C97-BA10-5E3608430854} {0xB97D20BB, L"C:\\Users\\User\\AppData\\Roaming\\Microsoft\\Windows\\Start " L"Menu\\Programs\\Startup"}, // FOLDERID_StartMenu = {625B53C3-AB48-4EC1-BA1F-A1EF4146FC19} {0x625B53C3, L"C:\\Users\\User\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu"}, // FOLDERID_Fonts = {FD228CB7-AE11-4AE3-864C-16F3910AB8FE} {0xFD228CB7, L"C:\\Windows\\Fonts"}, // FOLDERID_Templates = {A63293E8-664E-48DB-A079-DF759E0509F7} {0xA63293E8, L"C:\\Users\\User\\AppData\\Roaming\\Microsoft\\Windows\\Templates"}, // FOLDERID_PublicDesktop = {C4AA340D-F20F-4863-AFEF-F87EF2E6BA25} {0xC4AA340D, L"C:\\Users\\Public\\Desktop"}, // FOLDERID_CommonDocuments = {ED4824AF-DCE4-45A8-81E2-FC7965083634} {0xED4824AF, L"C:\\Users\\Public\\Documents"}}; // 从传入的rfid获取第一个DWORD作为键 uint32_t guidFirstDword = 0; uc_mem_read(uc, rfid, &guidFirstDword, sizeof(uint32_t)); // 查找对应的文件夹路径 auto it = knownFolders.find(guidFirstDword); if (it != knownFolders.end()) { context->SetMalwareAnalysisType(MalwareAnalysisType::kSuspicious); folderPath = it->second; } else { // 如果找不到对应的GUID,返回默认文档文件夹 folderPath = L"C:\\Users\\User\\Documents"; } // 分配内存用于存储路径 uint64_t pathBuffer = 0; size_t bufferSize = (folderPath.length() + 1) * sizeof(wchar_t); // 从堆中分配内存 if (context->GetPeInfo()->isX64) { HeapSegment* segment = context->FindHeapSegment(HEAP_ADDRESS_64); if (segment) { pathBuffer = context->AllocateFromSegment(segment, bufferSize); } } else { HeapSegment* segment = context->FindHeapSegment(HEAP_ADDRESS_32); if (segment) { pathBuffer = context->AllocateFromSegment(segment, bufferSize); } } if (pathBuffer != 0) { // 写入路径 uc_mem_write(uc, pathBuffer, folderPath.c_str(), bufferSize); // 写入路径地址到ppszPath指向的位置 if (ppszPath != 0) { uc_mem_write(uc, ppszPath, &pathBuffer, context->GetPeInfo()->isX64 ? 8 : 4); result = 0; // S_OK } else { result = 0x80070057; // E_INVALIDARG } } else { result = 0x8007000E; // E_OUTOFMEMORY } printf( "[*] SHGetKnownFolderPath: rfid=0x%llx, flags=0x%x, token=0x%llx, " "path=0x%llx, result=0x%llx, folder=%ls\n", rfid, dwFlags, hToken, ppszPath, result, folderPath.c_str()); // 设置返回值 uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result); } auto Api_EncodePointer(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); uint64_t ptr = 0; // 获取参数 if (context->GetPeInfo()->isX64) { // x64: rcx = ptr uc_reg_read(uc, UC_X86_REG_RCX, &ptr); } else { // x86: 从栈上读取参数 uint32_t esp_address = 0; uint32_t temp_ptr = 0; uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); esp_address += 0x4; // 跳过返回地址 uc_mem_read(uc, esp_address, &temp_ptr, sizeof(uint32_t)); ptr = temp_ptr; } // 使用固定密钥进行简单的异或操作来"编码"指针 // 注意:这是一个简化的实现,实际的Windows实现更复杂 uint64_t cookie = 0x1234567890ABCDEF; uint64_t encoded_ptr = ptr ^ cookie; printf("[*] EncodePointer: Original=0x%llx, Encoded=0x%llx\n", ptr, encoded_ptr); // 返回编码后的指针 uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &encoded_ptr); } 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); } // 实现 GetACP API auto Api_GetACP(void* sandbox, uc_engine* uc, uint64_t address) -> void { // 返回默认的 ANSI 代码页 (936 - 简体中文) uint32_t codepage = 936; printf("[*] GetACP: CodePage=%u\n", codepage); // 返回代码页值 uc_reg_write(uc, static_cast(sandbox)->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &codepage); } // 实现 GetCPInfo API auto Api_GetCPInfo(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); uint32_t codePage = 0; uint64_t lpCPInfo = 0; BOOL success = FALSE; // 获取参数 if (context->GetPeInfo()->isX64) { // x64: rcx = CodePage, rdx = lpCPInfo uint64_t temp_codepage; uc_reg_read(uc, UC_X86_REG_RCX, &temp_codepage); codePage = static_cast(temp_codepage); uc_reg_read(uc, UC_X86_REG_RDX, &lpCPInfo); } 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, &codePage, sizeof(uint32_t)); esp_address += 0x4; uint32_t temp_cpinfo; uc_mem_read(uc, esp_address, &temp_cpinfo, sizeof(uint32_t)); lpCPInfo = temp_cpinfo; } if (lpCPInfo != 0) { // 创建 CPINFO 结构 CPINFO cpInfo = {0}; // 根据代码页设置相应的信息 switch (codePage) { case 936: // 简体中文 GBK cpInfo.MaxCharSize = 2; // 最大字符大小为2字节 cpInfo.DefaultChar[0] = '?'; // 默认替换字符 cpInfo.DefaultChar[1] = '\0'; cpInfo.LeadByte[0] = 0x81; // 前导字节范围 cpInfo.LeadByte[1] = 0xFE; cpInfo.LeadByte[2] = 0; // 结束标记 success = TRUE; break; case 437: // US ASCII case 1252: // Western European cpInfo.MaxCharSize = 1; // 单字节字符集 cpInfo.DefaultChar[0] = '?'; cpInfo.DefaultChar[1] = '\0'; cpInfo.LeadByte[0] = 0; // 无前导字节 success = TRUE; break; default: // 不支持的代码页 if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = ERROR_INVALID_PARAMETER; } else { context->GetTeb32()->LastErrorValue = ERROR_INVALID_PARAMETER; } success = FALSE; break; } if (success) { // 写入 CPINFO 结构到目标内存 uc_mem_write(uc, lpCPInfo, &cpInfo, sizeof(CPINFO)); } } else { // 无效的指针参数 if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = ERROR_INVALID_PARAMETER; } else { context->GetTeb32()->LastErrorValue = ERROR_INVALID_PARAMETER; } success = FALSE; } printf("[*] GetCPInfo: CodePage=%u, lpCPInfo=0x%llx, Success=%d\n", codePage, lpCPInfo, success); // 返回操作是否成功 uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &success); } auto Api_MultiByteToWideChar(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); uint32_t CodePage = 0; uint32_t dwFlags = 0; uint64_t lpMultiByteStr = 0; int32_t cbMultiByte = 0; uint64_t lpWideCharStr = 0; int32_t cchWideChar = 0; // 获取参数 if (context->GetPeInfo()->isX64) { uint64_t temp_codepage = 0; uint64_t temp_flags = 0; uint64_t temp_multibyte = 0; uint64_t temp_cbmultibyte = 0; // x64: rcx, rdx, r8, r9, [rsp+0x28], [rsp+0x30] uc_reg_read(uc, UC_X86_REG_RCX, &temp_codepage); uc_reg_read(uc, UC_X86_REG_RDX, &temp_flags); uc_reg_read(uc, UC_X86_REG_R8, &temp_multibyte); uc_reg_read(uc, UC_X86_REG_R9, &temp_cbmultibyte); CodePage = static_cast(temp_codepage); dwFlags = static_cast(temp_flags); lpMultiByteStr = temp_multibyte; cbMultiByte = static_cast(temp_cbmultibyte); // 获取栈上的参数 uint64_t rsp = 0; uc_reg_read(uc, UC_X86_REG_RSP, &rsp); // 为了确保安全访问,先验证栈地址的有效性 if (rsp < 0x8000000000000000 || rsp + 0x40 > 0x8000000000010000) { // 无效的栈地址 DWORD error = ERROR_INVALID_PARAMETER; context->GetTeb64()->LastErrorValue = error; int result = 0; uc_reg_write(uc, UC_X86_REG_RAX, &result); return; } // 读取栈上的参数 uint64_t shadow_space = 0x20; // x64调用约定中的shadow space uc_mem_read(uc, rsp + shadow_space + 0x8, &lpWideCharStr, sizeof(uint64_t)); uc_mem_read(uc, rsp + shadow_space + 0x10, &cchWideChar, sizeof(int32_t)); } 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, &CodePage, sizeof(uint32_t)); uc_mem_read(uc, esp_address + 0x4, &dwFlags, sizeof(uint32_t)); uc_mem_read(uc, esp_address + 0x8, &lpMultiByteStr, sizeof(uint32_t)); uc_mem_read(uc, esp_address + 0xC, &cbMultiByte, sizeof(int32_t)); uc_mem_read(uc, esp_address + 0x10, &lpWideCharStr, sizeof(uint32_t)); uc_mem_read(uc, esp_address + 0x14, &cchWideChar, sizeof(int32_t)); } // 验证参数 if (lpMultiByteStr == 0 || (lpWideCharStr == 0 && cchWideChar != 0)) { DWORD error = ERROR_INVALID_PARAMETER; if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = error; } else { context->GetTeb32()->LastErrorValue = error; } int result = 0; uc_reg_write( uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result); return; } // 读取源字符串 std::vector srcBuffer; if (cbMultiByte == -1) { // 如果长度为-1,则源字符串以null结尾 char ch = 0; size_t len = 0; do { if (uc_mem_read(uc, lpMultiByteStr + len, &ch, 1) != UC_ERR_OK) { break; } srcBuffer.push_back(ch); len++; } while (ch != 0 && len < MAX_PATH); // 添加长度限制防止无限循环 if (len >= MAX_PATH) { // 设置错误码 DWORD error = ERROR_INSUFFICIENT_BUFFER; if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = error; } else { context->GetTeb32()->LastErrorValue = error; } int result = 0; uc_reg_write( uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result); return; } cbMultiByte = static_cast(len); } else if (cbMultiByte > 0) { // 使用指定长度,但添加安全检查 if (cbMultiByte > MAX_PATH) { DWORD error = ERROR_INSUFFICIENT_BUFFER; if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = error; } else { context->GetTeb32()->LastErrorValue = error; } int result = 0; uc_reg_write( uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result); return; } srcBuffer.resize(cbMultiByte); if (uc_mem_read(uc, lpMultiByteStr, srcBuffer.data(), cbMultiByte) != UC_ERR_OK) { DWORD error = ERROR_INVALID_PARAMETER; if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = error; } else { context->GetTeb32()->LastErrorValue = error; } int result = 0; uc_reg_write( uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result); return; } } else { // 无效的输入长度 DWORD error = ERROR_INVALID_PARAMETER; if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = error; } else { context->GetTeb32()->LastErrorValue = error; } int result = 0; uc_reg_write( uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result); return; } // 计算所需的宽字符缓冲区大小 int result = MultiByteToWideChar(CodePage, dwFlags, srcBuffer.data(), cbMultiByte, nullptr, 0); if (result == 0) { // 转换失败,获取错误码 DWORD error = GetLastError(); 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 (lpWideCharStr == 0 || cchWideChar == 0) { uc_reg_write( uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result); return; } // 检查目标缓冲区大小是否足够 if (cchWideChar < result) { DWORD error = ERROR_INSUFFICIENT_BUFFER; if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = error; } else { context->GetTeb32()->LastErrorValue = error; } result = 0; uc_reg_write( uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result); return; } // 执行实际转换 std::vector wideBuffer(result); if (MultiByteToWideChar(CodePage, dwFlags, srcBuffer.data(), cbMultiByte, wideBuffer.data(), result) > 0) { // 写入转换后的字符串到目标内存 if (uc_mem_write(uc, lpWideCharStr, wideBuffer.data(), result * sizeof(wchar_t)) != UC_ERR_OK) { DWORD error = ERROR_INVALID_PARAMETER; if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = error; } else { context->GetTeb32()->LastErrorValue = error; } result = 0; } } else { // 转换失败 DWORD error = GetLastError(); if (context->GetPeInfo()->isX64) { context->GetTeb64()->LastErrorValue = error; } else { context->GetTeb32()->LastErrorValue = error; } result = 0; } printf( "[*] MultiByteToWideChar: CodePage=%u, Flags=0x%x, Input=%p, " "InputLen=%d, Output=%p, OutputLen=%d, Result=%d\n", CodePage, dwFlags, (void*)lpMultiByteStr, cbMultiByte, (void*)lpWideCharStr, cchWideChar, result); uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result); } 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; // 分配失败 }