diff --git a/ai_anti_malware/ai_anti_malware.cpp b/ai_anti_malware/ai_anti_malware.cpp
index f525406..f67344c 100644
--- a/ai_anti_malware/ai_anti_malware.cpp
+++ b/ai_anti_malware/ai_anti_malware.cpp
@@ -313,26 +313,24 @@ auto doMalwareScan(int argc, char* argv[]) -> void {
}
int doSandbox(int argc, char* argv[]) {
- if (argc < 3) {
- std::cout << "用法: " << argv[0] << " <文件路径> <地址>" << std::endl;
- return;
- }
- std::string filePath = argv[1];
+ std::string filePath = "C:\\opengl32.dll";
auto peInfo = getPeInfo(filePath);
if (peInfo == nullptr) {
- return 0;
+ std::cout << "无法加载PE文件: " << filePath << std::endl;
+ return 1;
}
+
Sandbox se;
se.InitEnv(peInfo);
- // se.Run(0x180003980);
+ se.Run(0x10002F20);
return 0;
}
int main(int argc, char* argv[]) {
// doMl(argc, argv);
// doPredict(argc, argv);
- doMalwareScan(argc, argv);
- // doSandbox(argc, argv);
+ // doMalwareScan(argc, argv);
+ doSandbox(argc, argv);
return 0;
}
diff --git a/ai_anti_malware/ai_anti_malware.vcxproj b/ai_anti_malware/ai_anti_malware.vcxproj
index fb1fa85..157f328 100644
--- a/ai_anti_malware/ai_anti_malware.vcxproj
+++ b/ai_anti_malware/ai_anti_malware.vcxproj
@@ -82,6 +82,7 @@
false
+ $(SolutionDir)ai_anti_malware\libpeconv\libpeconv\;$(SolutionDir)ai_anti_malware\libpeconv\libpeconv\include;$(SolutionDir)ai_anti_malware\libpeconv\;$(IncludePath)
@@ -131,8 +132,9 @@
true
true
true
- NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
true
+ stdcpplatest
Console
diff --git a/ai_anti_malware/native_struct.h b/ai_anti_malware/native_struct.h
index e7c8dce..5301b1a 100644
--- a/ai_anti_malware/native_struct.h
+++ b/ai_anti_malware/native_struct.h
@@ -120,6 +120,12 @@ typedef struct _UNICODE_STRING {
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;
+typedef struct _UNICODE_STRING32 {
+ USHORT Length;
+ USHORT MaximumLength;
+ DWORD Buffer;
+} UNICODE_STRING32;
+
typedef UNICODE_STRING* PUNICODE_STRING;
typedef const UNICODE_STRING* PCUNICODE_STRING;
typedef PVOID(NTAPI* RtlImageDirectoryEntryToDataFn)(PVOID, BOOLEAN, USHORT,
@@ -905,6 +911,54 @@ union SegmentSelector {
};
static_assert(sizeof(SegmentSelector) == 2, "Size check");
#include
+typedef struct _STARTUPINFOW32 {
+ DWORD cb;
+ DWORD lpReserved;
+ DWORD lpDesktop;
+ DWORD lpTitle;
+ DWORD dwX;
+ DWORD dwY;
+ DWORD dwXSize;
+ DWORD dwYSize;
+ DWORD dwXCountChars;
+ DWORD dwYCountChars;
+ DWORD dwFillAttribute;
+ DWORD dwFlags;
+ WORD wShowWindow;
+ WORD cbReserved2;
+ DWORD lpReserved2;
+ DWORD hStdInput;
+ DWORD hStdOutput;
+ DWORD hStdError;
+} STARTUPINFOW32, * LPSTARTUPINFOW32;
+static_assert(sizeof(STARTUPINFOW32) == 68, "Size check");
+typedef struct tagPROCESSENTRY32W_32
+{
+ DWORD dwSize;
+ DWORD cntUsage;
+ DWORD th32ProcessID; // this process
+ DWORD th32DefaultHeapID;
+ DWORD th32ModuleID; // associated exe
+ DWORD cntThreads;
+ DWORD th32ParentProcessID; // this process's parent process
+ LONG pcPriClassBase; // Base priority of process's threads
+ DWORD dwFlags;
+ WCHAR szExeFile[MAX_PATH]; // Path
+} PROCESSENTRY32W_32;
+static_assert(sizeof(PROCESSENTRY32W_32) == 556, "Size check");
+#pragma pack(push, 8)
+
+typedef struct _RTL_CRITICAL_SECTION32 {
+ DWORD DebugInfo;
+ LONG LockCount;
+ LONG RecursionCount;
+ DWORD OwningThread; // from the thread's ClientId->UniqueThread
+ DWORD LockSemaphore;
+ DWORD SpinCount; // force size on 64-bit systems when packed
+} RTL_CRITICAL_SECTION32, * PRTL_CRITICAL_SECTION32;
+
+#pragma pack(pop)
+static_assert(sizeof(RTL_CRITICAL_SECTION32) == 24, "Size check");
union FlagRegister {
ULONG_PTR all;
diff --git a/ai_anti_malware/sandbox.cpp b/ai_anti_malware/sandbox.cpp
index ba3203f..cb53f7d 100644
--- a/ai_anti_malware/sandbox.cpp
+++ b/ai_anti_malware/sandbox.cpp
@@ -651,7 +651,7 @@ auto Sandbox::InitEnv(std::shared_ptr peInfo) -> void {
if (!peconv::load_imports(m_peInfo->peBuffer, &importFixer)) {
throw std::runtime_error("Failed to fix imports");
}
- //给所有导入表加c3
+ // 给所有导入表加c3
for (const auto& module : this->GetModuleList()) {
// 遍历导出函数查找对应名称
for (const auto& exp : module->export_function) {
@@ -751,8 +751,8 @@ auto Sandbox::Run(uint64_t address) -> void {
}
// 系统调用钩子
err = uc_hook_add(m_ucEngine, &hook_syscall, UC_HOOK_INTR | UC_HOOK_INSN,
- reinterpret_cast(sandboxCallbacks::handleSyscall),
- this, 1, 0, UC_X86_INS_SYSCALL);
+ reinterpret_cast(sandboxCallbacks::handleSyscall),
+ this, 1, 0, UC_X86_INS_SYSCALL);
if (err != UC_ERR_OK) {
throw std::runtime_error("Failed to add syscall hook");
}
@@ -773,9 +773,38 @@ auto Sandbox::Run(uint64_t address) -> void {
// 1.入口点是必须跑的
if (m_peInfo->isDll) {
// 给rcx和rdx设置dll应该设置的
- auto dll_fdwReason = 1;
- uc_reg_write(m_ucEngine, UC_X86_REG_RCX, &m_peInfo->RecImageBase);
- uc_reg_write(m_ucEngine, UC_X86_REG_RDX, &dll_fdwReason);
+ auto dll_fdwReason = 1; // DLL_PROCESS_ATTACH
+ if (m_peInfo->isX64) {
+ uc_reg_write(m_ucEngine, UC_X86_REG_RCX, &m_peInfo->RecImageBase);
+ uc_reg_write(m_ucEngine, UC_X86_REG_RDX, &dll_fdwReason);
+ } else {
+ // 32位使用栈传参而不是寄存器传参
+ uint32_t rsp;
+ uc_reg_read(m_ucEngine, UC_X86_REG_ESP, &rsp);
+
+ // 为参数腾出空间
+ rsp -= 3 * 4; // 三个参数:hinstDLL, fdwReason, lpvReserved
+ uc_reg_write(m_ucEngine, UC_X86_REG_ESP, &rsp);
+
+ // 按照从右到左的顺序压栈
+ uint32_t lpvReserved = 0; // 第三个参数为NULL
+ uint32_t reason = dll_fdwReason; // DLL_PROCESS_ATTACH
+ uint32_t imageBase = static_cast(m_peInfo->RecImageBase);
+
+ // 按照从右到左的调用约定写入参数到栈上
+ uc_mem_write(m_ucEngine, rsp, &lpvReserved,
+ sizeof(uint32_t)); // lpvReserved (最右侧参数最先入栈)
+ uc_mem_write(m_ucEngine, rsp + 4, &reason,
+ sizeof(uint32_t)); // fdwReason (中间参数次之入栈)
+ uc_mem_write(m_ucEngine, rsp + 8, &imageBase,
+ sizeof(uint32_t)); // hinstDLL (最左侧参数最后入栈)
+
+ // 在Windows下,DLL的返回地址也需要压栈
+ uint32_t returnAddress = 0xABABABAB; // 虚拟的返回地址
+ rsp -= 4; // 为返回地址腾出空间
+ uc_reg_write(m_ucEngine, UC_X86_REG_ESP, &rsp);
+ uc_mem_write(m_ucEngine, rsp, &returnAddress, sizeof(uint32_t));
+ }
}
err = uc_emu_start(m_ucEngine, entryPoint, m_peInfo->imageEnd, timeout, 0);
// 2. 有自定义地址 再跑自定义地址
diff --git a/ai_anti_malware/sandbox.h b/ai_anti_malware/sandbox.h
index 0d40d4d..8b4b5b3 100644
--- a/ai_anti_malware/sandbox.h
+++ b/ai_anti_malware/sandbox.h
@@ -425,4 +425,7 @@ auto Api_FwpmProviderAdd0(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto Api_FwpmFilterAdd0(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_FwpmEngineClose0(void* sandbox, uc_engine* uc, uint64_t address)
- -> void;
\ No newline at end of file
+ -> void;
+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;
\ 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 c39e836..5e904f6 100644
--- a/ai_anti_malware/sandbox_api_emu.cpp
+++ b/ai_anti_malware/sandbox_api_emu.cpp
@@ -2,6 +2,7 @@
#include "sandbox_callbacks.h"
#include "sandbox_api_winhttp.h"
#include
+
auto Api_QueryPerformanceCounter(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast(sandbox);
@@ -602,7 +603,16 @@ auto Api_VirtualProtect(void* sandbox, uc_engine* uc, uint64_t address)
// 检查地址范围是否已映射
uint32_t unicornProtect = WindowsToUnicornProtect(flNewProtect);
- uc_err err = uc_mem_protect(uc, lpAddress, dwSize, unicornProtect);
+ // 对齐地址和大小到页面边界
+ uint64_t aligned_address =
+ lpAddress & ~(PAGE_SIZE - 1); // 向下对齐到页面边界
+ uint64_t end_address = (lpAddress + dwSize + PAGE_SIZE - 1) &
+ ~(PAGE_SIZE - 1); // 向上对齐到页面边界
+ uint64_t aligned_size = end_address - aligned_address;
+
+ uc_err err =
+ uc_mem_protect(uc, aligned_address, aligned_size, unicornProtect);
+
if (err != UC_ERR_OK) {
uint64_t result = 0; // FALSE
uc_reg_write(
@@ -909,6 +919,285 @@ auto Api_CreateDirectoryW(void* sandbox, uc_engine* uc, uint64_t address)
}
}
}
+auto Api_GetStringTypeW(void* sandbox, uc_engine* uc, uint64_t address)
+ -> void {
+ auto context = static_cast(sandbox);
+ uint32_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 =
_fakeApi{.func = Api_GetSystemTimeAsFileTime, .paramCount = 1};
@@ -1062,6 +1351,15 @@ auto Sandbox::InitApiHooks() -> void {
_fakeApi{.func = Api_CreateDirectoryW, .paramCount = 2};
auto FakeApi_URLDownloadToFileW =
_fakeApi{.func = Api_URLDownloadToFileW, .paramCount = 5};
+ auto FakeApi_TlsFree = _fakeApi{.func = Api_TlsFree, .paramCount = 1};
+ auto FakeApi_FlsAlloc = _fakeApi{.func = Api_FlsAlloc, .paramCount = 1};
+ auto FakeApi_FlsGetValue =
+ _fakeApi{.func = Api_FlsGetValue, .paramCount = 1};
+ auto FakeApi_GetStringTypeW =
+ _fakeApi{.func = Api_GetStringTypeW, .paramCount = 4};
+ auto FakeApi_LCMapStringW =
+ _fakeApi{.func = Api_LCMapStringW, .paramCount = 6};
+
api_map = {
{"GetSystemTimeAsFileTime",
std::make_shared<_fakeApi>(FakeApi_GetSystemTimeAsFileTime)},
@@ -1187,14 +1485,15 @@ auto Sandbox::InitApiHooks() -> void {
std::make_shared<_fakeApi>(FakeApi_LookupPrivilegeValueA)},
{"AdjustTokenPrivileges",
std::make_shared<_fakeApi>(FakeApi_AdjustTokenPrivileges)},
- {"LookupPrivilegeValueA",
- std::make_shared<_fakeApi>(FakeApi_LookupPrivilegeValueA)},
- {"AdjustTokenPrivileges",
- std::make_shared<_fakeApi>(FakeApi_AdjustTokenPrivileges)},
{"CreateDirectoryW",
std::make_shared<_fakeApi>(FakeApi_CreateDirectoryW)},
{"URLDownloadToFileW",
std::make_shared<_fakeApi>(FakeApi_URLDownloadToFileW)},
+ {"TlsFree", std::make_shared<_fakeApi>(FakeApi_TlsFree)},
+ {"FlsAlloc", std::make_shared<_fakeApi>(FakeApi_FlsAlloc)},
+ {"FlsGetValue", std::make_shared<_fakeApi>(FakeApi_FlsGetValue)},
+ {"GetStringTypeW", std::make_shared<_fakeApi>(FakeApi_GetStringTypeW)},
+ {"LCMapStringW", std::make_shared<_fakeApi>(FakeApi_LCMapStringW)},
};
}
auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip,
@@ -1202,8 +1501,8 @@ auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip,
auto it = api_map.find(ApiName);
if (it != api_map.end()) {
it->second->func(this, uc, address);
- this->ApiCallList.push_back(ApiName);
+ this->ApiCallList.push_back(ApiName);
// 获取参数数量
int paramCount = it->second->paramCount;
uint32_t esp;
@@ -1236,7 +1535,8 @@ auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip,
// x86下,所有参数都通过栈传递
// 调整栈指针:每个参数4字节 + 返回地址4字节
esp += (paramCount * 4) + 4;
- // 设置EIP为返回地址
+ // esp += 4;
+ // 设置EIP为返回地址
uc_reg_write(uc, UC_X86_REG_EIP, &return_address_32);
}
if (this->GetPeInfo()->isX64) {
diff --git a/ai_anti_malware/sandbox_api_process.cpp b/ai_anti_malware/sandbox_api_process.cpp
index 93e2aa8..e8b70ef 100644
--- a/ai_anti_malware/sandbox_api_process.cpp
+++ b/ai_anti_malware/sandbox_api_process.cpp
@@ -270,23 +270,46 @@ auto Api_Process32FirstW(void* sandbox, uc_engine* uc, uint64_t address)
// 读取结构体大小
DWORD structSize = 0;
if (uc_mem_read(uc, lppe, &structSize, sizeof(DWORD)) == UC_ERR_OK) {
- if (structSize == sizeof(PROCESSENTRY32W)) {
- // 获取第一个进程信息(在我们的实现中是DingTalk.exe)
- PROCESSENTRY32W pe32 = {0};
- pe32.dwSize = sizeof(PROCESSENTRY32W);
- pe32.th32ProcessID = 1001; // DingTalk的PID
- pe32.cntThreads = 1;
- pe32.th32ParentProcessID = 4; // 父进程是System
- pe32.pcPriClassBase = 8; // 正常优先级
+ if (context->GetPeInfo()->isX64) {
+ if (structSize == sizeof(PROCESSENTRY32W)) {
+ // 获取第一个进程信息(在我们的实现中是DingTalk.exe)
+ PROCESSENTRY32W pe32 = { 0 };
+ pe32.dwSize = sizeof(PROCESSENTRY32W);
+ pe32.th32ProcessID = 1001; // DingTalk的PID
+ pe32.cntThreads = 1;
+ pe32.th32ParentProcessID = 4; // 父进程是System
+ pe32.pcPriClassBase = 8; // 正常优先级
- // 设置进程名
- std::wstring procName = L"DingTalk.exe";
- wcscpy_s(pe32.szExeFile, procName.c_str());
+ // 设置进程名
+ std::wstring procName = L"DingTalk.exe";
+ wcscpy_s(pe32.szExeFile, procName.c_str());
- // 写入进程信息到用户提供的缓冲区
- if (uc_mem_write(uc, lppe, &pe32, sizeof(PROCESSENTRY32W)) ==
- UC_ERR_OK) {
- success = true;
+ // 写入进程信息到用户提供的缓冲区
+ if (uc_mem_write(uc, lppe, &pe32, sizeof(PROCESSENTRY32W)) ==
+ UC_ERR_OK) {
+ success = true;
+ }
+ }
+ }
+ else {
+ if (structSize == sizeof(PROCESSENTRY32W_32)) {
+ // 获取第一个进程信息(在我们的实现中是DingTalk.exe)
+ PROCESSENTRY32W_32 pe32 = { 0 };
+ pe32.dwSize = sizeof(PROCESSENTRY32W_32);
+ pe32.th32ProcessID = 1001; // DingTalk的PID
+ pe32.cntThreads = 1;
+ pe32.th32ParentProcessID = 4; // 父进程是System
+ pe32.pcPriClassBase = 8; // 正常优先级
+
+ // 设置进程名
+ std::wstring procName = L"DingTalk.exe";
+ wcscpy_s(pe32.szExeFile, procName.c_str());
+
+ // 写入进程信息到用户提供的缓冲区
+ if (uc_mem_write(uc, lppe, &pe32, sizeof(PROCESSENTRY32W_32)) ==
+ UC_ERR_OK) {
+ success = true;
+ }
}
}
}
@@ -388,6 +411,36 @@ auto Api_Process32NextW(void* sandbox, uc_engine* uc, uint64_t address)
hSnapshot = temp_handle;
lppe = temp_lppe;
}
+ // 获取当前进程索引
+ size_t currentIndex = 0;
+ auto it = context->process_enum_state.find(hSnapshot);
+ if (it != context->process_enum_state.end()) {
+ currentIndex = it->second;
+ currentIndex++; // 移动到下一个进程
+ }
+
+ // 定义进程列表
+ struct ProcessInfo {
+ const wchar_t* name;
+ uint32_t pid;
+ uint32_t parentPid;
+ };
+
+ ProcessInfo processes[] = {
+ {L"DingTalk.exe", 1001, 4}, // 钉钉
+ {L"Lanxin.exe", 1002, 4}, // 蓝信
+ {L"QQ.exe", 1003, 4}, // QQ
+ {L"Feishu.exe", 1004, 4}, // 飞书
+ {L"explorer.exe", 1005, 4}, // Windows 资源管理器
+ {L"svchost.exe", 1006, 4}, // 系统服务宿主进程
+ {L"System", 4, 0}, // 系统进程
+ {L"smss.exe", 376, 4}, // 会话管理器
+ {L"csrss.exe", 648, 376}, // 客户端服务器运行时子系统
+ {L"winlogon.exe", 672, 376}, // Windows 登录进程
+ };
+
+ const size_t processCount =
+ sizeof(processes) / sizeof(processes[0]);
// 验证句柄
bool success = false;
@@ -395,43 +448,37 @@ auto Api_Process32NextW(void* sandbox, uc_engine* uc, uint64_t address)
// 读取结构体大小
DWORD structSize = 0;
if (uc_mem_read(uc, lppe, &structSize, sizeof(DWORD)) == UC_ERR_OK) {
- if (structSize == sizeof(PROCESSENTRY32W)) {
- // 获取当前进程索引
- size_t currentIndex = 0;
- auto it = context->process_enum_state.find(hSnapshot);
- if (it != context->process_enum_state.end()) {
- currentIndex = it->second;
- currentIndex++; // 移动到下一个进程
+ if (context->GetPeInfo()->isX64) {
+ if (structSize == sizeof(PROCESSENTRY32W)) {
+ // 检查是否还有更多进程
+ if (currentIndex < processCount) {
+ // 填充进程信息
+ PROCESSENTRY32W pe32 = { 0 };
+ pe32.dwSize = sizeof(PROCESSENTRY32W);
+ pe32.th32ProcessID = processes[currentIndex].pid;
+ pe32.th32ParentProcessID =
+ processes[currentIndex].parentPid;
+ pe32.cntThreads = 1;
+ pe32.pcPriClassBase = 8; // 正常优先级
+
+ // 设置进程名
+ wcscpy_s(pe32.szExeFile, processes[currentIndex].name);
+
+ // 写入进程信息到用户提供的缓冲区
+ if (uc_mem_write(uc, lppe, &pe32,
+ sizeof(PROCESSENTRY32W)) == UC_ERR_OK) {
+ success = true;
+ // 更新进程索引
+ context->process_enum_state[hSnapshot] = currentIndex;
+ }
+ }
}
-
- // 定义进程列表
- struct ProcessInfo {
- const wchar_t* name;
- uint32_t pid;
- uint32_t parentPid;
- };
-
- ProcessInfo processes[] = {
- {L"DingTalk.exe", 1001, 4}, // 钉钉
- {L"Lanxin.exe", 1002, 4}, // 蓝信
- {L"QQ.exe", 1003, 4}, // QQ
- {L"Feishu.exe", 1004, 4}, // 飞书
- {L"explorer.exe", 1005, 4}, // Windows 资源管理器
- {L"svchost.exe", 1006, 4}, // 系统服务宿主进程
- {L"System", 4, 0}, // 系统进程
- {L"smss.exe", 376, 4}, // 会话管理器
- {L"csrss.exe", 648, 376}, // 客户端服务器运行时子系统
- {L"winlogon.exe", 672, 376}, // Windows 登录进程
- };
-
- const size_t processCount =
- sizeof(processes) / sizeof(processes[0]);
-
- // 检查是否还有更多进程
+ }
+ else {
if (currentIndex < processCount) {
// 填充进程信息
- PROCESSENTRY32W pe32 = {0};
- pe32.dwSize = sizeof(PROCESSENTRY32W);
+ PROCESSENTRY32W_32 pe32 = { 0 };
+ pe32.dwSize = sizeof(PROCESSENTRY32W_32);
pe32.th32ProcessID = processes[currentIndex].pid;
pe32.th32ParentProcessID =
processes[currentIndex].parentPid;
@@ -443,7 +490,7 @@ auto Api_Process32NextW(void* sandbox, uc_engine* uc, uint64_t address)
// 写入进程信息到用户提供的缓冲区
if (uc_mem_write(uc, lppe, &pe32,
- sizeof(PROCESSENTRY32W)) == UC_ERR_OK) {
+ sizeof(PROCESSENTRY32W_32)) == UC_ERR_OK) {
success = true;
// 更新进程索引
context->process_enum_state[hSnapshot] = currentIndex;
diff --git a/ai_anti_malware/sandbox_api_stl.cpp b/ai_anti_malware/sandbox_api_stl.cpp
index 07bfad0..a8cb73b 100644
--- a/ai_anti_malware/sandbox_api_stl.cpp
+++ b/ai_anti_malware/sandbox_api_stl.cpp
@@ -1333,39 +1333,72 @@ auto Api_EnterCriticalSection(void* sandbox, uc_engine* uc, uint64_t address)
lpCriticalSection = temp_cs;
}
+ // 获取当前线程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 (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;
- }
+ RTL_CRITICAL_SECTION cs;
+ uc_mem_read(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION));
- // 如果当前线程已经拥有锁,增加递归计数
- 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++;
+
+ // 如果当前线程已经拥有锁,增加递归计数
+ 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));
+ // 写回更新后的关键段结构
+ uc_mem_write(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION));
+ }
+ else {
+ RTL_CRITICAL_SECTION32 cs;
+ uc_mem_read(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION32));
+
+
+ // 如果当前线程已经拥有锁,增加递归计数
+ if (cs.OwningThread == (DWORD)currentThreadHandle) {
+ cs.RecursionCount++;
+ }
+ else {
+ // 如果没有线程拥有锁,获取它
+ if (cs.LockCount == -1) {
+ cs.OwningThread = (DWORD)currentThreadHandle;
+ cs.RecursionCount = 1;
+ cs.LockCount = 0;
+ }
+ else {
+ // 在实际情况下这里应该自旋等待,但在模拟环境中我们直接获取锁
+ cs.OwningThread = (DWORD)currentThreadHandle;
+ cs.RecursionCount = 1;
+ cs.LockCount++;
+ }
+ }
+
+ // 写回更新后的关键段结构
+ uc_mem_write(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION32));
+ }
}
printf("[*] EnterCriticalSection: CS=0x%llx\n", lpCriticalSection);
@@ -1426,7 +1459,7 @@ auto Api_GetStartupInfoW(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast(sandbox);
uint64_t lpStartupInfo = 0;
-
+ printf("[*] GetStartupInfoW start dump vmenv\n");
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = lpStartupInfo
@@ -1442,28 +1475,49 @@ auto Api_GetStartupInfoW(void* sandbox, uc_engine* uc, uint64_t address)
}
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));
+ if (context->GetPeInfo()->isX64) {
+ 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));
+ }
+ else {
+ STARTUPINFOW32 si = { 0 };
+ si.cb = sizeof(STARTUPINFOW32);
+ si.dwFlags = STARTF_USESHOWWINDOW;
+ si.wShowWindow = SW_SHOWNORMAL;
+ si.lpDesktop = 0;
+ si.lpTitle = 0;
+ 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 = 0;
+ si.hStdInput = 0;
+ si.hStdOutput = 0;
+ si.hStdError = 0;
+ uc_mem_write(uc, lpStartupInfo, &si, sizeof(STARTUPINFOW32));
+ }
}
printf("[*] GetStartupInfoW: lpStartupInfo=0x%llx\n", lpStartupInfo);
@@ -2058,15 +2112,25 @@ auto Api_RtlFormatCurrentUserKeyPath(void* sandbox, uc_engine* uc,
if (stringBuffer != 0 && keyPathBuffer != 0) {
// 将路径字符串写入到分配的缓冲区
uc_mem_write(uc, stringBuffer, userKeyPath, bufferSize);
+ if (context->GetPeInfo()->isX64) {
+ // 创建UNICODE_STRING结构
+ UNICODE_STRING unicodeString;
+ unicodeString.Length = static_cast(pathLen * sizeof(wchar_t));
+ unicodeString.MaximumLength = static_cast(bufferSize);
+ unicodeString.Buffer = reinterpret_cast(stringBuffer);
- // 创建UNICODE_STRING结构
- UNICODE_STRING unicodeString;
- unicodeString.Length = static_cast(pathLen * sizeof(wchar_t));
- unicodeString.MaximumLength = static_cast(bufferSize);
- unicodeString.Buffer = reinterpret_cast(stringBuffer);
+ // 将UNICODE_STRING结构写入到提供的缓冲区
+ uc_mem_write(uc, keyPathBuffer, &unicodeString, sizeof(UNICODE_STRING));
+ }
+ else {
+ UNICODE_STRING32 unicodeString;
+ unicodeString.Length = static_cast(pathLen * sizeof(wchar_t));
+ unicodeString.MaximumLength = static_cast(bufferSize);
+ unicodeString.Buffer = (DWORD)(stringBuffer);
- // 将UNICODE_STRING结构写入到提供的缓冲区
- uc_mem_write(uc, keyPathBuffer, &unicodeString, sizeof(UNICODE_STRING));
+ // 将UNICODE_STRING结构写入到提供的缓冲区
+ uc_mem_write(uc, keyPathBuffer, &unicodeString, sizeof(UNICODE_STRING32));
+ }
}
// 返回NTSTATUS成功代码 (0x00000000 = STATUS_SUCCESS)
@@ -2143,3 +2207,189 @@ auto Api_FlsSetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void {
}
}
}
+
+// 实现TlsFree API
+auto Api_TlsFree(void* sandbox, uc_engine* uc, uint64_t address) -> void {
+ auto context = static_cast(sandbox);
+ uint32_t dwTlsIndex = 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)并释放对应的TLS槽
+ BOOL success = FALSE;
+ if (dwTlsIndex < 64) {
+ if (context->GetPeInfo()->isX64) {
+ auto teb = context->GetTeb64();
+ // 检查槽是否已分配(不为0x1337ffffff)
+ if (teb->TlsSlots[dwTlsIndex] != (void*)0x1337ffffff) {
+ // 将槽位标记为可用
+ teb->TlsSlots[dwTlsIndex] = (void*)0x1337ffffff;
+ success = TRUE;
+ }
+ } else {
+ auto teb = context->GetTeb32();
+ // 检查槽是否已分配(不为0x1337)
+ if (teb->TlsSlots[dwTlsIndex] != 0x1337) {
+ // 将槽位标记为可用
+ teb->TlsSlots[dwTlsIndex] = 0x1337;
+ success = TRUE;
+ }
+ }
+ }
+
+ if (!success) {
+ // 设置错误码
+ DWORD error = ERROR_INVALID_PARAMETER;
+ if (context->GetPeInfo()->isX64) {
+ context->GetTeb64()->LastErrorValue = error;
+ } else {
+ context->GetTeb32()->LastErrorValue = error;
+ }
+ }
+
+ printf("[*] TlsFree: Index=0x%x, Success=%d\n", dwTlsIndex, success);
+
+ // 返回操作是否成功
+ uc_reg_write(uc,
+ context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
+ &success);
+}
+
+// 实现FlsAlloc API
+auto Api_FlsAlloc(void* sandbox, uc_engine* uc, uint64_t address) -> void {
+ auto context = static_cast(sandbox);
+ uint64_t lpCallback = 0;
+
+ // 获取参数
+ if (context->GetPeInfo()->isX64) {
+ // x64: rcx = lpCallback
+ uc_reg_read(uc, UC_X86_REG_RCX, &lpCallback);
+ } else {
+ // x86: 从栈上读取参数
+ uint32_t esp_address = 0;
+ uint32_t temp_callback = 0;
+ uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
+ esp_address += 0x4; // 跳过返回地址
+ uc_mem_read(uc, esp_address, &temp_callback, sizeof(uint32_t));
+ lpCallback = temp_callback;
+ }
+
+ // 初始化返回值为失败状态
+ DWORD fls_index = FLS_OUT_OF_INDEXES;
+
+ // 获取TEB结构
+ if (context->GetPeInfo()->isX64) {
+ auto teb = context->GetTeb64();
+ // 在TLS槽中查找第一个可用的位置
+ for (DWORD i = 0; i < 64; i++) { // TEB中TlsSlots数组大小为64
+ if (teb->TlsSlots[i] == (void*)0x1337ffffff) {
+ teb->TlsSlots[i] = (void*)0; // 标记为已使用
+ fls_index = i;
+ break;
+ }
+ }
+ } else {
+ auto teb = context->GetTeb32();
+ // 在TLS槽中查找第一个可用的位置
+ for (DWORD i = 0; i < 64; i++) { // TEB中TlsSlots数组大小为64
+ if (teb->TlsSlots[i] == 0x1337) {
+ teb->TlsSlots[i] = 0; // 标记为已使用
+ fls_index = i;
+ break;
+ }
+ }
+ }
+
+ if (fls_index == FLS_OUT_OF_INDEXES) {
+ // 设置LastError为没有可用的FLS索引
+ DWORD error = ERROR_NO_MORE_ITEMS;
+ if (context->GetPeInfo()->isX64) {
+ context->GetTeb64()->LastErrorValue = error;
+ } else {
+ context->GetTeb32()->LastErrorValue = error;
+ }
+ }
+
+ printf("[*] FlsAlloc: Callback=0x%llx, Allocated FLS Index=0x%x\n",
+ lpCallback, fls_index);
+
+ // 返回分配的FLS索引
+ uc_reg_write(uc,
+ context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
+ &fls_index);
+}
+
+// 实现FlsGetValue API
+auto Api_FlsGetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void {
+ auto context = static_cast(sandbox);
+ uint32_t dwFlsIndex = 0;
+ uint64_t return_value = 0;
+
+ // 获取参数
+ if (context->GetPeInfo()->isX64) {
+ // x64: rcx = dwFlsIndex
+ uint64_t temp_index;
+ uc_reg_read(uc, UC_X86_REG_RCX, &temp_index);
+ dwFlsIndex = 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, &dwFlsIndex, sizeof(uint32_t));
+ }
+
+ // 检查索引是否有效(小于64)
+ if (dwFlsIndex < 64) {
+ if (context->GetPeInfo()->isX64) {
+ auto teb = context->GetTeb64();
+ // 检查槽是否已分配(不为nullptr)
+ if (teb->TlsSlots[dwFlsIndex] != (void*)0x1337ffffff) {
+ return_value =
+ reinterpret_cast(teb->TlsSlots[dwFlsIndex]);
+ } else {
+ // 槽未分配,设置LastError
+ DWORD error = ERROR_INVALID_PARAMETER;
+ teb->LastErrorValue = error;
+ }
+ } else {
+ auto teb = context->GetTeb32();
+ // 检查槽是否已分配(不为0)
+ if (teb->TlsSlots[dwFlsIndex] != 0x1337) {
+ return_value = teb->TlsSlots[dwFlsIndex];
+ } 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("[*] FlsGetValue: Index=0x%x, Value=0x%llx\n", dwFlsIndex,
+ return_value);
+
+ // 返回FLS槽中的值
+ uc_reg_write(uc,
+ context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
+ &return_value);
+}
diff --git a/ai_anti_malware/sandbox_callbacks.cpp b/ai_anti_malware/sandbox_callbacks.cpp
index f361ae4..5b70e0b 100644
--- a/ai_anti_malware/sandbox_callbacks.cpp
+++ b/ai_anti_malware/sandbox_callbacks.cpp
@@ -38,7 +38,6 @@ void handleCodeRun(uc_engine* uc, uint64_t address, uint32_t size,
break;
}
}
-
// 如果找到区段,并且与上次执行的区段不同,记录跨区段行为
if (currentSectionIndex >= 0 &&
sandbox->GetLastExecuteSectionIndex() != currentSectionIndex &&
@@ -84,7 +83,7 @@ void handleCodeRun(uc_engine* uc, uint64_t address, uint32_t size,
}
cs_free(instruction, instructionCount);
- // dumpVmenv(uc, userData);
+ //dumpVmenv(uc, userData);
}
}
@@ -177,9 +176,9 @@ void dumpVmenv(uc_engine* uc, void* userData) {
"%08x Ecx: %08x\n",
Rip, Rax, Rsp, Rbp, Rcx, Rdx, Eax, Ecx);
- // 打印16层栈内存
- printf("\n[Stack Memory Dump (16 levels)]\n");
- const int STACK_LEVELS = 16;
+ // 打印32层栈内存
+ printf("\n[Stack Memory Dump (32 levels)]\n");
+ const int STACK_LEVELS = 32;
const int POINTER_SIZE = sandbox->GetPeInfo()->isX64 ? 8 : 4;
for (int i = 0; i < STACK_LEVELS; i++) {
@@ -219,7 +218,7 @@ void dumpVmenv(uc_engine* uc, void* userData) {
}
}
- printf("\n[Frame Pointer Stack (16 levels)]\n");
+ printf("\n[Frame Pointer Stack (32 levels)]\n");
uint64_t currentBp = Rbp;
for (int i = 0; i < STACK_LEVELS && currentBp != 0; i++) {
uint64_t nextBp = 0;