From 232a7abcbab171f12c42f83a72cfc70a8eb5f803 Mon Sep 17 00:00:00 2001 From: huoji Date: Wed, 19 Mar 2025 20:47:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=A2=9E=E5=8A=A032=E4=BD=8D?= =?UTF-8?q?=E6=94=AF=E6=8C=81(=E6=B2=A1=E5=8A=A0=E5=85=A8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ai_anti_malware/ai_anti_malware.cpp | 16 +- ai_anti_malware/ai_anti_malware.vcxproj | 4 +- ai_anti_malware/native_struct.h | 54 ++++ ai_anti_malware/sandbox.cpp | 41 ++- ai_anti_malware/sandbox.h | 5 +- ai_anti_malware/sandbox_api_emu.cpp | 314 +++++++++++++++++++- ai_anti_malware/sandbox_api_process.cpp | 147 ++++++---- ai_anti_malware/sandbox_api_stl.cpp | 364 ++++++++++++++++++++---- ai_anti_malware/sandbox_callbacks.cpp | 11 +- 9 files changed, 819 insertions(+), 137 deletions(-) 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;