diff --git a/ai_anti_malware/ai_anti_malware.cpp b/ai_anti_malware/ai_anti_malware.cpp
index 855728f..1f7e897 100644
--- a/ai_anti_malware/ai_anti_malware.cpp
+++ b/ai_anti_malware/ai_anti_malware.cpp
@@ -375,8 +375,13 @@ int main(int argc, char* argv[]) {
}
std::string filePath = argv[1];
+
+ std::string filePath = "";
+ DetectEngine scanner;
+
+ DetectEngineType result = scanner.DetectMalware(filePath);
+ printf("result: %d \n", result);
+ //DetectMalwareInDirectory(filePath);
*/
- std::string filePath = "Z:\\123";
- DetectMalwareInDirectory(filePath);
return 0;
}
diff --git a/ai_anti_malware/ai_anti_malware.vcxproj b/ai_anti_malware/ai_anti_malware.vcxproj
index 68b9668..28b8c00 100644
--- a/ai_anti_malware/ai_anti_malware.vcxproj
+++ b/ai_anti_malware/ai_anti_malware.vcxproj
@@ -180,6 +180,7 @@
+
diff --git a/ai_anti_malware/ai_anti_malware.vcxproj.filters b/ai_anti_malware/ai_anti_malware.vcxproj.filters
index 3d838d4..11162a8 100644
--- a/ai_anti_malware/ai_anti_malware.vcxproj.filters
+++ b/ai_anti_malware/ai_anti_malware.vcxproj.filters
@@ -171,6 +171,9 @@
源文件\sandbox
+
+ 源文件\sandbox\apis
+
diff --git a/ai_anti_malware/sandbox.cpp b/ai_anti_malware/sandbox.cpp
index ff05030..49968e9 100644
--- a/ai_anti_malware/sandbox.cpp
+++ b/ai_anti_malware/sandbox.cpp
@@ -185,6 +185,12 @@ Sandbox::~Sandbox() {
}
m_wfpEngines.clear();
+ // 清理文件句柄资源
+ for (auto& pair : m_fileHandles) {
+ delete pair.second;
+ }
+ m_fileHandles.clear();
+
// 1. 先清理高层资源
m_crossSectionExecution.clear();
envStrings.clear();
diff --git a/ai_anti_malware/sandbox.h b/ai_anti_malware/sandbox.h
index 9f82c90..76c5494 100644
--- a/ai_anti_malware/sandbox.h
+++ b/ai_anti_malware/sandbox.h
@@ -85,6 +85,9 @@ struct InternetHandleInfo {
size_t currentPosition;
};
+// 添加文件句柄信息前向声明
+struct FileHandleInfo;
+
class Sandbox {
friend class cFixImprot; // 声明cFixImprot为友元类
public:
@@ -252,6 +255,13 @@ class Sandbox {
// 注册COM相关API
void RegisterComApis();
+ // 文件句柄管理相关方法
+ auto GenerateFileHandle() -> uint64_t;
+ auto GetFileHandleInfo(uint64_t handle) -> FileHandleInfo*;
+
+ // 文件句柄表
+ static std::map m_fileHandles;
+
private:
std::shared_ptr m_peInfo;
std::pair> m_lastImpRead;
@@ -461,4 +471,14 @@ auto Api_TlsFree(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_FlsAlloc(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_FlsGetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api__initterm_e(void* sandbox, uc_engine* uc, uint64_t address) -> void;
-auto Api_getenv(void* sandbox, uc_engine* uc, uint64_t address) -> void;
\ No newline at end of file
+auto Api_getenv(void* sandbox, uc_engine* uc, uint64_t address) -> void;
+auto Api_GetStringTypeW(void* sandbox, uc_engine* uc, uint64_t address) -> void;
+auto Api_CreateDirectoryW(void* sandbox, uc_engine* uc, uint64_t address) -> void;
+auto Api_LCMapStringW(void* sandbox, uc_engine* uc, uint64_t address) -> void;
+auto Api_LCMapStringEx(void* sandbox, uc_engine* uc, uint64_t address) -> void;
+
+// 文件API函数声明
+auto Api_ReadFileA(void* sandbox, uc_engine* uc, uint64_t address) -> void;
+auto Api_ReadFileW(void* sandbox, uc_engine* uc, uint64_t address) -> void;
+auto Api_ReadFile(void* sandbox, uc_engine* uc, uint64_t address, bool isWideChar) -> void;
+auto Api_CloseFile(void* sandbox, uc_engine* uc, uint64_t address) -> void;
\ No newline at end of file
diff --git a/ai_anti_malware/sandbox_api_emu.cpp b/ai_anti_malware/sandbox_api_emu.cpp
index eb36323..28c6c9e 100644
--- a/ai_anti_malware/sandbox_api_emu.cpp
+++ b/ai_anti_malware/sandbox_api_emu.cpp
@@ -858,350 +858,6 @@ auto Api_AdjustTokenPrivileges(void* sandbox, uc_engine* uc, uint64_t address)
context->GetTeb32()->LastErrorValue = error;
}
}
-auto Api_CreateDirectoryW(void* sandbox, uc_engine* uc, uint64_t address)
- -> void {
- auto context = static_cast(sandbox);
- uint64_t lpPathName = 0;
- uint64_t lpSecurityAttributes = 0;
-
- // 获取参数
- if (context->GetPeInfo()->isX64) {
- // x64: rcx = lpPathName, rdx = lpSecurityAttributes
- uc_reg_read(uc, UC_X86_REG_RCX, &lpPathName);
- uc_reg_read(uc, UC_X86_REG_RDX, &lpSecurityAttributes);
- } else {
- // x86: 从栈上读取参数
- uint32_t esp_address = 0;
- uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
- esp_address += 0x4; // 跳过返回地址
-
- uint32_t temp_path_name, temp_security_attr;
- uc_mem_read(uc, esp_address, &temp_path_name, sizeof(uint32_t));
- uc_mem_read(uc, esp_address + 0x4, &temp_security_attr,
- sizeof(uint32_t));
-
- lpPathName = temp_path_name;
- lpSecurityAttributes = temp_security_attr;
- }
-
- // 读取目录路径
- wchar_t pathBuffer[MAX_PATH] = {0};
- if (lpPathName != 0) {
- size_t i = 0;
- do {
- uint16_t wchar;
- uc_mem_read(uc, lpPathName + (i * 2), &wchar, 2);
- pathBuffer[i] = wchar;
- i++;
- } while (pathBuffer[i - 1] != 0 && i < MAX_PATH);
- }
-
- // 将宽字符转换为常规字符串用于日志输出
- std::wstring widePath(pathBuffer);
- std::string path(widePath.begin(), widePath.end());
-
- // 在实际的实现中,可能需要检查目录是否已存在
- // 这里简单地返回成功,不实际创建目录
- bool success = true;
-
- // 输出日志
- printf("[*] CreateDirectoryW: Path=%s, Result=%s\n", path.c_str(),
- success ? "TRUE" : "FALSE");
-
- // 设置返回值
- uint64_t result = success ? 1 : 0;
- uc_reg_write(uc,
- context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
- &result);
-
- // 如果失败,可以设置LastError
- if (!success) {
- DWORD error = ERROR_PATH_NOT_FOUND; // 或其他适当的错误代码
- if (context->GetPeInfo()->isX64) {
- context->GetTeb64()->LastErrorValue = error;
- } else {
- context->GetTeb32()->LastErrorValue = error;
- }
- }
-}
-auto Api_GetStringTypeW(void* sandbox, uc_engine* uc, uint64_t address)
- -> void {
- auto context = static_cast(sandbox);
- uint64_t dwInfoType = 0;
- uint64_t lpSrcStr = 0;
- int32_t cchSrc = 0;
- uint64_t lpCharType = 0;
-
- // 获取参数
- if (context->GetPeInfo()->isX64) {
- // x64: rcx = dwInfoType, rdx = lpSrcStr, r8 = cchSrc, r9 = lpCharType
- uc_reg_read(uc, UC_X86_REG_RCX, &dwInfoType);
- uc_reg_read(uc, UC_X86_REG_RDX, &lpSrcStr);
- uint64_t temp_size;
- uc_reg_read(uc, UC_X86_REG_R8, &temp_size);
- cchSrc = static_cast(temp_size);
- uc_reg_read(uc, UC_X86_REG_R9, &lpCharType);
- } 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, &dwInfoType, sizeof(uint32_t));
- esp_address += 0x4;
-
- uint32_t temp_src_str;
- uc_mem_read(uc, esp_address, &temp_src_str, sizeof(uint32_t));
- lpSrcStr = temp_src_str;
- esp_address += 0x4;
-
- uc_mem_read(uc, esp_address, &cchSrc, sizeof(int32_t));
- esp_address += 0x4;
-
- uint32_t temp_char_type;
- uc_mem_read(uc, esp_address, &temp_char_type, sizeof(uint32_t));
- lpCharType = temp_char_type;
- }
-
- // 验证参数
- if (lpSrcStr == 0 || lpCharType == 0) {
- uint64_t result = 0; // FALSE
- uc_reg_write(
- uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
- &result);
- DWORD error = ERROR_INVALID_PARAMETER;
- if (context->GetPeInfo()->isX64) {
- context->GetTeb64()->LastErrorValue = error;
- } else {
- context->GetTeb32()->LastErrorValue = error;
- }
- return;
- }
-
- // 如果cchSrc为负数,计算字符串长度
- if (cchSrc < 0) {
- cchSrc = 0;
- wchar_t temp_char;
- do {
- uc_mem_read(uc, lpSrcStr + (cchSrc * 2), &temp_char,
- sizeof(wchar_t));
- cchSrc++;
- } while (temp_char != 0 && cchSrc < 1024); // 设置一个合理的上限
- cchSrc--; // 不包括null终止符
- }
-
- // 读取源字符串
- std::vector srcStr(cchSrc);
- uc_mem_read(uc, lpSrcStr, srcStr.data(), cchSrc * sizeof(wchar_t));
-
- // 处理每个字符
- std::vector charTypes(cchSrc);
- for (int i = 0; i < cchSrc; i++) {
- WORD type = 0;
- wchar_t ch = srcStr[i];
-
- switch (dwInfoType) {
- case CT_CTYPE1: {
- // 基本字符类型检查
- if (iswupper(ch)) type |= C1_UPPER;
- if (iswlower(ch)) type |= C1_LOWER;
- if (iswdigit(ch)) type |= C1_DIGIT;
- if (iswspace(ch)) type |= C1_SPACE;
- if (iswpunct(ch)) type |= C1_PUNCT;
- if (iswcntrl(ch)) type |= C1_CNTRL;
- if (ch == L' ' || ch == L'\t') type |= C1_BLANK;
- if ((ch >= L'0' && ch <= L'9') || (ch >= L'A' && ch <= L'F') ||
- (ch >= L'a' && ch <= L'f'))
- type |= C1_XDIGIT;
- if (iswalpha(ch)) type |= C1_ALPHA;
- if (type == 0) type |= C1_DEFINED;
- break;
- }
- case CT_CTYPE2: {
- // 简单的双向文本支持
- if ((ch >= L'A' && ch <= L'Z') || (ch >= L'a' && ch <= L'z') ||
- (ch >= L'0' && ch <= L'9')) {
- type = C2_LEFTTORIGHT;
- } else if (iswspace(ch)) {
- type = C2_WHITESPACE;
- } else {
- type = C2_NOTAPPLICABLE;
- }
- break;
- }
- case CT_CTYPE3: {
- // 基本文本处理信息
- if (iswalpha(ch)) type |= C3_ALPHA;
- // 这里可以添加更多的C3类型检查
- break;
- }
- }
- charTypes[i] = type;
- }
-
- // 写入结果
- uc_mem_write(uc, lpCharType, charTypes.data(), cchSrc * sizeof(WORD));
-
- printf("[*] GetStringTypeW: InfoType=0x%x, StrLen=%d\n", dwInfoType,
- cchSrc);
-
- // 返回成功
- uint64_t result = 1; // TRUE
- uc_reg_write(uc,
- context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
- &result);
-}
-
-auto Api_LCMapStringW(void* sandbox, uc_engine* uc, uint64_t address) -> void {
- auto context = static_cast(sandbox);
- uint32_t Locale = 0;
- uint32_t dwMapFlags = 0;
- uint64_t lpSrcStr = 0;
- int32_t cchSrc = 0;
- uint64_t lpDestStr = 0;
- int32_t cchDest = 0;
-
- // 获取参数
- if (context->GetPeInfo()->isX64) {
- // x64: rcx = Locale, rdx = dwMapFlags, r8 = lpSrcStr, r9 = cchSrc
- uc_reg_read(uc, UC_X86_REG_RCX, &Locale);
- uc_reg_read(uc, UC_X86_REG_RDX, &dwMapFlags);
- uc_reg_read(uc, UC_X86_REG_R8, &lpSrcStr);
- uint64_t temp_src_size;
- uc_reg_read(uc, UC_X86_REG_R9, &temp_src_size);
- cchSrc = static_cast(temp_src_size);
-
- // 从栈上读取剩余参数
- uint64_t rsp;
- uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
- uc_mem_read(uc, rsp + 0x28, &lpDestStr, sizeof(uint64_t));
- uc_mem_read(uc, rsp + 0x30, &cchDest, 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, &Locale, sizeof(uint32_t));
- esp_address += 0x4;
-
- uc_mem_read(uc, esp_address, &dwMapFlags, sizeof(uint32_t));
- esp_address += 0x4;
-
- uint32_t temp_src_str;
- uc_mem_read(uc, esp_address, &temp_src_str, sizeof(uint32_t));
- lpSrcStr = temp_src_str;
- esp_address += 0x4;
-
- uc_mem_read(uc, esp_address, &cchSrc, sizeof(int32_t));
- esp_address += 0x4;
-
- uint32_t temp_dest_str;
- uc_mem_read(uc, esp_address, &temp_dest_str, sizeof(uint32_t));
- lpDestStr = temp_dest_str;
- esp_address += 0x4;
-
- uc_mem_read(uc, esp_address, &cchDest, sizeof(int32_t));
- }
-
- // 验证参数
- if (lpSrcStr == 0) {
- uint32_t result = 0;
- uc_reg_write(
- uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
- &result);
- DWORD error = ERROR_INVALID_PARAMETER;
- if (context->GetPeInfo()->isX64) {
- context->GetTeb64()->LastErrorValue = error;
- } else {
- context->GetTeb32()->LastErrorValue = error;
- }
- return;
- }
-
- // 如果cchSrc为负数,计算源字符串长度
- if (cchSrc < 0) {
- cchSrc = 0;
- wchar_t temp_char;
- do {
- uc_mem_read(uc, lpSrcStr + (cchSrc * 2), &temp_char,
- sizeof(wchar_t));
- cchSrc++;
- } while (temp_char != 0 && cchSrc < 1024); // 设置一个合理的上限
- cchSrc--; // 不包括null终止符
- }
-
- // 读取源字符串
- std::vector srcStr(cchSrc);
- uc_mem_read(uc, lpSrcStr, srcStr.data(), cchSrc * sizeof(wchar_t));
-
- // 如果cchDest为0,返回所需缓冲区大小
- if (cchDest == 0) {
- uint32_t required_size = cchSrc;
- if (dwMapFlags & LCMAP_SORTKEY) {
- required_size = cchSrc * 2 + 1; // 排序键通常需要更多空间
- }
- uc_reg_write(
- uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
- &required_size);
- return;
- }
-
- // 检查目标缓冲区大小是否足够
- if (cchDest < cchSrc) {
- uint32_t result = 0;
- uc_reg_write(
- uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
- &result);
- DWORD error = ERROR_INSUFFICIENT_BUFFER;
- if (context->GetPeInfo()->isX64) {
- context->GetTeb64()->LastErrorValue = error;
- } else {
- context->GetTeb32()->LastErrorValue = error;
- }
- return;
- }
-
- // 处理字符串映射
- std::vector destStr(cchSrc);
- for (int i = 0; i < cchSrc; i++) {
- wchar_t ch = srcStr[i];
- if (dwMapFlags & LCMAP_UPPERCASE) {
- destStr[i] = towupper(ch);
- } else if (dwMapFlags & LCMAP_LOWERCASE) {
- destStr[i] = towlower(ch);
- } else {
- destStr[i] = ch; // 默认保持不变
- }
- }
-
- // 写入结果
- if (dwMapFlags & LCMAP_SORTKEY) {
- // 生成简单的排序键(这里只是一个基本实现)
- std::vector sortKey(cchSrc * 2 + 1);
- for (int i = 0; i < cchSrc; i++) {
- sortKey[i * 2] = static_cast(destStr[i] & 0xFF);
- sortKey[i * 2 + 1] = static_cast((destStr[i] >> 8) & 0xFF);
- }
- sortKey[cchSrc * 2] = 0; // 终止符
- uc_mem_write(uc, lpDestStr, sortKey.data(), sortKey.size());
- uint32_t result = static_cast(sortKey.size());
- uc_reg_write(
- uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
- &result);
- } else {
- // 写入映射后的字符串
- uc_mem_write(uc, lpDestStr, destStr.data(), cchSrc * sizeof(wchar_t));
- uint32_t result = cchSrc;
- uc_reg_write(
- uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
- &result);
- }
-
- printf(
- "[*] LCMapStringW: Locale=0x%x, MapFlags=0x%x, SrcLen=%d, DestLen=%d\n",
- Locale, dwMapFlags, cchSrc, cchDest);
-}
auto Sandbox::InitApiHooks() -> void {
auto FakeApi_GetSystemTimeAsFileTime =
@@ -1320,7 +976,6 @@ auto Sandbox::InitApiHooks() -> void {
_fakeApi{.func = Api_CreateProcessA, .paramCount = 10};
auto FakeApi_CreateProcessW =
_fakeApi{.func = Api_CreateProcessW, .paramCount = 10};
- auto FakeApi_ReadFile = _fakeApi{.func = Api_ReadFile, .paramCount = 5};
auto FakeApi_WlanOpenHandle =
_fakeApi{.func = Api_WlanOpenHandle, .paramCount = 4};
auto FakeApi_WlanEnumInterfaces =
@@ -1380,6 +1035,15 @@ auto Sandbox::InitApiHooks() -> void {
_fakeApi{.func = Api_SysAllocString, .paramCount = 1};
auto FakeApi_LoadLibraryW =
_fakeApi{ .func = Api_LoadLibraryW, .paramCount = 1 };
+ // *** 新增 LCMapStringEx ***
+ auto FakeApi_LCMapStringEx =
+ _fakeApi{.func = Api_LCMapStringEx, .paramCount = 9}; // LCMapStringEx 有 9 个参数
+
+ // 添加文件操作相关API
+ auto FakeApi_CreateFileW = _fakeApi{.func = Api_CreateFileW, .paramCount = 7};
+ auto FakeApi_ReadFileA = _fakeApi{.func = Api_ReadFileA, .paramCount = 5};
+ auto FakeApi_ReadFileW = _fakeApi{.func = Api_ReadFileW, .paramCount = 5};
+ auto FakeApi_CloseFile = _fakeApi{.func = Api_CloseFile, .paramCount = 1};
api_map = {
{"GetSystemTimeAsFileTime",
@@ -1477,7 +1141,6 @@ auto Sandbox::InitApiHooks() -> void {
{"CreatePipe", std::make_shared<_fakeApi>(FakeApi_CreatePipe)},
{"CreateProcessA", std::make_shared<_fakeApi>(FakeApi_CreateProcessA)},
{"CreateProcessW", std::make_shared<_fakeApi>(FakeApi_CreateProcessW)},
- {"ReadFile", std::make_shared<_fakeApi>(FakeApi_ReadFile)},
{"WlanOpenHandle", std::make_shared<_fakeApi>(FakeApi_WlanOpenHandle)},
{"WlanEnumInterfaces",
std::make_shared<_fakeApi>(FakeApi_WlanEnumInterfaces)},
@@ -1524,6 +1187,13 @@ auto Sandbox::InitApiHooks() -> void {
{"VariantClear", std::make_shared<_fakeApi>(FakeApi_VariantClear)},
{"SysAllocString", std::make_shared<_fakeApi>(FakeApi_SysAllocString)},
{"LoadLibraryW", std::make_shared<_fakeApi>(FakeApi_LoadLibraryW)},
+ // *** 新增 LCMapStringEx 映射 ***
+ {"LCMapStringEx", std::make_shared<_fakeApi>(FakeApi_LCMapStringEx)},
+ // 添加文件操作相关API映射
+ {"CreateFileW", std::make_shared<_fakeApi>(FakeApi_CreateFileW)},
+ {"ReadFileA", std::make_shared<_fakeApi>(FakeApi_ReadFileA)},
+ {"ReadFileW", std::make_shared<_fakeApi>(FakeApi_ReadFileW)},
+ {"CloseFile", std::make_shared<_fakeApi>(FakeApi_CloseFile)},
};
}
auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip,
diff --git a/ai_anti_malware/sandbox_api_files.cpp b/ai_anti_malware/sandbox_api_files.cpp
new file mode 100644
index 0000000..2941954
--- /dev/null
+++ b/ai_anti_malware/sandbox_api_files.cpp
@@ -0,0 +1,295 @@
+#include "sandbox.h"
+#include "sandbox_callbacks.h"
+#include
+
+// 文件句柄信息结构体
+struct FileHandleInfo {
+ uint64_t handle; // 文件句柄
+ std::string path; // 文件路径
+ std::vector content; // 文件内容
+ size_t currentPosition; // 当前读取位置
+ bool isValid; // 是否有效
+};
+
+// 在Sandbox类中添加文件句柄表
+std::map Sandbox::m_fileHandles;
+
+// 生成唯一的文件句柄
+uint64_t Sandbox::GenerateFileHandle() {
+ static uint64_t nextHandle = 0x2000; // 起始值,避免与特殊句柄冲突
+ return nextHandle++;
+}
+
+// 获取文件句柄信息
+FileHandleInfo* Sandbox::GetFileHandleInfo(uint64_t handle) {
+ auto it = m_fileHandles.find(handle);
+ if (it != m_fileHandles.end()) {
+ return it->second;
+ }
+ return nullptr;
+}
+
+// CreateFileW API实现
+auto Api_CreateFileW(void* sandbox, uc_engine* uc, uint64_t address) -> void {
+ auto context = static_cast(sandbox);
+ uint64_t lpFileName = 0;
+ uint64_t dwDesiredAccess = 0;
+ uint64_t dwShareMode = 0;
+ uint64_t lpSecurityAttributes = 0;
+ uint64_t dwCreationDisposition = 0;
+ uint64_t dwFlagsAndAttributes = 0;
+ uint64_t hTemplateFile = 0;
+
+ // 获取参数
+ if (context->GetPeInfo()->isX64) {
+ // x64: rcx = lpFileName, rdx = dwDesiredAccess, r8 = dwShareMode, r9 = lpSecurityAttributes
+ uc_reg_read(uc, UC_X86_REG_RCX, &lpFileName);
+ uc_reg_read(uc, UC_X86_REG_RDX, &dwDesiredAccess);
+ uint64_t temp_share_mode;
+ uc_reg_read(uc, UC_X86_REG_R8, &temp_share_mode);
+ dwShareMode = static_cast(temp_share_mode);
+ uc_reg_read(uc, UC_X86_REG_R9, &lpSecurityAttributes);
+
+ // 从栈上读取其他参数
+ uint64_t rsp;
+ uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
+ uc_mem_read(uc, rsp + 0x28, &dwCreationDisposition, sizeof(uint32_t));
+ uc_mem_read(uc, rsp + 0x30, &dwFlagsAndAttributes, sizeof(uint32_t));
+ uc_mem_read(uc, rsp + 0x38, &hTemplateFile, sizeof(uint64_t));
+ } else {
+ // x86: 从栈上读取参数
+ uint32_t esp;
+ uc_reg_read(uc, UC_X86_REG_ESP, &esp);
+ esp += 0x4; // 跳过返回地址
+
+ uint32_t temp_values[7];
+ for (int i = 0; i < 7; i++) {
+ uc_mem_read(uc, esp + (i * 4), &temp_values[i], sizeof(uint32_t));
+ }
+
+ lpFileName = temp_values[0];
+ dwDesiredAccess = temp_values[1];
+ dwShareMode = temp_values[2];
+ lpSecurityAttributes = temp_values[3];
+ dwCreationDisposition = temp_values[4];
+ dwFlagsAndAttributes = temp_values[5];
+ hTemplateFile = temp_values[6];
+ }
+
+ // 读取文件名
+ std::wstring filename;
+ if (lpFileName != 0) {
+ wchar_t buffer[MAX_PATH] = {0};
+ size_t i = 0;
+ do {
+ wchar_t wch;
+ uc_mem_read(uc, lpFileName + (i * 2), &wch, sizeof(wchar_t));
+ buffer[i] = wch;
+ i++;
+ } while (buffer[i - 1] != 0 && i < MAX_PATH);
+
+ if (i > 0 && i < MAX_PATH) {
+ filename = buffer;
+ }
+ }
+
+ // 将宽字符串转换为窄字符串,用于日志和内部存储
+ std::string ansiFilename(filename.begin(), filename.end());
+
+ // 创建文件句柄信息
+ auto fileHandleInfo = new FileHandleInfo();
+ fileHandleInfo->path = ansiFilename;
+ fileHandleInfo->currentPosition = 0;
+ fileHandleInfo->isValid = true;
+
+ // 读取实际文件内容(如果存在)
+ std::ifstream file(ansiFilename, std::ios::binary | std::ios::ate);
+ if (file.is_open()) {
+ std::streamsize size = file.tellg();
+ file.seekg(0, std::ios::beg);
+
+ fileHandleInfo->content.resize(size);
+ if (size > 0) {
+ file.read(fileHandleInfo->content.data(), size);
+ }
+ file.close();
+ } else {
+ // 文件不存在或无法打开
+ if (dwCreationDisposition == CREATE_NEW ||
+ dwCreationDisposition == CREATE_ALWAYS ||
+ dwCreationDisposition == OPEN_ALWAYS) {
+ // 创建空文件
+ fileHandleInfo->content.clear();
+ } else {
+ // 返回无效句柄
+ delete fileHandleInfo;
+ uint64_t invalidHandle = (uint64_t)INVALID_HANDLE_VALUE;
+ uc_reg_write(uc,
+ context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
+ &invalidHandle);
+
+ // 设置错误码
+ DWORD error = ERROR_FILE_NOT_FOUND;
+ if (context->GetPeInfo()->isX64) {
+ context->GetTeb64()->LastErrorValue = error;
+ } else {
+ context->GetTeb32()->LastErrorValue = error;
+ }
+ return;
+ }
+ }
+
+ // 生成唯一的文件句柄
+ uint64_t fileHandle = context->GenerateFileHandle();
+ fileHandleInfo->handle = fileHandle;
+
+ // 添加到文件句柄表
+ context->m_fileHandles[fileHandle] = fileHandleInfo;
+
+ printf("[*] CreateFileW: File=%ls, Access=0x%x, Share=0x%x, Create=0x%x, Handle=0x%llx\n",
+ filename.c_str(), dwDesiredAccess, dwShareMode, dwCreationDisposition, fileHandle);
+
+ // 返回文件句柄
+ uc_reg_write(uc,
+ context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
+ &fileHandle);
+}
+
+// ReadFileA API实现
+auto Api_ReadFileA(void* sandbox, uc_engine* uc, uint64_t address) -> void {
+ Api_ReadFile(sandbox, uc, address, false);
+}
+
+// ReadFileW API实现
+auto Api_ReadFileW(void* sandbox, uc_engine* uc, uint64_t address) -> void {
+ Api_ReadFile(sandbox, uc, address, true);
+}
+
+// 统一的ReadFile实现
+auto Api_ReadFile(void* sandbox, uc_engine* uc, uint64_t address, bool isWideChar) -> void {
+ auto context = static_cast(sandbox);
+ uint64_t hFile = 0;
+ uint64_t lpBuffer = 0;
+ uint32_t nNumberOfBytesToRead = 0;
+ uint64_t lpNumberOfBytesRead = 0;
+ uint64_t lpOverlapped = 0;
+
+ // 获取参数
+ if (context->GetPeInfo()->isX64) {
+ // x64: rcx = hFile, rdx = lpBuffer, r8 = nNumberOfBytesToRead, r9 = lpNumberOfBytesRead
+ uc_reg_read(uc, UC_X86_REG_RCX, &hFile);
+ uc_reg_read(uc, UC_X86_REG_RDX, &lpBuffer);
+ uint64_t temp_bytes_to_read;
+ uc_reg_read(uc, UC_X86_REG_R8, &temp_bytes_to_read);
+ nNumberOfBytesToRead = static_cast(temp_bytes_to_read);
+ uc_reg_read(uc, UC_X86_REG_R9, &lpNumberOfBytesRead);
+
+ // 从栈上读取lpOverlapped参数
+ uint64_t rsp;
+ uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
+ uc_mem_read(uc, rsp + 0x28, &lpOverlapped, sizeof(uint64_t));
+ } else {
+ // x86: 从栈上读取参数
+ uint32_t esp;
+ uc_reg_read(uc, UC_X86_REG_ESP, &esp);
+ esp += 0x4; // 跳过返回地址
+
+ uint32_t temp_handle, temp_buffer, temp_bytes_read, temp_overlapped;
+ uc_mem_read(uc, esp, &temp_handle, sizeof(uint32_t));
+ uc_mem_read(uc, esp + 0x4, &temp_buffer, sizeof(uint32_t));
+ uc_mem_read(uc, esp + 0x8, &nNumberOfBytesToRead, sizeof(uint32_t));
+ uc_mem_read(uc, esp + 0xC, &temp_bytes_read, sizeof(uint32_t));
+ uc_mem_read(uc, esp + 0x10, &temp_overlapped, sizeof(uint32_t));
+
+ hFile = temp_handle;
+ lpBuffer = temp_buffer;
+ lpNumberOfBytesRead = temp_bytes_read;
+ lpOverlapped = temp_overlapped;
+ }
+
+ // 从文件句柄表中查找句柄信息
+ auto fileInfo = context->GetFileHandleInfo(hFile);
+ bool success = false;
+ uint32_t bytesRead = 0;
+
+ if (fileInfo && fileInfo->isValid) {
+ // 计算实际可读取的字节数
+ size_t availableBytes = fileInfo->content.size() - fileInfo->currentPosition;
+ bytesRead = (nNumberOfBytesToRead < availableBytes) ? nNumberOfBytesToRead : (uint32_t)availableBytes;
+
+ if (bytesRead > 0) {
+ // 读取数据
+ uc_mem_write(uc, lpBuffer,
+ fileInfo->content.data() + fileInfo->currentPosition,
+ bytesRead);
+
+ // 更新当前位置
+ fileInfo->currentPosition += bytesRead;
+ success = true;
+ } else {
+ // 没有更多数据可读
+ success = true; // 返回TRUE,但是bytesRead为0
+ }
+ } else {
+ // 设置错误码
+ DWORD error = ERROR_INVALID_HANDLE;
+ if (context->GetPeInfo()->isX64) {
+ context->GetTeb64()->LastErrorValue = error;
+ } else {
+ context->GetTeb32()->LastErrorValue = error;
+ }
+ }
+
+ // 写入实际读取的字节数
+ if (lpNumberOfBytesRead != 0) {
+ uc_mem_write(uc, lpNumberOfBytesRead, &bytesRead, sizeof(uint32_t));
+ }
+
+ // 设置返回值
+ uint64_t result = success ? TRUE : FALSE;
+ uc_reg_write(uc,
+ context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
+ &result);
+
+ const char* apiName = isWideChar ? "ReadFileW" : "ReadFileA";
+ printf("[*] %s: Handle=0x%llx, Buffer=0x%llx, BytesToRead=%u, BytesRead=%u, Result=%s\n",
+ apiName, hFile, lpBuffer, nNumberOfBytesToRead, bytesRead,
+ success ? "TRUE" : "FALSE");
+}
+
+// CloseFile API实现
+auto Api_CloseFile(void* sandbox, uc_engine* uc, uint64_t address) -> void {
+ auto context = static_cast(sandbox);
+ uint64_t hFile = 0;
+
+ // 获取参数
+ if (context->GetPeInfo()->isX64) {
+ uc_reg_read(uc, UC_X86_REG_RCX, &hFile);
+ } else {
+ uint32_t esp;
+ uc_reg_read(uc, UC_X86_REG_ESP, &esp);
+ esp += 0x4; // 跳过返回地址
+ uint32_t temp_handle;
+ uc_mem_read(uc, esp, &temp_handle, sizeof(uint32_t));
+ hFile = temp_handle;
+ }
+
+ // 在文件句柄表中查找并释放资源
+ auto it = context->m_fileHandles.find(hFile);
+ bool success = false;
+
+ if (it != context->m_fileHandles.end() && it->second) {
+ delete it->second;
+ context->m_fileHandles.erase(it);
+ success = true;
+ }
+
+ // 设置返回值
+ uint64_t result = success ? TRUE : FALSE;
+ uc_reg_write(uc,
+ context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
+ &result);
+
+ printf("[*] CloseFile: Handle=0x%llx, Result=%s\n",
+ hFile, success ? "TRUE" : "FALSE");
+}
\ No newline at end of file
diff --git a/ai_anti_malware/sandbox_api_stl.cpp b/ai_anti_malware/sandbox_api_stl.cpp
index 9aa34ac..4810ee9 100644
--- a/ai_anti_malware/sandbox_api_stl.cpp
+++ b/ai_anti_malware/sandbox_api_stl.cpp
@@ -2531,3 +2531,591 @@ auto Api_getenv(void* sandbox, uc_engine* uc, uint64_t address) -> void {
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&return_value);
}
+
+auto Api_CreateDirectoryW(void* sandbox, uc_engine* uc, uint64_t address)
+-> void {
+ auto context = static_cast(sandbox);
+ uint64_t lpPathName = 0;
+ uint64_t lpSecurityAttributes = 0;
+
+ // 获取参数
+ if (context->GetPeInfo()->isX64) {
+ // x64: rcx = lpPathName, rdx = lpSecurityAttributes
+ uc_reg_read(uc, UC_X86_REG_RCX, &lpPathName);
+ uc_reg_read(uc, UC_X86_REG_RDX, &lpSecurityAttributes);
+ }
+ else {
+ // x86: 从栈上读取参数
+ uint32_t esp_address = 0;
+ uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
+ esp_address += 0x4; // 跳过返回地址
+
+ uint32_t temp_path_name, temp_security_attr;
+ uc_mem_read(uc, esp_address, &temp_path_name, sizeof(uint32_t));
+ uc_mem_read(uc, esp_address + 0x4, &temp_security_attr,
+ sizeof(uint32_t));
+
+ lpPathName = temp_path_name;
+ lpSecurityAttributes = temp_security_attr;
+ }
+
+ // 读取目录路径
+ wchar_t pathBuffer[MAX_PATH] = { 0 };
+ if (lpPathName != 0) {
+ size_t i = 0;
+ do {
+ uint16_t wchar;
+ uc_mem_read(uc, lpPathName + (i * 2), &wchar, 2);
+ pathBuffer[i] = wchar;
+ i++;
+ } while (pathBuffer[i - 1] != 0 && i < MAX_PATH);
+ }
+
+ // 将宽字符转换为常规字符串用于日志输出
+ std::wstring widePath(pathBuffer);
+ std::string path(widePath.begin(), widePath.end());
+
+ // 在实际的实现中,可能需要检查目录是否已存在
+ // 这里简单地返回成功,不实际创建目录
+ bool success = true;
+
+ // 输出日志
+ printf("[*] CreateDirectoryW: Path=%s, Result=%s\n", path.c_str(),
+ success ? "TRUE" : "FALSE");
+
+ // 设置返回值
+ uint64_t result = success ? 1 : 0;
+ uc_reg_write(uc,
+ context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
+ &result);
+
+ // 如果失败,可以设置LastError
+ if (!success) {
+ DWORD error = ERROR_PATH_NOT_FOUND; // 或其他适当的错误代码
+ if (context->GetPeInfo()->isX64) {
+ context->GetTeb64()->LastErrorValue = error;
+ }
+ else {
+ context->GetTeb32()->LastErrorValue = error;
+ }
+ }
+}
+auto Api_GetStringTypeW(void* sandbox, uc_engine* uc, uint64_t address)
+-> void {
+ auto context = static_cast(sandbox);
+ uint64_t dwInfoType = 0;
+ uint64_t lpSrcStr = 0;
+ int32_t cchSrc = 0;
+ uint64_t lpCharType = 0;
+
+ // 获取参数
+ if (context->GetPeInfo()->isX64) {
+ // x64: rcx = dwInfoType, rdx = lpSrcStr, r8 = cchSrc, r9 = lpCharType
+ uc_reg_read(uc, UC_X86_REG_RCX, &dwInfoType);
+ uc_reg_read(uc, UC_X86_REG_RDX, &lpSrcStr);
+ uint64_t temp_size;
+ uc_reg_read(uc, UC_X86_REG_R8, &temp_size);
+ cchSrc = static_cast(temp_size);
+ uc_reg_read(uc, UC_X86_REG_R9, &lpCharType);
+ }
+ 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, &dwInfoType, sizeof(uint32_t));
+ esp_address += 0x4;
+
+ uint32_t temp_src_str;
+ uc_mem_read(uc, esp_address, &temp_src_str, sizeof(uint32_t));
+ lpSrcStr = temp_src_str;
+ esp_address += 0x4;
+
+ uc_mem_read(uc, esp_address, &cchSrc, sizeof(int32_t));
+ esp_address += 0x4;
+
+ uint32_t temp_char_type;
+ uc_mem_read(uc, esp_address, &temp_char_type, sizeof(uint32_t));
+ lpCharType = temp_char_type;
+ }
+
+ // 验证参数
+ if (lpSrcStr == 0 || lpCharType == 0) {
+ uint64_t result = 0; // FALSE
+ uc_reg_write(
+ uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
+ &result);
+ DWORD error = ERROR_INVALID_PARAMETER;
+ if (context->GetPeInfo()->isX64) {
+ context->GetTeb64()->LastErrorValue = error;
+ }
+ else {
+ context->GetTeb32()->LastErrorValue = error;
+ }
+ return;
+ }
+
+ // 如果cchSrc为负数,计算字符串长度
+ if (cchSrc < 0) {
+ cchSrc = 0;
+ wchar_t temp_char;
+ do {
+ uc_mem_read(uc, lpSrcStr + (cchSrc * 2), &temp_char,
+ sizeof(wchar_t));
+ cchSrc++;
+ } while (temp_char != 0 && cchSrc < 1024); // 设置一个合理的上限
+ cchSrc--; // 不包括null终止符
+ }
+
+ // 读取源字符串
+ std::vector srcStr(cchSrc);
+ uc_mem_read(uc, lpSrcStr, srcStr.data(), cchSrc * sizeof(wchar_t));
+
+ // 处理每个字符
+ std::vector charTypes(cchSrc);
+ for (int i = 0; i < cchSrc; i++) {
+ WORD type = 0;
+ wchar_t ch = srcStr[i];
+
+ switch (dwInfoType) {
+ case CT_CTYPE1: {
+ // 基本字符类型检查
+ if (iswupper(ch)) type |= C1_UPPER;
+ if (iswlower(ch)) type |= C1_LOWER;
+ if (iswdigit(ch)) type |= C1_DIGIT;
+ if (iswspace(ch)) type |= C1_SPACE;
+ if (iswpunct(ch)) type |= C1_PUNCT;
+ if (iswcntrl(ch)) type |= C1_CNTRL;
+ if (ch == L' ' || ch == L'\t') type |= C1_BLANK;
+ if ((ch >= L'0' && ch <= L'9') || (ch >= L'A' && ch <= L'F') ||
+ (ch >= L'a' && ch <= L'f'))
+ type |= C1_XDIGIT;
+ if (iswalpha(ch)) type |= C1_ALPHA;
+ if (type == 0) type |= C1_DEFINED;
+ break;
+ }
+ case CT_CTYPE2: {
+ // 简单的双向文本支持
+ if ((ch >= L'A' && ch <= L'Z') || (ch >= L'a' && ch <= L'z') ||
+ (ch >= L'0' && ch <= L'9')) {
+ type = C2_LEFTTORIGHT;
+ }
+ else if (iswspace(ch)) {
+ type = C2_WHITESPACE;
+ }
+ else {
+ type = C2_NOTAPPLICABLE;
+ }
+ break;
+ }
+ case CT_CTYPE3: {
+ // 基本文本处理信息
+ if (iswalpha(ch)) type |= C3_ALPHA;
+ // 这里可以添加更多的C3类型检查
+ break;
+ }
+ }
+ charTypes[i] = type;
+ }
+
+ // 写入结果
+ uc_mem_write(uc, lpCharType, charTypes.data(), cchSrc * sizeof(WORD));
+
+ printf("[*] GetStringTypeW: InfoType=0x%x, StrLen=%d\n", dwInfoType,
+ cchSrc);
+
+ // 返回成功
+ uint64_t result = 1; // TRUE
+ uc_reg_write(uc,
+ context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
+ &result);
+}
+
+auto Api_LCMapStringW(void* sandbox, uc_engine* uc, uint64_t address) -> void {
+ auto context = static_cast(sandbox);
+ uint32_t Locale = 0;
+ uint32_t dwMapFlags = 0;
+ uint64_t lpSrcStr = 0;
+ int32_t cchSrc = 0;
+ uint64_t lpDestStr = 0;
+ int32_t cchDest = 0;
+
+ // 获取参数
+ if (context->GetPeInfo()->isX64) {
+ // x64: rcx = Locale, rdx = dwMapFlags, r8 = lpSrcStr, r9 = cchSrc
+ uc_reg_read(uc, UC_X86_REG_RCX, &Locale);
+ uc_reg_read(uc, UC_X86_REG_RDX, &dwMapFlags);
+ uc_reg_read(uc, UC_X86_REG_R8, &lpSrcStr);
+ uint64_t temp_src_size;
+ uc_reg_read(uc, UC_X86_REG_R9, &temp_src_size);
+ cchSrc = static_cast(temp_src_size);
+
+ // 从栈上读取剩余参数
+ uint64_t rsp;
+ uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
+ uc_mem_read(uc, rsp + 0x28, &lpDestStr, sizeof(uint64_t));
+ uc_mem_read(uc, rsp + 0x30, &cchDest, 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, &Locale, sizeof(uint32_t));
+ esp_address += 0x4;
+
+ uc_mem_read(uc, esp_address, &dwMapFlags, sizeof(uint32_t));
+ esp_address += 0x4;
+
+ uint32_t temp_src_str;
+ uc_mem_read(uc, esp_address, &temp_src_str, sizeof(uint32_t));
+ lpSrcStr = temp_src_str;
+ esp_address += 0x4;
+
+ uc_mem_read(uc, esp_address, &cchSrc, sizeof(int32_t));
+ esp_address += 0x4;
+
+ uint32_t temp_dest_str;
+ uc_mem_read(uc, esp_address, &temp_dest_str, sizeof(uint32_t));
+ lpDestStr = temp_dest_str;
+ esp_address += 0x4;
+
+ uc_mem_read(uc, esp_address, &cchDest, sizeof(int32_t));
+ }
+
+ // 验证参数
+ if (lpSrcStr == 0) {
+ uint32_t result = 0;
+ uc_reg_write(
+ uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
+ &result);
+ DWORD error = ERROR_INVALID_PARAMETER;
+ if (context->GetPeInfo()->isX64) {
+ context->GetTeb64()->LastErrorValue = error;
+ }
+ else {
+ context->GetTeb32()->LastErrorValue = error;
+ }
+ return;
+ }
+
+ // 如果cchSrc为负数,计算源字符串长度
+ if (cchSrc < 0) {
+ cchSrc = 0;
+ wchar_t temp_char;
+ do {
+ uc_mem_read(uc, lpSrcStr + (cchSrc * 2), &temp_char,
+ sizeof(wchar_t));
+ cchSrc++;
+ } while (temp_char != 0 && cchSrc < 1024); // 设置一个合理的上限
+ cchSrc--; // 不包括null终止符
+ }
+
+ // 读取源字符串
+ std::vector srcStr(cchSrc);
+ uc_mem_read(uc, lpSrcStr, srcStr.data(), cchSrc * sizeof(wchar_t));
+
+ // 如果cchDest为0,返回所需缓冲区大小
+ if (cchDest == 0) {
+ uint32_t required_size = cchSrc;
+ if (dwMapFlags & LCMAP_SORTKEY) {
+ required_size = cchSrc * 2 + 1; // 排序键通常需要更多空间
+ }
+ uc_reg_write(
+ uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
+ &required_size);
+ return;
+ }
+
+ // 检查目标缓冲区大小是否足够
+ if (cchDest < cchSrc) {
+ uint32_t result = 0;
+ uc_reg_write(
+ uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
+ &result);
+ DWORD error = ERROR_INSUFFICIENT_BUFFER;
+ if (context->GetPeInfo()->isX64) {
+ context->GetTeb64()->LastErrorValue = error;
+ }
+ else {
+ context->GetTeb32()->LastErrorValue = error;
+ }
+ return;
+ }
+
+ // 处理字符串映射
+ std::vector destStr(cchSrc);
+ for (int i = 0; i < cchSrc; i++) {
+ wchar_t ch = srcStr[i];
+ if (dwMapFlags & LCMAP_UPPERCASE) {
+ destStr[i] = towupper(ch);
+ }
+ else if (dwMapFlags & LCMAP_LOWERCASE) {
+ destStr[i] = towlower(ch);
+ }
+ else {
+ destStr[i] = ch; // 默认保持不变
+ }
+ }
+
+ // 写入结果
+ if (dwMapFlags & LCMAP_SORTKEY) {
+ // 生成简单的排序键(这里只是一个基本实现)
+ std::vector sortKey(cchSrc * 2 + 1);
+ for (int i = 0; i < cchSrc; i++) {
+ sortKey[i * 2] = static_cast(destStr[i] & 0xFF);
+ sortKey[i * 2 + 1] = static_cast((destStr[i] >> 8) & 0xFF);
+ }
+ sortKey[cchSrc * 2] = 0; // 终止符
+ uc_mem_write(uc, lpDestStr, sortKey.data(), sortKey.size());
+ uint32_t result = static_cast(sortKey.size());
+ uc_reg_write(
+ uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
+ &result);
+ }
+ else {
+ // 写入映射后的字符串
+ uc_mem_write(uc, lpDestStr, destStr.data(), cchSrc * sizeof(wchar_t));
+ uint32_t result = cchSrc;
+ uc_reg_write(
+ uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
+ &result);
+ }
+
+ printf(
+ "[*] LCMapStringW: Locale=0x%x, MapFlags=0x%x, SrcLen=%d, DestLen=%d\n",
+ Locale, dwMapFlags, cchSrc, cchDest);
+}
+
+// 实现 LCMapStringEx API
+auto Api_LCMapStringEx(void* sandbox, uc_engine* uc, uint64_t address) -> void {
+ auto context = static_cast(sandbox);
+ uint64_t lpLocaleName = 0;
+ uint64_t dwMapFlags = 0;
+ uint64_t lpSrcStr = 0;
+ uint64_t cchSrc = 0;
+ uint64_t lpDestStr = 0;
+ uint64_t cchDest = 0;
+ uint64_t lpVersionInformation = 0; // 通常为 NULL
+ uint64_t lpReserved = 0; // 必须为 NULL
+ uint64_t sortHandle = 0; // 必须为 0
+
+ // 获取参数
+ if (context->GetPeInfo()->isX64) {
+ // x64: rcx = lpLocaleName, rdx = dwMapFlags, r8 = lpSrcStr, r9 = cchSrc
+ uc_reg_read(uc, UC_X86_REG_RCX, &lpLocaleName);
+ uc_reg_read(uc, UC_X86_REG_RDX, &dwMapFlags);
+ uc_reg_read(uc, UC_X86_REG_R8, &lpSrcStr);
+ uint64_t temp_src_size;
+ uc_reg_read(uc, UC_X86_REG_R9, &temp_src_size);
+ cchSrc = static_cast(temp_src_size);
+
+ // 从栈上读取剩余参数 (参数 5 到 9)
+ uint64_t rsp;
+ uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
+ // 参数从 rsp + 0x28 开始 (跳过4个寄存器参数的shadow space + 返回地址)
+ uc_mem_read(uc, rsp + 0x28, &lpDestStr, sizeof(uint64_t));
+ uc_mem_read(uc, rsp + 0x30, &cchDest, sizeof(int32_t));
+ // 注意:参数在栈上的偏移量可能需要根据调用约定微调
+ uc_mem_read(uc, rsp + 0x38, &lpVersionInformation, sizeof(uint64_t));
+ uc_mem_read(uc, rsp + 0x40, &lpReserved, sizeof(uint64_t));
+ uc_mem_read(uc, rsp + 0x48, &sortHandle, sizeof(uint64_t));
+
+ }
+ else {
+ // x86: 从栈上读取所有参数
+ uint32_t esp_address = 0;
+ uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
+ esp_address += 0x4; // 跳过返回地址
+
+ uint32_t temp_locale_name, temp_src_str, temp_dest_str, temp_version_info, temp_reserved, temp_sort_handle;
+
+ uc_mem_read(uc, esp_address, &temp_locale_name, sizeof(uint32_t)); lpLocaleName = temp_locale_name; esp_address += 0x4;
+ uc_mem_read(uc, esp_address, &dwMapFlags, sizeof(uint32_t)); esp_address += 0x4;
+ uc_mem_read(uc, esp_address, &temp_src_str, sizeof(uint32_t)); lpSrcStr = temp_src_str; esp_address += 0x4;
+ uc_mem_read(uc, esp_address, &cchSrc, sizeof(int32_t)); esp_address += 0x4;
+ uc_mem_read(uc, esp_address, &temp_dest_str, sizeof(uint32_t)); lpDestStr = temp_dest_str; esp_address += 0x4;
+ uc_mem_read(uc, esp_address, &cchDest, sizeof(int32_t)); esp_address += 0x4;
+ uc_mem_read(uc, esp_address, &temp_version_info, sizeof(uint32_t)); lpVersionInformation = temp_version_info; esp_address += 0x4;
+ uc_mem_read(uc, esp_address, &temp_reserved, sizeof(uint32_t)); lpReserved = temp_reserved; esp_address += 0x4;
+ uc_mem_read(uc, esp_address, &temp_sort_handle, sizeof(uint32_t)); sortHandle = temp_sort_handle; esp_address += 0x4;
+ }
+
+ // 读取区域设置名称(可选,模拟中可能忽略)
+ std::wstring localeNameStr;
+ if (lpLocaleName != 0) {
+ wchar_t buffer[LOCALE_NAME_MAX_LENGTH] = { 0 };
+ size_t i = 0;
+ do {
+ uint16_t wchar;
+ if (uc_mem_read(uc, lpLocaleName + (i * 2), &wchar, 2) != UC_ERR_OK) break;
+ buffer[i] = wchar;
+ i++;
+ } while (buffer[i - 1] != 0 && i < LOCALE_NAME_MAX_LENGTH);
+ localeNameStr = buffer;
+ }
+
+
+ // 验证参数 (与 LCMapStringW 类似)
+ if (lpSrcStr == 0 || lpReserved != 0 || sortHandle != 0) { // 添加了对 lpReserved 和 sortHandle 的检查
+ uint32_t result = 0;
+ uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result);
+ DWORD error = ERROR_INVALID_PARAMETER;
+ if (context->GetPeInfo()->isX64) {
+ context->GetTeb64()->LastErrorValue = error;
+ }
+ else {
+ context->GetTeb32()->LastErrorValue = error;
+ }
+ printf("[*] LCMapStringEx: Invalid parameter (lpSrcStr=0x%llx, lpReserved=0x%llx, sortHandle=0x%llx)\\n", lpSrcStr, lpReserved, sortHandle);
+ return;
+ }
+
+ // 如果cchSrc为负数,计算源字符串长度 (与 LCMapStringW 相同)
+ if (cchSrc < 0) {
+ cchSrc = 0;
+ wchar_t temp_char;
+ do {
+ if (uc_mem_read(uc, lpSrcStr + (cchSrc * 2), &temp_char, sizeof(wchar_t)) != UC_ERR_OK) {
+ // 内存读取错误处理
+ uint32_t result = 0;
+ uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result);
+ DWORD error = ERROR_INVALID_PARAMETER; // 或者更具体的错误
+ if (context->GetPeInfo()->isX64) context->GetTeb64()->LastErrorValue = error;
+ else context->GetTeb32()->LastErrorValue = error;
+ printf("[*] LCMapStringEx: Error reading source string length at 0x%llx\\n", lpSrcStr + (cchSrc * 2));
+ return;
+ }
+ cchSrc++;
+ } while (temp_char != 0 && cchSrc < 4096); // 增加合理上限防止死循环
+ if (cchSrc >= 4096) {
+ // 字符串过长或未找到终止符
+ uint32_t result = 0;
+ uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result);
+ DWORD error = ERROR_INVALID_PARAMETER;
+ if (context->GetPeInfo()->isX64) context->GetTeb64()->LastErrorValue = error;
+ else context->GetTeb32()->LastErrorValue = error;
+ printf("[*] LCMapStringEx: Source string too long or unterminated at 0x%llx\\n", lpSrcStr);
+ return;
+ }
+ cchSrc--; // 不包括null终止符
+ }
+
+
+ // 读取源字符串 (与 LCMapStringW 相同)
+ std::vector srcStr(cchSrc + 1, 0); // 分配足够空间并初始化为0
+ if (cchSrc > 0) {
+ if (uc_mem_read(uc, lpSrcStr, srcStr.data(), cchSrc * sizeof(wchar_t)) != UC_ERR_OK) {
+ // 内存读取错误处理
+ uint32_t result = 0;
+ uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result);
+ DWORD error = ERROR_INVALID_PARAMETER; // 或者更具体的错误
+ if (context->GetPeInfo()->isX64) context->GetTeb64()->LastErrorValue = error;
+ else context->GetTeb32()->LastErrorValue = error;
+ printf("[*] LCMapStringEx: Error reading source string data from 0x%llx\\n", lpSrcStr);
+ return;
+ }
+ }
+
+
+ uint32_t required_size = cchSrc; // 默认需要的大小与源长度相同
+ bool needs_null_terminator = false; // 是否需要在目标缓冲区添加空终止符
+
+ // 根据 dwMapFlags 确定是否需要空终止符以及调整所需大小
+ if (!(dwMapFlags & LCMAP_BYTEREV) && !(dwMapFlags & LCMAP_SORTKEY)) {
+ required_size++; // 需要为 null 终止符增加空间
+ needs_null_terminator = true;
+ }
+ if (dwMapFlags & LCMAP_SORTKEY) {
+ required_size = cchSrc * 2 + 1; // 排序键通常需要更多空间,包含终止符
+ needs_null_terminator = true; // Sortkey is null-terminated byte array
+ }
+
+
+ // 如果cchDest为0,返回所需缓冲区大小 (与 LCMapStringW 类似,但考虑了 null 终止符)
+ if (cchDest == 0) {
+ uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &required_size);
+ printf("[*] LCMapStringEx: Querying buffer size. Required: %u\\n", required_size);
+ return;
+ }
+
+ // 检查目标缓冲区大小是否足够
+ if (cchDest < required_size) {
+ uint32_t result = 0;
+ uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result);
+ DWORD error = ERROR_INSUFFICIENT_BUFFER;
+ if (context->GetPeInfo()->isX64) {
+ context->GetTeb64()->LastErrorValue = error;
+ }
+ else {
+ context->GetTeb32()->LastErrorValue = error;
+ }
+ printf("[*] LCMapStringEx: Insufficient buffer. Provided: %d, Required: %u\\n", cchDest, required_size);
+ return;
+ }
+
+ // 处理字符串映射 (与 LCMapStringW 类似)
+ std::vector destStr(cchSrc);
+ for (int i = 0; i < cchSrc; i++) {
+ wchar_t ch = srcStr[i];
+ if (dwMapFlags & LCMAP_UPPERCASE) {
+ destStr[i] = towupper(ch);
+ }
+ else if (dwMapFlags & LCMAP_LOWERCASE) {
+ destStr[i] = towlower(ch);
+ }
+ else {
+ destStr[i] = ch; // 默认保持不变
+ }
+ // TODO: 处理其他 dwMapFlags,如 LCMAP_HALFWIDTH, LCMAP_FULLWIDTH, LCMAP_HIRAGANA, LCMAP_KATAKANA, LCMAP_LINGUISTIC_CASING 等
+ // 这些需要更复杂的实现,可能需要 NLS 功能库或 ICU
+ }
+
+
+ // 写入结果
+ uint32_t written_size = 0;
+ uc_err write_err = UC_ERR_OK;
+
+ if (dwMapFlags & LCMAP_SORTKEY) {
+ // 生成简单的排序键(这里只是一个基本实现) (与 LCMapStringW 相同)
+ std::vector sortKey(required_size); // 使用 required_size
+ for (int i = 0; i < cchSrc; i++) {
+ // 简单地将 wchar_t 分解为两个字节
+ sortKey[i * 2] = static_cast(destStr[i] & 0xFF);
+ sortKey[i * 2 + 1] = static_cast((destStr[i] >> 8) & 0xFF);
+ }
+ sortKey[cchSrc * 2] = 0; // 终止符
+ write_err = uc_mem_write(uc, lpDestStr, sortKey.data(), required_size);
+ written_size = required_size;
+ }
+ else {
+ // 写入映射后的字符串
+ write_err = uc_mem_write(uc, lpDestStr, destStr.data(), cchSrc * sizeof(wchar_t));
+ if (write_err == UC_ERR_OK && needs_null_terminator) {
+ // 写入 null 终止符
+ wchar_t null_term = 0;
+ write_err = uc_mem_write(uc, lpDestStr + (cchSrc * sizeof(wchar_t)), &null_term, sizeof(wchar_t));
+ }
+ written_size = needs_null_terminator ? (cchSrc + 1) : cchSrc;
+ }
+
+
+ if (write_err != UC_ERR_OK) {
+ // 写入错误处理
+ uint32_t result = 0;
+ uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result);
+ DWORD error = ERROR_INVALID_PARAMETER; // 或者更具体的内存写入错误码
+ if (context->GetPeInfo()->isX64) context->GetTeb64()->LastErrorValue = error;
+ else context->GetTeb32()->LastErrorValue = error;
+ printf("[*] LCMapStringEx: Error writing to destination buffer at 0x%llx. Error: %u\\n", lpDestStr, write_err);
+ return;
+ }
+
+ // 设置返回值 (写入的字符数或字节数,取决于 flags)
+ uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &written_size);
+
+ printf("[*] LCMapStringEx: Locale=%ls, MapFlags=0x%x, SrcLen=%d, DestLen=%d, Result=%u\\n",
+ localeNameStr.empty() ? L"(null)" : localeNameStr.c_str(), dwMapFlags, cchSrc, cchDest, written_size);
+}
\ No newline at end of file