Files
awesome_anti_virus_engine/ai_anti_malware/sandbox_api_stl.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

1515 lines
53 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"
// 实现 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*>(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*>(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<uint32_t>(temp_codepage);
dwFlags = static_cast<uint32_t>(temp_flags);
lpWideCharStr = temp_widechar;
cchWideChar = static_cast<int32_t>(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<wchar_t> 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<int>(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<char> multiByteBuffer(requiredSize);
int result = WideCharToMultiByte(
CodePage, dwFlags, srcBuffer.data(), static_cast<int>(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*>(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*>(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*>(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*>(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<uint32_t>(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*>(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<uint64_t, std::wstring> 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*>(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*>(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*>(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<uint32_t>(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*>(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<uint32_t>(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*>(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<uint32_t>(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<uint64_t>(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*>(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<uint32_t>(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*>(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*>(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*>(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*>(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<int32_t>(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<HANDLE>(0x1000); // 模拟标准输入句柄
break;
case STD_OUTPUT_HANDLE: // -11
handle = reinterpret_cast<HANDLE>(0x2000); // 模拟标准输出句柄
break; // End of Selection
break;
case STD_ERROR_HANDLE: // -12
handle = reinterpret_cast<HANDLE>(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<uint64_t>(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*>(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<HANDLE>(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<HANDLE>(static_cast<uint64_t>(temp_handle));
}
DWORD file_type = FILE_TYPE_UNKNOWN;
// 根据标准句柄类型返回相应的文件类型
if (hFile == reinterpret_cast<HANDLE>(0x1000) || // STD_INPUT_HANDLE
hFile == reinterpret_cast<HANDLE>(0x2000) || // STD_OUTPUT_HANDLE
hFile == reinterpret_cast<HANDLE>(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*>(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*>(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*>(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*>(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<uint32_t>(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*>(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<uint32_t>(temp_codepage);
dwFlags = static_cast<uint32_t>(temp_flags);
lpMultiByteStr = temp_multibyte;
cbMultiByte = static_cast<int32_t>(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<char> 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<int32_t>(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<wchar_t> 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; // 分配失败
}