From 534b6a84a6401049969c8a0552fdf43c757cec68 Mon Sep 17 00:00:00 2001 From: huoji Date: Tue, 18 Mar 2025 20:49:18 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B2=99=E7=AE=B1=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E5=92=8CAPI=E9=92=A9=E5=AD=90=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在沙箱中实现了新的功能,包括内存分配和API钩子初始化 - 更新了沙箱类,增加了对WFP引擎的支持 - 添加了多个API的实现,如GetLastError、InitializeCriticalSection等 - 修改了主函数以使用新的沙箱功能,替换了恶意软件扫描功能 - 更新了项目文件以包含新的源文件和API实现 - 改进了错误处理和日志记录功能 --- .vscode/c_cpp_properties.json | 19 + ai_anti_malware/ai_anti_malware.cpp | 23 +- ai_anti_malware/ai_anti_malware.vcxproj | 4 + .../ai_anti_malware.vcxproj.filters | 29 +- ai_anti_malware/head.h | 11 +- ai_anti_malware/sandbox.cpp | 57 +- ai_anti_malware/sandbox.h | 130 ++- ai_anti_malware/sandbox_api_emu.cpp | 825 ++---------------- ai_anti_malware/sandbox_api_file.cpp | 180 ++++ ai_anti_malware/sandbox_api_process.cpp | 784 +++++++++++++++++ ai_anti_malware/sandbox_api_stl.cpp | 618 ++++++++++++- ai_anti_malware/sandbox_api_wfp.cpp | 220 +++++ ai_anti_malware/sandbox_api_wlan.cpp | 286 ++++++ ai_anti_malware/sandbox_callbacks.cpp | 8 +- ai_anti_malware/tiny_wfp_structs.h | 3 + 15 files changed, 2443 insertions(+), 754 deletions(-) create mode 100644 .vscode/c_cpp_properties.json create mode 100644 ai_anti_malware/sandbox_api_file.cpp create mode 100644 ai_anti_malware/sandbox_api_process.cpp create mode 100644 ai_anti_malware/sandbox_api_wfp.cpp create mode 100644 ai_anti_malware/sandbox_api_wlan.cpp create mode 100644 ai_anti_malware/tiny_wfp_structs.h diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..97c8fc9 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,19 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [ + "_DEBUG", + "UNICODE", + "_UNICODE" + ], + "compilerPath": "E:/Program Files/LLVM/bin/clang++.exe", + "cStandard": "c11", + "cppStandard": "c++23" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/ai_anti_malware/ai_anti_malware.cpp b/ai_anti_malware/ai_anti_malware.cpp index bd125dc..45f439e 100644 --- a/ai_anti_malware/ai_anti_malware.cpp +++ b/ai_anti_malware/ai_anti_malware.cpp @@ -39,6 +39,7 @@ auto getPeInfo(std::string inputFilePath) -> std::shared_ptr { sampleInfo->RecImageBase + (sampleInfo->isX64 ? sampleInfo->ntHead64->OptionalHeader.SizeOfImage : sampleInfo->ntHead32->OptionalHeader.SizeOfImage); + sampleInfo->isDll = peconv::is_module_dll((BYTE*)sampleInfo->peBuffer); printf("Debug - Memory mapping parameters:\n"); printf("RecImageBase: 0x%llx\n", sampleInfo->RecImageBase); printf("peSize: 0x%llx\n", sampleInfo->peSize); @@ -310,9 +311,29 @@ auto doMalwareScan(int argc, char* argv[]) -> void { auto sampleType = scanner.DetectMalware(filePath); printf("sample type: %d \n", sampleType); } +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:\\mso.dll"; + + auto peInfo = getPeInfo(filePath); + if (peInfo == nullptr) { + return 0; + } + Sandbox se; + se.InitEnv(peInfo); + se.Run(0x180003980); + return 0; +} int main(int argc, char* argv[]) { // doMl(argc, argv); // doPredict(argc, argv); - doMalwareScan(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 ea626f5..fb1fa85 100644 --- a/ai_anti_malware/ai_anti_malware.vcxproj +++ b/ai_anti_malware/ai_anti_malware.vcxproj @@ -174,9 +174,13 @@ + + + + diff --git a/ai_anti_malware/ai_anti_malware.vcxproj.filters b/ai_anti_malware/ai_anti_malware.vcxproj.filters index 5143e33..c02f998 100644 --- a/ai_anti_malware/ai_anti_malware.vcxproj.filters +++ b/ai_anti_malware/ai_anti_malware.vcxproj.filters @@ -28,6 +28,9 @@ {65a79261-ea29-4842-b41c-7983eddbdc85} + + {44f6b6b6-64fa-44ff-b7fa-af7f7294a3f2} + @@ -120,9 +123,6 @@ 源文件\sandbox - - 源文件\sandbox - 源文件\machine_learning @@ -132,14 +132,29 @@ 源文件\sandbox + + 源文件\sandbox\apis + + + 源文件\sandbox\apis + + + 源文件\sandbox\apis + - 源文件\sandbox + 源文件\sandbox\apis - 源文件\sandbox + 源文件\sandbox\apis - - 源文件\sandbox + + 源文件\sandbox\apis + + + 源文件\sandbox\apis + + + 源文件\sandbox\apis diff --git a/ai_anti_malware/head.h b/ai_anti_malware/head.h index ab4c354..f99b4c4 100644 --- a/ai_anti_malware/head.h +++ b/ai_anti_malware/head.h @@ -3,21 +3,23 @@ #define _CRT_SECURE_NO_WARNINGS #include -#include -#include +#include + #include #include #include -#include #include - +#include +#include +#include #include "unicorn/include/unicorn/unicorn.h" #include "capstone/include/capstone/capstone.h" #pragma comment(lib, "unicorn/unicorn.lib") #pragma comment(lib, "capstone/capstone.lib") #include "libpeconv/include/peconv.h" #include "native_struct.h" +#include "tiny_wfp_structs.h" struct BasicPeInfo { std::string inputFilePath; bool isX64; @@ -29,6 +31,7 @@ struct BasicPeInfo { size_t peSize; PIMAGE_NT_HEADERS ntHead64; PIMAGE_NT_HEADERS32 ntHead32; + bool isDll; }; #include "sandbox.h" #include "ml.h" \ No newline at end of file diff --git a/ai_anti_malware/sandbox.cpp b/ai_anti_malware/sandbox.cpp index 924e345..5b224ef 100644 --- a/ai_anti_malware/sandbox.cpp +++ b/ai_anti_malware/sandbox.cpp @@ -2,6 +2,28 @@ #include "sandbox_callbacks.h" +// 在文件开头添加AllocateMemory函数的声明 +auto Sandbox::AllocateMemory(size_t size) -> uint64_t { + // 使用一个简单的内存分配策略 + static uint64_t next_address = 0x60000000; // 起始地址 + uint64_t allocated_address = next_address; + + // 对齐到4KB + size = (size + 0xFFF) & ~0xFFF; + + // 分配内存 + uc_err err = uc_mem_map(m_ucEngine, allocated_address, size, UC_PROT_ALL); + if (err != UC_ERR_OK) { + printf("[!] Failed to allocate memory at 0x%llx: %u\n", + allocated_address, err); + return 0; + } + + // 更新下一个可用地址 + next_address += size + 0x1000; // 添加一个页面的间隔 + return allocated_address; +} + std::string getDllNameFromApiSetMap(const std::string& apiSet) { const std::wstring wApiSet(apiSet.begin(), apiSet.end()); @@ -174,9 +196,19 @@ class cFixImprot : public peconv::t_function_resolver { private: Sandbox* m_sandbox; // Sandbox实例的指针 }; -Sandbox::Sandbox() {} +Sandbox::Sandbox() { + m_ucEngine = nullptr; + m_peInfo = nullptr; + m_nextWfpEngineHandle = (HANDLE)0x1000; // 初始化WFP引擎句柄 +} Sandbox::~Sandbox() { + // 清理WFP引擎资源 + for (auto& pair : m_wfpEngines) { + delete pair.second; + } + m_wfpEngines.clear(); + // 1. 先清理高层资源 m_crossSectionExecution.clear(); envStrings.clear(); @@ -631,7 +663,7 @@ auto Sandbox::InitEnv(std::shared_ptr peInfo) -> void { InitCommandLine(peInfo->inputFilePath); } -auto Sandbox::Run() -> void { +auto Sandbox::Run(uint64_t address) -> void { // 初始化堆栈 uc_err err = uc_mem_map(m_ucEngine, m_stackBase, m_stackSize, UC_PROT_READ | UC_PROT_WRITE); @@ -659,7 +691,7 @@ auto Sandbox::Run() -> void { &rbp); // 设置入口点 - uint64_t entryPoint = m_peInfo->RecImageBase + m_peInfo->entryPoint; + uint64_t entryPoint = (m_peInfo->RecImageBase + m_peInfo->entryPoint); // 添加钩子 uc_hook hook_code, hook_mem, hook_mem_unmap, hook_mem_write, hook_syscall; @@ -708,7 +740,7 @@ auto Sandbox::Run() -> void { if (err != UC_ERR_OK) { throw std::runtime_error("Failed to add syscall hook"); } - + auto customIP = address; // 设置EIP/RIP err = uc_reg_write(m_ucEngine, m_peInfo->isX64 ? UC_X86_REG_RIP : UC_X86_REG_EIP, @@ -718,11 +750,26 @@ auto Sandbox::Run() -> void { } InitApiHooks(); + std::cout << "Starting execution at " << std::hex << entryPoint << std::endl; uint64_t timeout = 60 * 1000 * 1000; + // 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); + } err = uc_emu_start(m_ucEngine, entryPoint, m_peInfo->imageEnd, timeout, 0); - std::cerr << "Emulation error: " << uc_strerror(err) << std::endl; + // 2. 有自定义地址 再跑自定义地址 + std::cerr << "Entry Point Emulation error: " << uc_strerror(err) + << std::endl; + if (address != 0) { + err = uc_emu_start(m_ucEngine, address, m_peInfo->imageEnd, timeout, 0); + std::cerr << "Custom Emulation error: " << uc_strerror(err) + << std::endl; + } } auto Sandbox::GetEnvString() -> std::vector { diff --git a/ai_anti_malware/sandbox.h b/ai_anti_malware/sandbox.h index fcd49ce..3dc5941 100644 --- a/ai_anti_malware/sandbox.h +++ b/ai_anti_malware/sandbox.h @@ -1,9 +1,7 @@ #pragma once -#include -#include #include "head.h" -#include +#include #define PAGE_SIZE 0x1000 #define CF_MASK (1 << 0) #define PF_MASK (1 << 2) @@ -87,12 +85,21 @@ struct InternetHandleInfo { class Sandbox { friend class cFixImprot; // 声明cFixImprot为友元类 public: + // WFP引擎相关结构体 + struct FakeWFPEngine { + bool isOpen; + std::vector providers; + std::vector filters; + }; + Sandbox(); ~Sandbox(); + std::map + process_enum_state; // 用于跟踪每个句柄的枚举状态 // Public methods auto InitEnv(std::shared_ptr peInfo) -> void; - auto Run() -> void; + auto Run(uint64_t address = 0) -> void; auto GetCapstoneHandle() const -> csh { return m_csHandle; } auto GetUnicornHandle() const -> uc_engine* { return m_ucEngine; } auto GetPeInfo() const -> std::shared_ptr { return m_peInfo; } @@ -115,6 +122,9 @@ class Sandbox { auto GetEnvStringsSize() -> size_t; auto InitCommandLine() -> void; + // 内存分配相关的方法 + auto AllocateMemory(size_t size) -> uint64_t; + // 堆管理相关的公共方法 auto CreateHeapSegment(uint64_t base, size_t size) -> HeapSegment*; auto AllocateFromSegment(HeapSegment* segment, size_t size) -> uint64_t; @@ -213,6 +223,16 @@ class Sandbox { } std::vector ApiCallList; + // WFP引擎相关方法 + auto GetWfpEngines() -> std::map& { + return m_wfpEngines; + } + auto GetNextWfpEngineHandle() -> HANDLE { + auto handle = m_nextWfpEngineHandle; + m_nextWfpEngineHandle = (HANDLE)((uint64_t)m_nextWfpEngineHandle + 1); + return handle; + } + private: std::shared_ptr m_peInfo; uint64_t m_gsBase; @@ -302,4 +322,106 @@ class Sandbox { auto UpdateLdrLinks(const LDR_DATA_TABLE_ENTRY& entry, uint64_t entryAddress, X64_PEB_LDR_DATA& ldrData) -> void; + + // WFP引擎相关成员 + std::map m_wfpEngines; + HANDLE m_nextWfpEngineHandle; }; +std::string getDllNameFromApiSetMap(const std::string& apiSet); +void Api_GetLastError(void* sandbox, uc_engine* uc, uint64_t address); +auto Api_InitializeCriticalSectionAndSpinCount(void* sandbox, uc_engine* uc, + uint64_t address) -> void; +auto Api_InitializeCriticalSectionEx(void* sandbox, uc_engine* uc, + uint64_t address) -> void; +auto Api_IsProcessorFeaturePresent(void* sandbox, uc_engine* uc, + uint64_t address) -> void; +auto Api_DeleteCriticalSection(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +auto Api_TlsAlloc(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_TlsSetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api___set_app_type(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api___p__fmode(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_RegOpenKeyExW(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_RegCloseKey(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_AreFileApisANSI(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +auto Api_WideCharToMultiByte(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +auto Api_InitializeSListHead(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +auto Api_GetEnvironmentStringsW(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +auto Api_FreeEnvironmentStringsW(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +auto Api_GetProcessHeap(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_HeapAlloc(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_HeapFree(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_TlsGetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_SetLastError(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_EnterCriticalSection(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +auto Api_LeaveCriticalSection(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +auto Api_GetStartupInfoW(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +auto Api_GetStdHandle(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_GetFileType(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_HeapCreate(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_GetCommandLineA(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +auto Api_GetCommandLineW(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +auto Api_GetACP(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_GetCPInfo(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_MultiByteToWideChar(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +auto Api_SHGetKnownFolderPath(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +auto Api_EncodePointer(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_Process32NextW(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_CreateToolhelp32Snapshot(void* sandbox, uc_engine* uc, + uint64_t address) -> void; +auto Api_Process32FirstW(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +auto Api_VirtualQuery(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_GetModuleHandleW(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +auto Api_GetModuleHandleA(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +auto GetModuleHandleInternal(void* sandbox, const std::wstring& moduleName) + -> HMODULE; +auto Api_Process32NextW(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_WlanOpenHandle(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_WlanEnumInterfaces(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +auto Api_WlanGetProfileList(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +auto Api_WlanFreeMemory(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_WlanCloseHandle(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +auto Api_ReadFile(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_CreatePipe(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_CloseHandle(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_RtlFormatCurrentUserKeyPath(void* sandbox, uc_engine* uc, + uint64_t address) -> void; +auto Api_FlsSetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_CreateFileW(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_WriteFile(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_CreateProcessA(void* sandbox, uc_engine* uc, uint64_t address) -> void; +auto Api_GetCurrentProcess(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +auto Api_GetCurrentThread(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +auto Api_OpenProcessToken(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +auto Api_GetTokenInformation(void* sandbox, uc_engine* uc, uint64_t address) + -> void; + +// WFP API函数声明 +auto Api_FwpmEngineOpen0(void* sandbox, uc_engine* uc, uint64_t address) + -> void; +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 diff --git a/ai_anti_malware/sandbox_api_emu.cpp b/ai_anti_malware/sandbox_api_emu.cpp index 6507fc2..eb024fa 100644 --- a/ai_anti_malware/sandbox_api_emu.cpp +++ b/ai_anti_malware/sandbox_api_emu.cpp @@ -1,47 +1,7 @@ #include "sandbox.h" #include "sandbox_callbacks.h" #include "sandbox_api_winhttp.h" -std::string getDllNameFromApiSetMap(const std::string& apiSet); -auto Api_RegOpenKeyExW(void* sandbox, uc_engine* uc, uint64_t address) -> void; -auto Api_RegCloseKey(void* sandbox, uc_engine* uc, uint64_t address) -> void; -auto Api_AreFileApisANSI(void* sandbox, uc_engine* uc, uint64_t address) - -> void; -auto Api_WideCharToMultiByte(void* sandbox, uc_engine* uc, uint64_t address) - -> void; -auto Api_InitializeSListHead(void* sandbox, uc_engine* uc, uint64_t address) - -> void; -; -auto Api_GetEnvironmentStringsW(void* sandbox, uc_engine* uc, uint64_t address) - -> void; -; -auto Api_FreeEnvironmentStringsW(void* sandbox, uc_engine* uc, uint64_t address) - -> void; -auto Api_GetProcessHeap(void* sandbox, uc_engine* uc, uint64_t address) -> void; -auto Api_HeapAlloc(void* sandbox, uc_engine* uc, uint64_t address) -> void; -auto Api_HeapFree(void* sandbox, uc_engine* uc, uint64_t address) -> void; -auto Api_TlsGetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void; -auto Api_SetLastError(void* sandbox, uc_engine* uc, uint64_t address) -> void; -auto Api_EnterCriticalSection(void* sandbox, uc_engine* uc, uint64_t address) - -> void; -auto Api_LeaveCriticalSection(void* sandbox, uc_engine* uc, uint64_t address) - -> void; -auto Api_GetStartupInfoW(void* sandbox, uc_engine* uc, uint64_t address) - -> void; -auto Api_GetStdHandle(void* sandbox, uc_engine* uc, uint64_t address) -> void; -auto Api_GetFileType(void* sandbox, uc_engine* uc, uint64_t address) -> void; -auto Api_HeapCreate(void* sandbox, uc_engine* uc, uint64_t address) -> void; -auto Api_GetCommandLineA(void* sandbox, uc_engine* uc, uint64_t address) - -> void; -auto Api_GetCommandLineW(void* sandbox, uc_engine* uc, uint64_t address) - -> void; -auto Api_GetACP(void* sandbox, uc_engine* uc, uint64_t address) -> void; -auto Api_GetCPInfo(void* sandbox, uc_engine* uc, uint64_t address) -> void; -auto Api_MultiByteToWideChar(void* sandbox, uc_engine* uc, uint64_t address) - -> void; -auto Api_SHGetKnownFolderPath(void* sandbox, uc_engine* uc, uint64_t address) - -> void; -auto Api_EncodePointer(void* sandbox, uc_engine* uc, uint64_t address) -> void; - +#include auto Api_QueryPerformanceCounter(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); @@ -89,6 +49,21 @@ void Api_GetCurrentProcessId(void* sandbox, uc_engine* uc, uint64_t address) { &context->GetTeb32()->ClientId.UniqueProcess); } } +auto Api_GetCurrentThread(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + + // GetCurrentThread 总是返回伪句柄值 -1 (0xFFFFFFFF) + uint64_t pseudo_handle = static_cast(-1); + + // 根据架构写入返回值 + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &pseudo_handle); + + printf("[*] GetCurrentThread called, returning pseudo-handle 0x%llx\n", + pseudo_handle); +} auto Api_LoadLibraryA(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); uint64_t params_address = 0; @@ -224,380 +199,6 @@ auto Api_LoadLibraryExW(void* sandbox, uc_engine* uc, uint64_t address) context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &return_address); } -void Api_GetLastError(void* sandbox, uc_engine* uc, uint64_t address) { - auto context = static_cast(sandbox); - DWORD last_error = 0; - - // 从TEB中获取LastError - if (context->GetPeInfo()->isX64) { - last_error = context->GetTeb64()->LastErrorValue; - } else { - last_error = context->GetTeb32()->LastErrorValue; - } - - printf("[*] GetLastError: LastError=0x%x\n", last_error); - uc_reg_write(uc, - context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, - &last_error); -} -auto Api_InitializeCriticalSectionAndSpinCount(void* sandbox, uc_engine* uc, - uint64_t address) -> void { - auto context = static_cast(sandbox); - uint64_t lpCriticalSection = 0; - uint32_t dwSpinCount = 0; - BOOL success = TRUE; // 默认返回成功 - - // 获取参数 - if (context->GetPeInfo()->isX64) { - // x64: rcx = lpCriticalSection, rdx = dwSpinCount - uc_reg_read(uc, UC_X86_REG_RCX, &lpCriticalSection); - uint64_t temp_spin_count = 0; - uc_reg_read(uc, UC_X86_REG_RDX, &temp_spin_count); - dwSpinCount = static_cast(temp_spin_count); - } else { - // x86: 从栈上读取参数 - uint32_t esp_address = 0; - uint32_t temp_cs = 0; - uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); - esp_address += 0x4; // 跳过返回地址 - uc_mem_read(uc, esp_address, &temp_cs, sizeof(uint32_t)); - lpCriticalSection = temp_cs; - esp_address += 0x4; - uc_mem_read(uc, esp_address, &dwSpinCount, sizeof(uint32_t)); - } - - if (lpCriticalSection != 0) { - // 初始化关键段结构 - RTL_CRITICAL_SECTION cs = {0}; - cs.LockCount = -1; // 初始未锁定状态 - cs.RecursionCount = 0; // 初始递归计数为0 - cs.SpinCount = dwSpinCount; // 设置自旋计数 - cs.OwningThread = 0; // 初始无拥有线程 - cs.LockSemaphore = 0; // 初始信号量为0 - - // 写入初始化后的结构到目标内存 - uc_mem_write(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION)); - } else { - success = FALSE; - // 设置LastError - DWORD error = ERROR_INVALID_PARAMETER; - if (context->GetPeInfo()->isX64) { - context->GetTeb64()->LastErrorValue = error; - } else { - context->GetTeb32()->LastErrorValue = error; - } - } - - printf( - "[*] InitializeCriticalSectionAndSpinCount: CS=0x%llx, SpinCount=0x%x, " - "Success=%d\n", - lpCriticalSection, dwSpinCount, success); - - uc_reg_write(uc, - context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, - &success); -} - -auto Api_InitializeCriticalSectionEx(void* sandbox, uc_engine* uc, - uint64_t address) -> void { - auto context = static_cast(sandbox); - uint64_t lpCriticalSection = 0; - uint32_t dwSpinCount = 0; - uint32_t dwFlags = 0; - BOOL success = TRUE; // 默认返回成功 - - // 获取参数 - if (context->GetPeInfo()->isX64) { - // x64: rcx = lpCriticalSection, rdx = dwSpinCount, r8 = dwFlags - uc_reg_read(uc, UC_X86_REG_RCX, &lpCriticalSection); - uint64_t temp_spin_count = 0; - uc_reg_read(uc, UC_X86_REG_RDX, &temp_spin_count); - dwSpinCount = static_cast(temp_spin_count); - uint64_t temp_flags = 0; - uc_reg_read(uc, UC_X86_REG_R8, &temp_flags); - dwFlags = static_cast(temp_flags); - } else { - // x86: 从栈上读取参数 - uint32_t esp_address = 0; - uint32_t temp_cs = 0; - uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); - esp_address += 0x4; // 跳过返回地址 - uc_mem_read(uc, esp_address, &temp_cs, sizeof(uint32_t)); - lpCriticalSection = temp_cs; - esp_address += 0x4; - uc_mem_read(uc, esp_address, &dwSpinCount, sizeof(uint32_t)); - esp_address += 0x4; - uc_mem_read(uc, esp_address, &dwFlags, sizeof(uint32_t)); - } - - if (lpCriticalSection != 0) { - // 初始化关键段结构 - RTL_CRITICAL_SECTION cs = {0}; - cs.LockCount = -1; // 初始未锁定状态 - cs.RecursionCount = 0; // 初始递归计数为0 - cs.SpinCount = dwSpinCount; // 设置自旋计数 - cs.OwningThread = 0; // 初始无拥有线程 - cs.LockSemaphore = 0; // 初始信号量为0 - - // 处理特殊标志 - // CRITICAL_SECTION_FLAG_NO_DEBUG_INFO = 0x01000000 - // CRITICAL_SECTION_FLAG_DYNAMIC_SPIN = 0x02000000 - // CRITICAL_SECTION_FLAG_STATIC_INIT = 0x04000000 - // CRITICAL_SECTION_FLAG_RESOURCE_TYPE = 0x08000000 - // CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO = 0x10000000 - - // 写入初始化后的结构到目标内存 - uc_mem_write(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION)); - } else { - success = FALSE; - // 设置LastError - DWORD error = ERROR_INVALID_PARAMETER; - if (context->GetPeInfo()->isX64) { - context->GetTeb64()->LastErrorValue = error; - } else { - context->GetTeb32()->LastErrorValue = error; - } - } - - printf( - "[*] InitializeCriticalSectionEx: CS=0x%llx, SpinCount=0x%x, " - "Flags=0x%x, " - "Success=%d\n", - lpCriticalSection, dwSpinCount, dwFlags, success); - - uc_reg_write(uc, - context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, - &success); -} - -auto Api_TlsAlloc(void* sandbox, uc_engine* uc, uint64_t address) -> void { - auto context = static_cast(sandbox); - DWORD tls_index = TLS_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; // 标记为已使用 - tls_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; // 标记为已使用 - tls_index = i; - break; - } - } - } - - if (tls_index == TLS_OUT_OF_INDEXES) { - // 设置LastError为没有可用的TLS索引 - DWORD error = ERROR_NO_MORE_ITEMS; - if (context->GetPeInfo()->isX64) { - context->GetTeb64()->LastErrorValue = error; - } else { - context->GetTeb32()->LastErrorValue = error; - } - } - - printf("[*] TlsAlloc: Allocated TLS Index=0x%x\n", tls_index); - - // 返回分配的TLS索引 - uc_reg_write(uc, - context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, - &tls_index); -} -auto Api_TlsSetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void { - auto context = static_cast(sandbox); - uint32_t dwTlsIndex = 0; - uint64_t lpTlsValue = 0; - BOOL success = FALSE; - - // 获取参数 - if (context->GetPeInfo()->isX64) { - // x64: rcx = dwTlsIndex, rdx = lpTlsValue - uint64_t temp_index; - uc_reg_read(uc, UC_X86_REG_RCX, &temp_index); - dwTlsIndex = static_cast(temp_index); - uc_reg_read(uc, UC_X86_REG_RDX, &lpTlsValue); - } 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)); - esp_address += 0x4; - uint32_t temp_value; - uc_mem_read(uc, esp_address, &temp_value, sizeof(uint32_t)); - lpTlsValue = temp_value; - } - - // 检查索引是否有效(小于64) - if (dwTlsIndex < 64) { - if (context->GetPeInfo()->isX64) { - auto teb = context->GetTeb64(); - // 检查槽是否已分配(不为nullptr) - if (teb->TlsSlots[dwTlsIndex] != (void*)0x1337ffffff) { - teb->TlsSlots[dwTlsIndex] = (void*)lpTlsValue; - success = TRUE; - } - } else { - auto teb = context->GetTeb32(); - // 检查槽是否已分配(不为0) - if (teb->TlsSlots[dwTlsIndex] != 0x1337) { - teb->TlsSlots[dwTlsIndex] = static_cast(lpTlsValue); - success = TRUE; - } - } - } - - if (!success) { - // 设置LastError - DWORD error = ERROR_INVALID_PARAMETER; - if (context->GetPeInfo()->isX64) { - context->GetTeb64()->LastErrorValue = error; - } else { - context->GetTeb32()->LastErrorValue = error; - } - } - - printf("[*] TlsSetValue: Index=0x%x, Value=0x%llx, Success=%d\n", - dwTlsIndex, lpTlsValue, success); - - uc_reg_write(uc, - context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, - &success); -} -auto Api_DeleteCriticalSection(void* sandbox, uc_engine* uc, uint64_t address) - -> void { - auto context = static_cast(sandbox); - uint64_t lpCriticalSection = 0; - - // 获取参数 - if (context->GetPeInfo()->isX64) { - // x64: rcx = lpCriticalSection - uc_reg_read(uc, UC_X86_REG_RCX, &lpCriticalSection); - } else { - // x86: 从栈上读取参数 - uint32_t esp_address = 0; - uint32_t temp_cs = 0; - uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); - esp_address += 0x4; // 跳过返回地址 - uc_mem_read(uc, esp_address, &temp_cs, sizeof(uint32_t)); - lpCriticalSection = temp_cs; - } - - if (lpCriticalSection != 0) { - // 读取现有的关键段结构 - RTL_CRITICAL_SECTION cs; - uc_mem_read(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION)); - - // 检查是否有线程仍在等待 - if (cs.LockCount >= 0) { - // 有线程正在等待,设置错误 - DWORD error = ERROR_SEM_IS_SET; - if (context->GetPeInfo()->isX64) { - context->GetTeb64()->LastErrorValue = error; - } else { - context->GetTeb32()->LastErrorValue = error; - } - } - - // 清零内存,表示删除 - memset(&cs, 0, sizeof(RTL_CRITICAL_SECTION)); - uc_mem_write(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION)); - } - - printf("[*] DeleteCriticalSection: CS=0x%llx\n", lpCriticalSection); -} - -auto Api_IsProcessorFeaturePresent(void* sandbox, uc_engine* uc, - uint64_t address) -> void { - auto context = static_cast(sandbox); - uint32_t feature_number = 0; - BOOL is_supported = FALSE; - - // 获取参数 - if (context->GetPeInfo()->isX64) { - // x64: rcx = FeatureNumber - uint64_t temp_feature; - uc_reg_read(uc, UC_X86_REG_RCX, &temp_feature); - feature_number = static_cast(temp_feature); - } 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, &feature_number, sizeof(uint32_t)); - } - - // 模拟一些常见的处理器特性 - switch (feature_number) { - case PF_FLOATING_POINT_PRECISION_ERRATA: // 0 - is_supported = FALSE; - break; - case PF_FLOATING_POINT_EMULATED: // 1 - is_supported = FALSE; - break; - case PF_COMPARE_EXCHANGE_DOUBLE: // 2 - is_supported = TRUE; - break; - case PF_MMX_INSTRUCTIONS_AVAILABLE: // 3 - is_supported = TRUE; - break; - case PF_XMMI_INSTRUCTIONS_AVAILABLE: // 6 - is_supported = TRUE; - break; - case PF_3DNOW_INSTRUCTIONS_AVAILABLE: // 7 - is_supported = FALSE; - break; - case PF_RDTSC_INSTRUCTION_AVAILABLE: // 8 - is_supported = TRUE; - break; - case PF_PAE_ENABLED: // 9 - is_supported = TRUE; - break; - case PF_XMMI64_INSTRUCTIONS_AVAILABLE: // 10 - is_supported = TRUE; - break; - case PF_SSE_DAZ_MODE_AVAILABLE: // 11 - is_supported = TRUE; - break; - case PF_NX_ENABLED: // 12 - is_supported = TRUE; - break; - case PF_SSE3_INSTRUCTIONS_AVAILABLE: // 13 - is_supported = TRUE; - break; - case PF_COMPARE_EXCHANGE128: // 14 - is_supported = TRUE; - break; - case PF_XSAVE_ENABLED: // 17 - is_supported = TRUE; - break; - case PF_ARM_VFP_32_REGISTERS_AVAILABLE: // 18 - is_supported = FALSE; - break; - default: - is_supported = FALSE; - break; - } - - printf("[*] IsProcessorFeaturePresent: Feature=0x%x, Supported=%d\n", - feature_number, is_supported); - - uc_reg_write(uc, - context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, - &is_supported); -} - auto Api_GetProcAddress(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); @@ -1038,83 +639,6 @@ auto Api_VirtualProtect(void* sandbox, uc_engine* uc, uint64_t address) &result); } -auto Api___set_app_type(void* sandbox, uc_engine* uc, uint64_t address) - -> void { - auto context = static_cast(sandbox); - int32_t appType = 0; - - // 获取参数 - if (context->GetPeInfo()->isX64) { - // x64: rcx = appType - uint64_t temp_type; - uc_reg_read(uc, UC_X86_REG_RCX, &temp_type); - appType = static_cast(temp_type); - } 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, &appType, sizeof(int32_t)); - } - - // 简单地返回0表示成功 - int32_t result = 0; - printf("[*] __set_app_type: AppType=%d\n", appType); - - uc_reg_write(uc, - context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, - &result); -} - -auto Api___p__fmode(void* sandbox, uc_engine* uc, uint64_t address) -> void { - auto sb = static_cast(sandbox); - - // 检查是否已经创建了 _fmode 变量 - static uint64_t fmode_address = 0; - static int32_t fmode_value = 0; // 默认为文本模式 (_O_TEXT) - - if (fmode_address == 0) { - // 为 _fmode 变量分配内存 - // 使用特定堆地址,与其他 API 一致 - uint64_t heap_handle = - sb->GetPeInfo()->isX64 ? HEAP_ADDRESS_64 : HEAP_ADDRESS_32; - - // 在堆上分配空间 - HeapSegment* segment = nullptr; - auto it = sb->m_heapSegments.find(heap_handle); - if (it != sb->m_heapSegments.end()) { - segment = it->second; - } else { - // 创建新的堆段 - segment = sb->CreateHeapSegment(heap_handle, 0x10000); - sb->m_heapSegments[heap_handle] = segment; - } - - if (segment) { - fmode_address = sb->AllocateFromSegment(segment, sizeof(int32_t)); - if (fmode_address) { - // 初始化 _fmode 为文本模式 - uc_mem_write(uc, fmode_address, &fmode_value, sizeof(int32_t)); - printf( - "[*] __p__fmode: Allocated _fmode at 0x%llx with value " - "%d\n", - fmode_address, fmode_value); - } - } - } - - // 返回 _fmode 变量的地址 - printf("[*] __p__fmode: Returning address 0x%llx\n", fmode_address); - - // 设置返回值 - if (sb->GetPeInfo()->isX64) { - uc_reg_write(uc, UC_X86_REG_RAX, &fmode_address); - } else { - uint32_t eax = static_cast(fmode_address); - uc_reg_write(uc, UC_X86_REG_EAX, &eax); - } -} - auto Api_Sleep(void* sandbox, uc_engine* uc, uint64_t address) -> void { auto context = static_cast(sandbox); uint64_t milliseconds; @@ -1134,242 +658,7 @@ auto Api_Sleep(void* sandbox, uc_engine* uc, uint64_t address) -> void { // 打印日志 printf("Sleep API called with %u milliseconds\n", milliseconds); } -// 内部实现函数,处理实际的模块句柄获取逻辑 -auto GetModuleHandleInternal(void* sandbox, const std::wstring& moduleName) - -> HMODULE { - auto* sb = static_cast(sandbox); - // 如果模块名为空,返回当前进程的基址 - if (moduleName.empty()) { - return reinterpret_cast(sb->GetPeInfo()->RecImageBase); - } - - // 在已加载的模块中查找 - for (const auto& module : sb->GetModuleList()) { - std::string currentModuleNameA = module->name; - std::wstring currentModuleName = - std::wstring(currentModuleNameA.begin(), currentModuleNameA.end()); - if (_wcsicmp(currentModuleName.c_str(), moduleName.c_str()) == 0) { - return reinterpret_cast(module->base); - } - } - - return nullptr; -} - -// GetModuleHandleA的实现 -auto Api_GetModuleHandleA(void* sandbox, uc_engine* uc, uint64_t address) - -> void { - auto* sb = static_cast(sandbox); - uint64_t esp = 0, rsp = 0; - HMODULE result = nullptr; - - if (sb->GetPeInfo()->isX64) { - // 获取第一个参数 (rcx) - uint64_t moduleNamePtr; - uc_reg_read(uc, UC_X86_REG_RCX, &moduleNamePtr); - uc_reg_read(uc, UC_X86_REG_RSP, &rsp); - - std::string moduleName; - if (moduleNamePtr != 0) { - // 读取ANSI字符串 - char ch; - size_t i = 0; - do { - if (uc_mem_read(uc, moduleNamePtr + i, &ch, 1) != UC_ERR_OK) { - break; - } - if (ch == 0) break; - moduleName += ch; - i++; - } while (i < MAX_PATH); - } - - // 转换为宽字符 - std::wstring wModuleName; - if (!moduleName.empty()) { - wModuleName = std::wstring(moduleName.begin(), moduleName.end()); - } - - // 获取模块句柄 - result = GetModuleHandleInternal(sandbox, wModuleName); - - // 设置返回值 - uc_reg_write(uc, UC_X86_REG_RAX, &result); - - } else { - // 32位实现 - uc_reg_read(uc, UC_X86_REG_ESP, &esp); - uint32_t moduleNamePtr; - uc_mem_read(uc, esp + 4, &moduleNamePtr, sizeof(moduleNamePtr)); - - std::string moduleName; - if (moduleNamePtr != 0) { - // 读取ANSI字符串 - char ch; - size_t i = 0; - do { - if (uc_mem_read(uc, moduleNamePtr + i, &ch, 1) != UC_ERR_OK) { - break; - } - if (ch == 0) break; - moduleName += ch; - i++; - } while (i < MAX_PATH); - } - - // 转换为宽字符 - std::wstring wModuleName; - if (!moduleName.empty()) { - wModuleName = std::wstring(moduleName.begin(), moduleName.end()); - } - - // 获取模块句柄 - result = GetModuleHandleInternal(sandbox, wModuleName); - - // 设置返回值 - uint32_t result32 = reinterpret_cast(result); - uc_reg_write(uc, UC_X86_REG_EAX, &result32); - } - - // 设置错误码 - DWORD error = result ? 0 : ERROR_MOD_NOT_FOUND; - if (sb->GetPeInfo()->isX64) { - sb->GetTeb64()->LastErrorValue = error; - } else { - sb->GetTeb32()->LastErrorValue = error; - } -} - -// GetModuleHandleW的实现 -auto Api_GetModuleHandleW(void* sandbox, uc_engine* uc, uint64_t address) - -> void { - auto* sb = static_cast(sandbox); - uint64_t esp = 0, rsp = 0; - HMODULE result = nullptr; - - if (sb->GetPeInfo()->isX64) { - // 获取第一个参数 (rcx) - uint64_t moduleNamePtr; - uc_reg_read(uc, UC_X86_REG_RCX, &moduleNamePtr); - uc_reg_read(uc, UC_X86_REG_RSP, &rsp); - - std::wstring moduleName; - if (moduleNamePtr != 0) { - // 读取宽字符串 - wchar_t ch; - size_t i = 0; - do { - if (uc_mem_read(uc, moduleNamePtr + (i * 2), &ch, 2) != - UC_ERR_OK) { - break; - } - if (ch == 0) break; - moduleName += ch; - i++; - } while (i < MAX_PATH); - } - - // 获取模块句柄 - result = GetModuleHandleInternal(sandbox, moduleName); - - // 设置返回值 - uc_reg_write(uc, UC_X86_REG_RAX, &result); - - } else { - // 32位实现 - uc_reg_read(uc, UC_X86_REG_ESP, &esp); - uint32_t moduleNamePtr; - uc_mem_read(uc, esp + 4, &moduleNamePtr, sizeof(moduleNamePtr)); - - std::wstring moduleName; - if (moduleNamePtr != 0) { - // 读取宽字符串 - wchar_t ch; - size_t i = 0; - do { - if (uc_mem_read(uc, moduleNamePtr + (i * 2), &ch, 2) != - UC_ERR_OK) { - break; - } - if (ch == 0) break; - moduleName += ch; - i++; - } while (i < MAX_PATH); - } - - // 获取模块句柄 - result = GetModuleHandleInternal(sandbox, moduleName); - - // 设置返回值 - uint32_t result32 = reinterpret_cast(result); - uc_reg_write(uc, UC_X86_REG_EAX, &result32); - } - - // 设置错误码 - DWORD error = result ? 0 : ERROR_MOD_NOT_FOUND; - if (sb->GetPeInfo()->isX64) { - sb->GetTeb64()->LastErrorValue = error; - } else { - sb->GetTeb32()->LastErrorValue = error; - } -} -auto Api_VirtualQuery(void* sandbox, uc_engine* uc, uint64_t address) -> void { - auto* context = static_cast(sandbox); - uint64_t lpAddress = 0; - uint64_t lpBuffer = 0; - uint32_t dwLength = 0; - - // 获取参数 - if (context->GetPeInfo()->isX64) { - // 64位参数获取 - uc_reg_read(uc, UC_X86_REG_RCX, &lpAddress); - uc_reg_read(uc, UC_X86_REG_RDX, &lpBuffer); - uint64_t temp_length = 0; - uc_reg_read(uc, UC_X86_REG_R8, &temp_length); - dwLength = static_cast(temp_length); - } else { - // 32位参数获取 - uint32_t esp = 0; - uc_reg_read(uc, UC_X86_REG_ESP, &esp); - esp += 0x4; // 跳过返回地址 - - uint32_t temp_address = 0; - uint32_t temp_buffer = 0; - uc_mem_read(uc, esp, &temp_address, sizeof(uint32_t)); - uc_mem_read(uc, esp + 0x4, &temp_buffer, sizeof(uint32_t)); - uc_mem_read(uc, esp + 0x8, &dwLength, sizeof(uint32_t)); - - lpAddress = temp_address; - lpBuffer = temp_buffer; - } - - // 构造MEMORY_BASIC_INFORMATION结构 - MEMORY_BASIC_INFORMATION mbi = {}; - mbi.BaseAddress = - reinterpret_cast(static_cast(lpAddress)); - mbi.AllocationBase = mbi.BaseAddress; - mbi.AllocationProtect = PAGE_EXECUTE_READWRITE; // 默认保护属性 - mbi.RegionSize = 0x1000; // 默认页大小 - mbi.State = MEM_COMMIT; - mbi.Protect = PAGE_EXECUTE_READWRITE; - mbi.Type = MEM_PRIVATE; - - // 写入查询结果 - uint64_t return_value = 0; - if (lpBuffer != 0 && dwLength >= sizeof(MEMORY_BASIC_INFORMATION)) { - uc_mem_write(uc, lpBuffer, &mbi, sizeof(MEMORY_BASIC_INFORMATION)); - return_value = sizeof(MEMORY_BASIC_INFORMATION); - } - - // 设置返回值 - if (context->GetPeInfo()->isX64) { - uc_reg_write(uc, UC_X86_REG_RAX, &return_value); - } else { - uint32_t return_value_32 = static_cast(return_value); - uc_reg_write(uc, UC_X86_REG_EAX, &return_value_32); - } -} auto Sandbox::InitApiHooks() -> void { auto FakeApi_GetSystemTimeAsFileTime = _fakeApi{.func = Api_GetSystemTimeAsFileTime, .paramCount = 1}; @@ -1377,6 +666,8 @@ auto Sandbox::InitApiHooks() -> void { _fakeApi{.func = Api_GetCurrentThreadId, .paramCount = 0}; auto FakeApi_GetCurrentProcessId = _fakeApi{.func = Api_GetCurrentProcessId, .paramCount = 0}; + auto FakeApi_GetCurrentThread = + _fakeApi{.func = Api_GetCurrentThread, .paramCount = 0}; auto FakeApi_QueryPerformanceCounter = _fakeApi{.func = Api_QueryPerformanceCounter, .paramCount = 1}; auto FakeApi_LoadLibraryA = @@ -1468,6 +759,48 @@ auto Sandbox::InitApiHooks() -> void { _fakeApi{.func = Api_GetModuleHandleW, .paramCount = 1}; auto FakeApi_VirtualQuery = _fakeApi{.func = Api_VirtualQuery, .paramCount = 3}; + auto FakeApi_Process32FirstW = + _fakeApi{.func = Api_Process32FirstW, .paramCount = 2}; + auto FakeApi_CreateToolhelp32Snapshot = + _fakeApi{.func = Api_CreateToolhelp32Snapshot, .paramCount = 2}; + auto FakeApi_Process32NextW = + _fakeApi{.func = Api_Process32NextW, .paramCount = 2}; + auto FakeApi_CloseHandle = + _fakeApi{.func = Api_CloseHandle, .paramCount = 1}; + auto FakeApi_RtlFormatCurrentUserKeyPath = + _fakeApi{.func = Api_RtlFormatCurrentUserKeyPath, .paramCount = 1}; + auto FakeApi_FlsSetValue = + _fakeApi{.func = Api_FlsSetValue, .paramCount = 2}; + auto FakeApi_CreatePipe = _fakeApi{.func = Api_CreatePipe, .paramCount = 4}; + auto FakeApi_CreateProcessA = + _fakeApi{.func = Api_CreateProcessA, .paramCount = 10}; + auto FakeApi_ReadFile = _fakeApi{.func = Api_ReadFile, .paramCount = 5}; + auto FakeApi_WlanOpenHandle = + _fakeApi{.func = Api_WlanOpenHandle, .paramCount = 4}; + auto FakeApi_WlanEnumInterfaces = + _fakeApi{.func = Api_WlanEnumInterfaces, .paramCount = 3}; + auto FakeApi_WlanGetProfileList = + _fakeApi{.func = Api_WlanGetProfileList, .paramCount = 4}; + auto FakeApi_WlanFreeMemory = + _fakeApi{.func = Api_WlanFreeMemory, .paramCount = 1}; + auto FakeApi_WlanCloseHandle = + _fakeApi{.func = Api_WlanCloseHandle, .paramCount = 2}; + auto FakeApi_GetCurrentProcess = + _fakeApi{.func = Api_GetCurrentProcess, .paramCount = 0}; + auto FakeApi_OpenProcessToken = + _fakeApi{.func = Api_OpenProcessToken, .paramCount = 3}; + auto FakeApi_GetTokenInformation = + _fakeApi{.func = Api_GetTokenInformation, .paramCount = 5}; + // 添加WFP相关API + auto FakeApi_FwpmEngineOpen0 = + _fakeApi{.func = Api_FwpmEngineOpen0, .paramCount = 5}; + auto FakeApi_FwpmProviderAdd0 = + _fakeApi{.func = Api_FwpmProviderAdd0, .paramCount = 3}; + auto FakeApi_FwpmFilterAdd0 = + _fakeApi{.func = Api_FwpmFilterAdd0, .paramCount = 4}; + auto FakeApi_FwpmEngineClose0 = + _fakeApi{.func = Api_FwpmEngineClose0, .paramCount = 1}; + api_map = { {"GetSystemTimeAsFileTime", std::make_shared<_fakeApi>(FakeApi_GetSystemTimeAsFileTime)}, @@ -1475,6 +808,8 @@ auto Sandbox::InitApiHooks() -> void { std::make_shared<_fakeApi>(FakeApi_GetCurrentThreadId)}, {"GetCurrentProcessId", std::make_shared<_fakeApi>(FakeApi_GetCurrentProcessId)}, + {"GetCurrentThread", + std::make_shared<_fakeApi>(FakeApi_GetCurrentThread)}, {"QueryPerformanceCounter", std::make_shared<_fakeApi>(FakeApi_QueryPerformanceCounter)}, {"LoadLibraryA", std::make_shared<_fakeApi>(FakeApi_LoadLibraryA)}, @@ -1550,6 +885,40 @@ auto Sandbox::InitApiHooks() -> void { {"GetModuleHandleW", std::make_shared<_fakeApi>(FakeApi_GetModuleHandleW)}, {"VirtualQuery", std::make_shared<_fakeApi>(FakeApi_VirtualQuery)}, + {"Process32FirstW", + std::make_shared<_fakeApi>(FakeApi_Process32FirstW)}, + {"CreateToolhelp32Snapshot", + std::make_shared<_fakeApi>(FakeApi_CreateToolhelp32Snapshot)}, + {"Process32NextW", std::make_shared<_fakeApi>(FakeApi_Process32NextW)}, + {"CloseHandle", std::make_shared<_fakeApi>(FakeApi_CloseHandle)}, + {"RtlFormatCurrentUserKeyPath", + std::make_shared<_fakeApi>(FakeApi_RtlFormatCurrentUserKeyPath)}, + {"FlsSetValue", std::make_shared<_fakeApi>(FakeApi_FlsSetValue)}, + {"CreatePipe", std::make_shared<_fakeApi>(FakeApi_CreatePipe)}, + {"CreateProcessA", std::make_shared<_fakeApi>(FakeApi_CreateProcessA)}, + {"ReadFile", std::make_shared<_fakeApi>(FakeApi_ReadFile)}, + {"WlanOpenHandle", std::make_shared<_fakeApi>(FakeApi_WlanOpenHandle)}, + {"WlanEnumInterfaces", + std::make_shared<_fakeApi>(FakeApi_WlanEnumInterfaces)}, + {"WlanGetProfileList", + std::make_shared<_fakeApi>(FakeApi_WlanGetProfileList)}, + {"WlanFreeMemory", std::make_shared<_fakeApi>(FakeApi_WlanFreeMemory)}, + {"WlanCloseHandle", + std::make_shared<_fakeApi>(FakeApi_WlanCloseHandle)}, + {"GetCurrentProcess", + std::make_shared<_fakeApi>(FakeApi_GetCurrentProcess)}, + {"OpenProcessToken", + std::make_shared<_fakeApi>(FakeApi_OpenProcessToken)}, + {"GetTokenInformation", + std::make_shared<_fakeApi>(FakeApi_GetTokenInformation)}, + // 添加WFP相关API映射 + {"FwpmEngineOpen0", + std::make_shared<_fakeApi>(FakeApi_FwpmEngineOpen0)}, + {"FwpmProviderAdd0", + std::make_shared<_fakeApi>(FakeApi_FwpmProviderAdd0)}, + {"FwpmFilterAdd0", std::make_shared<_fakeApi>(FakeApi_FwpmFilterAdd0)}, + {"FwpmEngineClose0", + std::make_shared<_fakeApi>(FakeApi_FwpmEngineClose0)}, }; } auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip, @@ -1603,4 +972,4 @@ auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip, printf("ApiName: %s not found\n", ApiName.c_str()); uc_emu_stop(uc); return; -} \ No newline at end of file +} diff --git a/ai_anti_malware/sandbox_api_file.cpp b/ai_anti_malware/sandbox_api_file.cpp new file mode 100644 index 0000000..e20bfc5 --- /dev/null +++ b/ai_anti_malware/sandbox_api_file.cpp @@ -0,0 +1,180 @@ +#include "sandbox.h" +#include "sandbox_callbacks.h" +#include "sandbox_api_winhttp.h" +#include +auto Api_ReadFile(void* sandbox, uc_engine* uc, uint64_t address) -> 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; + } + + // 检查句柄是否为之前CreatePipe创建的读管道 + bool success = false; + uint32_t bytesRead = 0; + + // 检查是否为之前CreatePipe创建的读管道句柄 (0x1338) + if (hFile == 0x1338) { + // 模拟管道数据读取 - 这里我们可以根据之前的CreateProcessA来生成数据 + // 生成一些模拟的ping命令输出数据 + std::string pingOutput = + "Reply from 127.0.0.1: bytes=32 time<1ms TTL=45\r\n" + "Reply from 127.0.0.1: bytes=32 time<1ms TTL=45\r\n" + "Reply from 127.0.0.1: bytes=32 time<1ms TTL=45\r\n" + "Reply from 127.0.0.1: bytes=32 time<1ms TTL=45\r\n\r\n" + "Ping statistics for 127.0.0.1:\r\n" + " Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),\r\n" + "Approximate round trip times in milli-seconds:\r\n" + " Minimum = 0ms, Maximum = 0ms, Average = 0ms\r\n"; + + // 确保不超过缓冲区大小 + bytesRead = min(static_cast(pingOutput.length()), + nNumberOfBytesToRead); + + // 写入数据到缓冲区 + if (lpBuffer != 0 && bytesRead > 0) { + uc_mem_write(uc, lpBuffer, pingOutput.c_str(), bytesRead); + success = true; + } + } + + // 写入实际读取的字节数 + if (lpNumberOfBytesRead != 0) { + if (context->GetPeInfo()->isX64) { + uc_mem_write(uc, lpNumberOfBytesRead, &bytesRead, sizeof(uint32_t)); + } else { + uc_mem_write(uc, lpNumberOfBytesRead, &bytesRead, sizeof(uint32_t)); + } + } + + printf( + "[*] ReadFile: Handle=0x%llx, Buffer=0x%llx, BytesToRead=%u, " + "BytesRead=%u, Success=%d\n", + hFile, lpBuffer, nNumberOfBytesToRead, bytesRead, success); + + // 设置返回值 + uint64_t result = success ? 1 : 0; + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &result); + + // 如果失败,设置错误码 + if (!success) { + DWORD error = ERROR_INVALID_HANDLE; + if (context->GetPeInfo()->isX64) { + context->GetTeb64()->LastErrorValue = error; + } else { + context->GetTeb32()->LastErrorValue = error; + } + } +} +auto Api_CreatePipe(void* sandbox, uc_engine* uc, uint64_t address) -> void { + auto context = static_cast(sandbox); + uint64_t hReadPipe = 0; + uint64_t hWritePipe = 0; + uint64_t lpPipeAttributes = 0; + uint32_t nSize = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = hReadPipe, rdx = hWritePipe, r8 = lpPipeAttributes, r9 = + // nSize + uc_reg_read(uc, UC_X86_REG_RCX, &hReadPipe); + uc_reg_read(uc, UC_X86_REG_RDX, &hWritePipe); + uc_reg_read(uc, UC_X86_REG_R8, &lpPipeAttributes); + uint64_t temp_size; + uc_reg_read(uc, UC_X86_REG_R9, &temp_size); + nSize = static_cast(temp_size); + } else { + // x86: 从栈上读取参数 + uint32_t esp_address = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); + esp_address += 0x4; // 跳过返回地址 + + uint32_t temp_read_pipe; + uint32_t temp_write_pipe; + uint32_t temp_pipe_attributes; + + uc_mem_read(uc, esp_address, &temp_read_pipe, sizeof(uint32_t)); + uc_mem_read(uc, esp_address + 0x4, &temp_write_pipe, sizeof(uint32_t)); + uc_mem_read(uc, esp_address + 0x8, &temp_pipe_attributes, + sizeof(uint32_t)); + uc_mem_read(uc, esp_address + 0xC, &nSize, sizeof(uint32_t)); + + hReadPipe = temp_read_pipe; + hWritePipe = temp_write_pipe; + lpPipeAttributes = temp_pipe_attributes; + } + + // 创建模拟的管道句柄 + uint64_t read_handle = 0x1338; // 使用特殊值作为读取句柄 + uint64_t write_handle = 0x1339; // 使用特殊值作为写入句柄 + + // 生成唯一的管道名称 + char pipeName[MAX_PATH]; + DWORD processId = + context->GetPeInfo()->isX64 + ? static_cast(context->GetTeb64()->ClientId.UniqueProcess) + : static_cast(context->GetTeb32()->ClientId.UniqueProcess); + + snprintf(pipeName, sizeof(pipeName), + "\\\\.\\pipe\\sandbox_pipe_%lu_%llx_%llx", processId, read_handle, + write_handle); + + // 写入句柄到输出参数 + if (context->GetPeInfo()->isX64) { + uc_mem_write(uc, hReadPipe, &read_handle, sizeof(uint64_t)); + uc_mem_write(uc, hWritePipe, &write_handle, sizeof(uint64_t)); + } else { + uint32_t read_handle_32 = static_cast(read_handle); + uint32_t write_handle_32 = static_cast(write_handle); + uc_mem_write(uc, hReadPipe, &read_handle_32, sizeof(uint32_t)); + uc_mem_write(uc, hWritePipe, &write_handle_32, sizeof(uint32_t)); + } + + // 设置返回值为TRUE + uint64_t result = 1; + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &result); + + printf( + "[*] CreatePipe: Name=%s, ReadHandle=0x%llx, WriteHandle=0x%llx, " + "Size=%u\n", + pipeName, read_handle, write_handle, nSize); +} \ No newline at end of file diff --git a/ai_anti_malware/sandbox_api_process.cpp b/ai_anti_malware/sandbox_api_process.cpp new file mode 100644 index 0000000..034a6f5 --- /dev/null +++ b/ai_anti_malware/sandbox_api_process.cpp @@ -0,0 +1,784 @@ +#include "sandbox.h" +#include "sandbox_callbacks.h" +#include "sandbox_api_winhttp.h" +#include + +// 内部实现函数,处理实际的模块句柄获取逻辑 +auto GetModuleHandleInternal(void* sandbox, const std::wstring& moduleName) + -> HMODULE { + auto* sb = static_cast(sandbox); + + // 如果模块名为空,返回当前进程的基址 + if (moduleName.empty()) { + return reinterpret_cast(sb->GetPeInfo()->RecImageBase); + } + + // 在已加载的模块中查找 + for (const auto& module : sb->GetModuleList()) { + std::string currentModuleNameA = module->name; + std::wstring currentModuleName = + std::wstring(currentModuleNameA.begin(), currentModuleNameA.end()); + if (_wcsicmp(currentModuleName.c_str(), moduleName.c_str()) == 0) { + return reinterpret_cast(module->base); + } + } + + return nullptr; +} + +// GetModuleHandleA的实现 +auto Api_GetModuleHandleA(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto* sb = static_cast(sandbox); + uint64_t esp = 0, rsp = 0; + HMODULE result = nullptr; + + if (sb->GetPeInfo()->isX64) { + // 获取第一个参数 (rcx) + uint64_t moduleNamePtr; + uc_reg_read(uc, UC_X86_REG_RCX, &moduleNamePtr); + uc_reg_read(uc, UC_X86_REG_RSP, &rsp); + + std::string moduleName; + if (moduleNamePtr != 0) { + // 读取ANSI字符串 + char ch; + size_t i = 0; + do { + if (uc_mem_read(uc, moduleNamePtr + i, &ch, 1) != UC_ERR_OK) { + break; + } + if (ch == 0) break; + moduleName += ch; + i++; + } while (i < MAX_PATH); + } + + // 转换为宽字符 + std::wstring wModuleName; + if (!moduleName.empty()) { + wModuleName = std::wstring(moduleName.begin(), moduleName.end()); + } + + // 获取模块句柄 + result = GetModuleHandleInternal(sandbox, wModuleName); + + // 设置返回值 + uc_reg_write(uc, UC_X86_REG_RAX, &result); + + } else { + // 32位实现 + uc_reg_read(uc, UC_X86_REG_ESP, &esp); + uint32_t moduleNamePtr; + uc_mem_read(uc, esp + 4, &moduleNamePtr, sizeof(moduleNamePtr)); + + std::string moduleName; + if (moduleNamePtr != 0) { + // 读取ANSI字符串 + char ch; + size_t i = 0; + do { + if (uc_mem_read(uc, moduleNamePtr + i, &ch, 1) != UC_ERR_OK) { + break; + } + if (ch == 0) break; + moduleName += ch; + i++; + } while (i < MAX_PATH); + } + + // 转换为宽字符 + std::wstring wModuleName; + if (!moduleName.empty()) { + wModuleName = std::wstring(moduleName.begin(), moduleName.end()); + } + + // 获取模块句柄 + result = GetModuleHandleInternal(sandbox, wModuleName); + + // 设置返回值 + uint32_t result32 = reinterpret_cast(result); + uc_reg_write(uc, UC_X86_REG_EAX, &result32); + } + + // 设置错误码 + DWORD error = result ? 0 : ERROR_MOD_NOT_FOUND; + if (sb->GetPeInfo()->isX64) { + sb->GetTeb64()->LastErrorValue = error; + } else { + sb->GetTeb32()->LastErrorValue = error; + } +} + +// GetModuleHandleW的实现 +auto Api_GetModuleHandleW(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto* sb = static_cast(sandbox); + uint64_t esp = 0, rsp = 0; + HMODULE result = nullptr; + + if (sb->GetPeInfo()->isX64) { + // 获取第一个参数 (rcx) + uint64_t moduleNamePtr; + uc_reg_read(uc, UC_X86_REG_RCX, &moduleNamePtr); + uc_reg_read(uc, UC_X86_REG_RSP, &rsp); + + std::wstring moduleName; + if (moduleNamePtr != 0) { + // 读取宽字符串 + wchar_t ch; + size_t i = 0; + do { + if (uc_mem_read(uc, moduleNamePtr + (i * 2), &ch, 2) != + UC_ERR_OK) { + break; + } + if (ch == 0) break; + moduleName += ch; + i++; + } while (i < MAX_PATH); + } + + // 获取模块句柄 + result = GetModuleHandleInternal(sandbox, moduleName); + + // 设置返回值 + uc_reg_write(uc, UC_X86_REG_RAX, &result); + + } else { + // 32位实现 + uc_reg_read(uc, UC_X86_REG_ESP, &esp); + uint32_t moduleNamePtr; + uc_mem_read(uc, esp + 4, &moduleNamePtr, sizeof(moduleNamePtr)); + + std::wstring moduleName; + if (moduleNamePtr != 0) { + // 读取宽字符串 + wchar_t ch; + size_t i = 0; + do { + if (uc_mem_read(uc, moduleNamePtr + (i * 2), &ch, 2) != + UC_ERR_OK) { + break; + } + if (ch == 0) break; + moduleName += ch; + i++; + } while (i < MAX_PATH); + } + + // 获取模块句柄 + result = GetModuleHandleInternal(sandbox, moduleName); + + // 设置返回值 + uint32_t result32 = reinterpret_cast(result); + uc_reg_write(uc, UC_X86_REG_EAX, &result32); + } + + // 设置错误码 + DWORD error = result ? 0 : ERROR_MOD_NOT_FOUND; + if (sb->GetPeInfo()->isX64) { + sb->GetTeb64()->LastErrorValue = error; + } else { + sb->GetTeb32()->LastErrorValue = error; + } +} +auto Api_VirtualQuery(void* sandbox, uc_engine* uc, uint64_t address) -> void { + auto* context = static_cast(sandbox); + uint64_t lpAddress = 0; + uint64_t lpBuffer = 0; + uint32_t dwLength = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // 64位参数获取 + uc_reg_read(uc, UC_X86_REG_RCX, &lpAddress); + uc_reg_read(uc, UC_X86_REG_RDX, &lpBuffer); + uint64_t temp_length = 0; + uc_reg_read(uc, UC_X86_REG_R8, &temp_length); + dwLength = static_cast(temp_length); + } else { + // 32位参数获取 + uint32_t esp = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &esp); + esp += 0x4; // 跳过返回地址 + + uint32_t temp_address = 0; + uint32_t temp_buffer = 0; + uc_mem_read(uc, esp, &temp_address, sizeof(uint32_t)); + uc_mem_read(uc, esp + 0x4, &temp_buffer, sizeof(uint32_t)); + uc_mem_read(uc, esp + 0x8, &dwLength, sizeof(uint32_t)); + + lpAddress = temp_address; + lpBuffer = temp_buffer; + } + + // 构造MEMORY_BASIC_INFORMATION结构 + MEMORY_BASIC_INFORMATION mbi = {}; + mbi.BaseAddress = + reinterpret_cast(static_cast(lpAddress)); + mbi.AllocationBase = mbi.BaseAddress; + mbi.AllocationProtect = PAGE_EXECUTE_READWRITE; // 默认保护属性 + mbi.RegionSize = 0x1000; // 默认页大小 + mbi.State = MEM_COMMIT; + mbi.Protect = PAGE_EXECUTE_READWRITE; + mbi.Type = MEM_PRIVATE; + + // 写入查询结果 + uint64_t return_value = 0; + if (lpBuffer != 0 && dwLength >= sizeof(MEMORY_BASIC_INFORMATION)) { + uc_mem_write(uc, lpBuffer, &mbi, sizeof(MEMORY_BASIC_INFORMATION)); + return_value = sizeof(MEMORY_BASIC_INFORMATION); + } + + // 设置返回值 + if (context->GetPeInfo()->isX64) { + uc_reg_write(uc, UC_X86_REG_RAX, &return_value); + } else { + uint32_t return_value_32 = static_cast(return_value); + uc_reg_write(uc, UC_X86_REG_EAX, &return_value_32); + } +} + +auto Api_Process32FirstW(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto* context = static_cast(sandbox); + uint64_t hSnapshot = 0; + uint64_t lppe = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = hSnapshot, rdx = lppe (LPPROCESSENTRY32W) + uc_reg_read(uc, UC_X86_REG_RCX, &hSnapshot); + uc_reg_read(uc, UC_X86_REG_RDX, &lppe); + } else { + // x86: 从栈上读取参数 + uint32_t esp = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &esp); + esp += 0x4; // 跳过返回地址 + uint32_t temp_handle; + uint32_t temp_lppe; + uc_mem_read(uc, esp, &temp_handle, sizeof(uint32_t)); + uc_mem_read(uc, esp + 0x4, &temp_lppe, sizeof(uint32_t)); + hSnapshot = temp_handle; + lppe = temp_lppe; + } + + // 验证句柄 + bool success = false; + if (hSnapshot == 0x1337) { // 我们在CreateToolhelp32Snapshot中使用的魔数 + // 读取结构体大小 + 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; // 正常优先级 + + // 设置进程名 + 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; + } + } + } + } + + printf("[*] Process32FirstW: Handle=0x%llx, Buffer=0x%llx, Success=%d\n", + hSnapshot, lppe, success); + + // 设置返回值 + uint64_t result = success ? 1 : 0; + if (context->GetPeInfo()->isX64) { + uc_reg_write(uc, UC_X86_REG_RAX, &result); + } else { + uint32_t result32 = static_cast(result); + uc_reg_write(uc, UC_X86_REG_EAX, &result32); + } + + // 设置错误码 + DWORD error = success ? 0 : ERROR_NO_MORE_FILES; + if (context->GetPeInfo()->isX64) { + context->GetTeb64()->LastErrorValue = error; + } else { + context->GetTeb32()->LastErrorValue = error; + } +} +auto Api_CreateToolhelp32Snapshot(void* sandbox, uc_engine* uc, + uint64_t address) -> void { + auto* context = static_cast(sandbox); + uint32_t dwFlags = 0; + uint32_t th32ProcessID = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = dwFlags, rdx = th32ProcessID + uint64_t temp_flags; + uint64_t temp_pid; + uc_reg_read(uc, UC_X86_REG_RCX, &temp_flags); + uc_reg_read(uc, UC_X86_REG_RDX, &temp_pid); + dwFlags = static_cast(temp_flags); + th32ProcessID = static_cast(temp_pid); + } else { + // x86: 从栈上读取参数 + uint32_t esp = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &esp); + esp += 0x4; // 跳过返回地址 + uc_mem_read(uc, esp, &dwFlags, sizeof(uint32_t)); + uc_mem_read(uc, esp + 0x4, &th32ProcessID, sizeof(uint32_t)); + } + + // 创建一个假的句柄值 + uint64_t handle = 0x1337; + + // 如果请求进程列表快照,初始化进程枚举状态 + if (dwFlags & TH32CS_SNAPPROCESS) { + // 初始化进程枚举状态为-1,这样Process32First会返回第一个进程 + context->process_enum_state[handle] = -1; + + // 清除错误码 + if (context->GetPeInfo()->isX64) { + context->GetTeb64()->LastErrorValue = 0; + } else { + context->GetTeb32()->LastErrorValue = 0; + } + } + + printf( + "[*] CreateToolhelp32Snapshot: Flags=0x%x, ProcessID=0x%x, " + "Handle=0x%llx\n", + dwFlags, th32ProcessID, handle); + + // 返回句柄 + if (context->GetPeInfo()->isX64) { + uc_reg_write(uc, UC_X86_REG_RAX, &handle); + } else { + uint32_t handle32 = static_cast(handle); + uc_reg_write(uc, UC_X86_REG_EAX, &handle32); + } +} +auto Api_Process32NextW(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto* context = static_cast(sandbox); + uint64_t hSnapshot = 0; + uint64_t lppe = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = hSnapshot, rdx = lppe (LPPROCESSENTRY32W) + uc_reg_read(uc, UC_X86_REG_RCX, &hSnapshot); + uc_reg_read(uc, UC_X86_REG_RDX, &lppe); + } else { + // x86: 从栈上读取参数 + uint32_t esp = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &esp); + esp += 0x4; // 跳过返回地址 + uint32_t temp_handle; + uint32_t temp_lppe; + uc_mem_read(uc, esp, &temp_handle, sizeof(uint32_t)); + uc_mem_read(uc, esp + 0x4, &temp_lppe, sizeof(uint32_t)); + hSnapshot = temp_handle; + lppe = temp_lppe; + } + + // 验证句柄 + bool success = false; + if (hSnapshot == 0x1337) { // 我们在CreateToolhelp32Snapshot中使用的魔数 + // 读取结构体大小 + 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++; // 移动到下一个进程 + } + + // 定义进程列表 + 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]); + + // 检查是否还有更多进程 + 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; + } + } + } + } + } + + printf("[*] Process32NextW: Handle=0x%llx, Buffer=0x%llx, Success=%d\n", + hSnapshot, lppe, success); + + // 设置返回值 + uint64_t result = success ? 1 : 0; + if (context->GetPeInfo()->isX64) { + uc_reg_write(uc, UC_X86_REG_RAX, &result); + } else { + uint32_t result32 = static_cast(result); + uc_reg_write(uc, UC_X86_REG_EAX, &result32); + } + + // 设置错误码 + DWORD error = success ? 0 : ERROR_NO_MORE_FILES; + if (context->GetPeInfo()->isX64) { + context->GetTeb64()->LastErrorValue = error; + } else { + context->GetTeb32()->LastErrorValue = error; + } +} + +auto Api_CreateProcessA(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + uint64_t lpApplicationName = 0; + uint64_t lpCommandLine = 0; + uint64_t lpProcessInformation = 0; + uint64_t lpStartupInfo = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = lpApplicationName, rdx = lpCommandLine + uc_reg_read(uc, UC_X86_REG_RCX, &lpApplicationName); + uc_reg_read(uc, UC_X86_REG_RDX, &lpCommandLine); + // 从栈上获取 PROCESS_INFORMATION 和 STARTUPINFO + uint64_t rsp; + uc_reg_read(uc, UC_X86_REG_RSP, &rsp); + rsp += 0x28; // 跳过前4个参数的影子空间 + uc_mem_read(uc, rsp + 0x20, &lpProcessInformation, sizeof(uint64_t)); + uc_mem_read(uc, rsp + 0x18, &lpStartupInfo, sizeof(uint64_t)); + + printf( + "[*] CreateProcessA Debug (x64): AppNameAddr=0x%llx, " + "CmdLineAddr=0x%llx\n", + lpApplicationName, lpCommandLine); + } else { + // x86: 从栈上读取参数 + uint32_t esp; + uc_reg_read(uc, UC_X86_REG_ESP, &esp); + esp += 0x4; // 跳过返回地址 + uint32_t temp_app_name, temp_cmd_line, temp_proc_info, + temp_startup_info; + uc_mem_read(uc, esp, &temp_app_name, sizeof(uint32_t)); + uc_mem_read(uc, esp + 0x4, &temp_cmd_line, sizeof(uint32_t)); + // 修正x86下的参数读取偏移,使用实际结构的偏移量 + uc_mem_read(uc, esp + 0x24, &temp_proc_info, sizeof(uint32_t)); + uc_mem_read(uc, esp + 0x1C, &temp_startup_info, sizeof(uint32_t)); + lpApplicationName = temp_app_name; + lpCommandLine = temp_cmd_line; + lpProcessInformation = temp_proc_info; + lpStartupInfo = temp_startup_info; + + printf( + "[*] CreateProcessA Debug (x86): ESP=0x%x, AppNameAddr=0x%x, " + "CmdLineAddr=0x%x\n", + esp, temp_app_name, temp_cmd_line); + } + + // 读取应用程序名称 + std::string applicationName; + if (lpApplicationName != 0) { + // 增加大小检测以避免内存溢出 + char buffer[MAX_PATH] = {0}; + size_t i = 0; + bool success = true; + + do { + uint8_t byte; + uc_err err = uc_mem_read(uc, lpApplicationName + i, &byte, 1); + if (err != UC_ERR_OK) { + printf( + "[!] Error reading application name at address 0x%llx: " + "%u\n", + lpApplicationName + i, err); + success = false; + break; + } + buffer[i] = byte; + i++; + } while (buffer[i - 1] != 0 && i < MAX_PATH - 1); + + // 确保字符串以 NULL 结尾 + buffer[i] = 0; + + if (success) { + applicationName = std::string(buffer); + printf("[*] Read ApplicationName: %s (Length: %zu)\n", buffer, + applicationName.length()); + } + } + + // 读取命令行 + std::string commandLine; + if (lpCommandLine != 0) { + char buffer[MAX_PATH] = {0}; + size_t i = 0; + bool success = true; + + do { + uint8_t byte; + uc_err err = uc_mem_read(uc, lpCommandLine + i, &byte, 1); + if (err != UC_ERR_OK) { + printf("[!] Error reading command line at address 0x%llx: %u\n", + lpCommandLine + i, err); + success = false; + break; + } + buffer[i] = byte; + i++; + } while (buffer[i - 1] != 0 && i < MAX_PATH - 1); + + // 确保字符串以 NULL 结尾 + buffer[i] = 0; + + if (success) { + commandLine = std::string(buffer); + printf("[*] Read CommandLine: %s (Length: %zu)\n", buffer, + commandLine.length()); + } + } + + printf("[*] CreateProcessA: ApplicationName=%s, CommandLine=%s\n", + applicationName.empty() ? "(null)" : applicationName.c_str(), + commandLine.empty() ? "(null)" : commandLine.c_str()); + + // 模拟创建进程,设置进程和线程ID + DWORD processId = 0x1234; + DWORD threadId = 0x5678; + HANDLE hProcess = (HANDLE)0x1340; + HANDLE hThread = (HANDLE)0x1341; + + // 写入进程信息 + if (lpProcessInformation != 0) { + if (context->GetPeInfo()->isX64) { + struct PROCESS_INFORMATION64 { + HANDLE64 hProcess; + HANDLE64 hThread; + DWORD dwProcessId; + DWORD dwThreadId; + } pi; + pi.hProcess = (HANDLE64)hProcess; + pi.hThread = (HANDLE64)hThread; + pi.dwProcessId = processId; + pi.dwThreadId = threadId; + uc_mem_write(uc, lpProcessInformation, &pi, sizeof(pi)); + printf("[*] Wrote process info (x64) to 0x%llx\n", + lpProcessInformation); + } else { + PROCESS_INFORMATION pi; + pi.hProcess = hProcess; + pi.hThread = hThread; + pi.dwProcessId = processId; + pi.dwThreadId = threadId; + uc_mem_write(uc, lpProcessInformation, &pi, sizeof(pi)); + printf("[*] Wrote process info (x86) to 0x%llx\n", + lpProcessInformation); + } + } + + // 返回成功 + uint64_t result = 1; + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &result); +} + +auto Api_GetCurrentProcess(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + + // GetCurrentProcess 总是返回伪句柄值 -1 (0xFFFFFFFF) + uint64_t pseudo_handle = static_cast(-1); + + // 根据架构写入返回值 + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &pseudo_handle); + + printf("[*] GetCurrentProcess called, returning pseudo-handle 0x%llx\n", + pseudo_handle); +} + +auto Api_OpenProcessToken(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + uint64_t ProcessHandle = 0; + uint32_t DesiredAccess = 0; + uint64_t TokenHandle = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = ProcessHandle, rdx = DesiredAccess, r8 = TokenHandle + uc_reg_read(uc, UC_X86_REG_RCX, &ProcessHandle); + uint64_t temp_access; + uc_reg_read(uc, UC_X86_REG_RDX, &temp_access); + DesiredAccess = static_cast(temp_access); + uc_reg_read(uc, UC_X86_REG_R8, &TokenHandle); + } else { + // x86: 从栈上读取参数 + uint32_t esp_address = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); + esp_address += 0x4; // 跳过返回地址 + + uint32_t temp_handle; + uc_mem_read(uc, esp_address, &temp_handle, sizeof(uint32_t)); + ProcessHandle = temp_handle; + esp_address += 0x4; + + uc_mem_read(uc, esp_address, &DesiredAccess, sizeof(uint32_t)); + esp_address += 0x4; + + uint32_t temp_token; + uc_mem_read(uc, esp_address, &temp_token, sizeof(uint32_t)); + TokenHandle = temp_token; + } + + // 创建一个假的token句柄(使用一个非零值) + uint64_t fake_token_handle = 0x1234; + + // 将假的token句柄写入TokenHandle指向的内存 + if (TokenHandle != 0) { + if (context->GetPeInfo()->isX64) { + uc_mem_write(uc, TokenHandle, &fake_token_handle, sizeof(uint64_t)); + } else { + uint32_t token_handle_32 = static_cast(fake_token_handle); + uc_mem_write(uc, TokenHandle, &token_handle_32, sizeof(uint32_t)); + } + } + + // 返回TRUE + uint64_t result = 1; + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &result); + + printf( + "[*] OpenProcessToken: ProcessHandle=0x%llx, DesiredAccess=0x%x, " + "TokenHandle=0x%llx\n", + ProcessHandle, DesiredAccess, fake_token_handle); +} + +auto Api_GetTokenInformation(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + uint64_t TokenHandle = 0; + uint32_t TokenInformationClass = 0; + uint64_t TokenInformation = 0; + uint32_t TokenInformationLength = 0; + uint64_t ReturnLength = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx, rdx, r8, r9, [rsp+0x28] + uc_reg_read(uc, UC_X86_REG_RCX, &TokenHandle); + uint64_t temp_class; + uc_reg_read(uc, UC_X86_REG_RDX, &temp_class); + TokenInformationClass = static_cast(temp_class); + uc_reg_read(uc, UC_X86_REG_R8, &TokenInformation); + uint64_t temp_length; + uc_reg_read(uc, UC_X86_REG_R9, &temp_length); + TokenInformationLength = static_cast(temp_length); + + uint64_t rsp; + uc_reg_read(uc, UC_X86_REG_RSP, &rsp); + uc_mem_read(uc, rsp + 0x28, &ReturnLength, 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_handle; + uc_mem_read(uc, esp_address, &temp_handle, sizeof(uint32_t)); + TokenHandle = temp_handle; + esp_address += 0x4; + + uc_mem_read(uc, esp_address, &TokenInformationClass, sizeof(uint32_t)); + esp_address += 0x4; + + uint32_t temp_info; + uc_mem_read(uc, esp_address, &temp_info, sizeof(uint32_t)); + TokenInformation = temp_info; + esp_address += 0x4; + + uc_mem_read(uc, esp_address, &TokenInformationLength, sizeof(uint32_t)); + esp_address += 0x4; + + uint32_t temp_return; + uc_mem_read(uc, esp_address, &temp_return, sizeof(uint32_t)); + ReturnLength = temp_return; + } + + // 如果是TokenElevation类(20),返回TRUE表示进程有管理员权限 + if (TokenInformationClass == 20) { // TokenElevation + uint32_t is_elevated = 1; // 1表示有管理员权限 + if (TokenInformation != 0 && + TokenInformationLength >= sizeof(uint32_t)) { + uc_mem_write(uc, TokenInformation, &is_elevated, sizeof(uint32_t)); + } + + // 写入所需的缓冲区大小 + uint32_t required_size = sizeof(uint32_t); + if (ReturnLength != 0) { + uc_mem_write(uc, ReturnLength, &required_size, sizeof(uint32_t)); + } + } + + // 返回TRUE + uint64_t result = 1; + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &result); + + printf( + "[*] GetTokenInformation: TokenHandle=0x%llx, Class=%d, Info=0x%llx, " + "Length=%u\n", + TokenHandle, TokenInformationClass, TokenInformation, + TokenInformationLength); +} diff --git a/ai_anti_malware/sandbox_api_stl.cpp b/ai_anti_malware/sandbox_api_stl.cpp index c25d4e1..a0daebe 100644 --- a/ai_anti_malware/sandbox_api_stl.cpp +++ b/ai_anti_malware/sandbox_api_stl.cpp @@ -1,6 +1,457 @@ #include "sandbox.h" #include "sandbox_callbacks.h" +void Api_GetLastError(void* sandbox, uc_engine* uc, uint64_t address) { + auto context = static_cast(sandbox); + DWORD last_error = 0; + + // 从TEB中获取LastError + if (context->GetPeInfo()->isX64) { + last_error = context->GetTeb64()->LastErrorValue; + } else { + last_error = context->GetTeb32()->LastErrorValue; + } + + printf("[*] GetLastError: LastError=0x%x\n", last_error); + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &last_error); +} +auto Api_InitializeCriticalSectionAndSpinCount(void* sandbox, uc_engine* uc, + uint64_t address) -> void { + auto context = static_cast(sandbox); + uint64_t lpCriticalSection = 0; + uint32_t dwSpinCount = 0; + BOOL success = TRUE; // 默认返回成功 + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = lpCriticalSection, rdx = dwSpinCount + uc_reg_read(uc, UC_X86_REG_RCX, &lpCriticalSection); + uint64_t temp_spin_count = 0; + uc_reg_read(uc, UC_X86_REG_RDX, &temp_spin_count); + dwSpinCount = static_cast(temp_spin_count); + } else { + // x86: 从栈上读取参数 + uint32_t esp_address = 0; + uint32_t temp_cs = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); + esp_address += 0x4; // 跳过返回地址 + uc_mem_read(uc, esp_address, &temp_cs, sizeof(uint32_t)); + lpCriticalSection = temp_cs; + esp_address += 0x4; + uc_mem_read(uc, esp_address, &dwSpinCount, sizeof(uint32_t)); + } + + if (lpCriticalSection != 0) { + // 初始化关键段结构 + RTL_CRITICAL_SECTION cs = {0}; + cs.LockCount = -1; // 初始未锁定状态 + cs.RecursionCount = 0; // 初始递归计数为0 + cs.SpinCount = dwSpinCount; // 设置自旋计数 + cs.OwningThread = 0; // 初始无拥有线程 + cs.LockSemaphore = 0; // 初始信号量为0 + + // 写入初始化后的结构到目标内存 + uc_mem_write(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION)); + } else { + success = FALSE; + // 设置LastError + DWORD error = ERROR_INVALID_PARAMETER; + if (context->GetPeInfo()->isX64) { + context->GetTeb64()->LastErrorValue = error; + } else { + context->GetTeb32()->LastErrorValue = error; + } + } + + printf( + "[*] InitializeCriticalSectionAndSpinCount: CS=0x%llx, SpinCount=0x%x, " + "Success=%d\n", + lpCriticalSection, dwSpinCount, success); + + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &success); +} + +auto Api_InitializeCriticalSectionEx(void* sandbox, uc_engine* uc, + uint64_t address) -> void { + auto context = static_cast(sandbox); + uint64_t lpCriticalSection = 0; + uint32_t dwSpinCount = 0; + uint32_t dwFlags = 0; + BOOL success = TRUE; // 默认返回成功 + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = lpCriticalSection, rdx = dwSpinCount, r8 = dwFlags + uc_reg_read(uc, UC_X86_REG_RCX, &lpCriticalSection); + uint64_t temp_spin_count = 0; + uc_reg_read(uc, UC_X86_REG_RDX, &temp_spin_count); + dwSpinCount = static_cast(temp_spin_count); + uint64_t temp_flags = 0; + uc_reg_read(uc, UC_X86_REG_R8, &temp_flags); + dwFlags = static_cast(temp_flags); + } else { + // x86: 从栈上读取参数 + uint32_t esp_address = 0; + uint32_t temp_cs = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); + esp_address += 0x4; // 跳过返回地址 + uc_mem_read(uc, esp_address, &temp_cs, sizeof(uint32_t)); + lpCriticalSection = temp_cs; + esp_address += 0x4; + uc_mem_read(uc, esp_address, &dwSpinCount, sizeof(uint32_t)); + esp_address += 0x4; + uc_mem_read(uc, esp_address, &dwFlags, sizeof(uint32_t)); + } + + if (lpCriticalSection != 0) { + // 初始化关键段结构 + RTL_CRITICAL_SECTION cs = {0}; + cs.LockCount = -1; // 初始未锁定状态 + cs.RecursionCount = 0; // 初始递归计数为0 + cs.SpinCount = dwSpinCount; // 设置自旋计数 + cs.OwningThread = 0; // 初始无拥有线程 + cs.LockSemaphore = 0; // 初始信号量为0 + + // 处理特殊标志 + // CRITICAL_SECTION_FLAG_NO_DEBUG_INFO = 0x01000000 + // CRITICAL_SECTION_FLAG_DYNAMIC_SPIN = 0x02000000 + // CRITICAL_SECTION_FLAG_STATIC_INIT = 0x04000000 + // CRITICAL_SECTION_FLAG_RESOURCE_TYPE = 0x08000000 + // CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO = 0x10000000 + + // 写入初始化后的结构到目标内存 + uc_mem_write(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION)); + } else { + success = FALSE; + // 设置LastError + DWORD error = ERROR_INVALID_PARAMETER; + if (context->GetPeInfo()->isX64) { + context->GetTeb64()->LastErrorValue = error; + } else { + context->GetTeb32()->LastErrorValue = error; + } + } + + printf( + "[*] InitializeCriticalSectionEx: CS=0x%llx, SpinCount=0x%x, " + "Flags=0x%x, " + "Success=%d\n", + lpCriticalSection, dwSpinCount, dwFlags, success); + + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &success); +} + +auto Api_TlsAlloc(void* sandbox, uc_engine* uc, uint64_t address) -> void { + auto context = static_cast(sandbox); + DWORD tls_index = TLS_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; // 标记为已使用 + tls_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; // 标记为已使用 + tls_index = i; + break; + } + } + } + + if (tls_index == TLS_OUT_OF_INDEXES) { + // 设置LastError为没有可用的TLS索引 + DWORD error = ERROR_NO_MORE_ITEMS; + if (context->GetPeInfo()->isX64) { + context->GetTeb64()->LastErrorValue = error; + } else { + context->GetTeb32()->LastErrorValue = error; + } + } + + printf("[*] TlsAlloc: Allocated TLS Index=0x%x\n", tls_index); + + // 返回分配的TLS索引 + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &tls_index); +} +auto Api_TlsSetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void { + auto context = static_cast(sandbox); + uint32_t dwTlsIndex = 0; + uint64_t lpTlsValue = 0; + BOOL success = FALSE; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = dwTlsIndex, rdx = lpTlsValue + uint64_t temp_index; + uc_reg_read(uc, UC_X86_REG_RCX, &temp_index); + dwTlsIndex = static_cast(temp_index); + uc_reg_read(uc, UC_X86_REG_RDX, &lpTlsValue); + } 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)); + esp_address += 0x4; + uint32_t temp_value; + uc_mem_read(uc, esp_address, &temp_value, sizeof(uint32_t)); + lpTlsValue = temp_value; + } + + // 检查索引是否有效(小于64) + if (dwTlsIndex < 64) { + if (context->GetPeInfo()->isX64) { + auto teb = context->GetTeb64(); + // 检查槽是否已分配(不为nullptr) + if (teb->TlsSlots[dwTlsIndex] != (void*)0x1337ffffff) { + teb->TlsSlots[dwTlsIndex] = (void*)lpTlsValue; + success = TRUE; + } + } else { + auto teb = context->GetTeb32(); + // 检查槽是否已分配(不为0) + if (teb->TlsSlots[dwTlsIndex] != 0x1337) { + teb->TlsSlots[dwTlsIndex] = static_cast(lpTlsValue); + success = TRUE; + } + } + } + + if (!success) { + // 设置LastError + DWORD error = ERROR_INVALID_PARAMETER; + if (context->GetPeInfo()->isX64) { + context->GetTeb64()->LastErrorValue = error; + } else { + context->GetTeb32()->LastErrorValue = error; + } + } + + printf("[*] TlsSetValue: Index=0x%x, Value=0x%llx, Success=%d\n", + dwTlsIndex, lpTlsValue, success); + + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &success); +} +auto Api_DeleteCriticalSection(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + uint64_t lpCriticalSection = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = lpCriticalSection + uc_reg_read(uc, UC_X86_REG_RCX, &lpCriticalSection); + } else { + // x86: 从栈上读取参数 + uint32_t esp_address = 0; + uint32_t temp_cs = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); + esp_address += 0x4; // 跳过返回地址 + uc_mem_read(uc, esp_address, &temp_cs, sizeof(uint32_t)); + lpCriticalSection = temp_cs; + } + + if (lpCriticalSection != 0) { + // 读取现有的关键段结构 + RTL_CRITICAL_SECTION cs; + uc_mem_read(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION)); + + // 检查是否有线程仍在等待 + if (cs.LockCount >= 0) { + // 有线程正在等待,设置错误 + DWORD error = ERROR_SEM_IS_SET; + if (context->GetPeInfo()->isX64) { + context->GetTeb64()->LastErrorValue = error; + } else { + context->GetTeb32()->LastErrorValue = error; + } + } + + // 清零内存,表示删除 + memset(&cs, 0, sizeof(RTL_CRITICAL_SECTION)); + uc_mem_write(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION)); + } + + printf("[*] DeleteCriticalSection: CS=0x%llx\n", lpCriticalSection); +} + +auto Api_IsProcessorFeaturePresent(void* sandbox, uc_engine* uc, + uint64_t address) -> void { + auto context = static_cast(sandbox); + uint32_t feature_number = 0; + BOOL is_supported = FALSE; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = FeatureNumber + uint64_t temp_feature; + uc_reg_read(uc, UC_X86_REG_RCX, &temp_feature); + feature_number = static_cast(temp_feature); + } 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, &feature_number, sizeof(uint32_t)); + } + + // 模拟一些常见的处理器特性 + switch (feature_number) { + case PF_FLOATING_POINT_PRECISION_ERRATA: // 0 + is_supported = FALSE; + break; + case PF_FLOATING_POINT_EMULATED: // 1 + is_supported = FALSE; + break; + case PF_COMPARE_EXCHANGE_DOUBLE: // 2 + is_supported = TRUE; + break; + case PF_MMX_INSTRUCTIONS_AVAILABLE: // 3 + is_supported = TRUE; + break; + case PF_XMMI_INSTRUCTIONS_AVAILABLE: // 6 + is_supported = TRUE; + break; + case PF_3DNOW_INSTRUCTIONS_AVAILABLE: // 7 + is_supported = FALSE; + break; + case PF_RDTSC_INSTRUCTION_AVAILABLE: // 8 + is_supported = TRUE; + break; + case PF_PAE_ENABLED: // 9 + is_supported = TRUE; + break; + case PF_XMMI64_INSTRUCTIONS_AVAILABLE: // 10 + is_supported = TRUE; + break; + case PF_SSE_DAZ_MODE_AVAILABLE: // 11 + is_supported = TRUE; + break; + case PF_NX_ENABLED: // 12 + is_supported = TRUE; + break; + case PF_SSE3_INSTRUCTIONS_AVAILABLE: // 13 + is_supported = TRUE; + break; + case PF_COMPARE_EXCHANGE128: // 14 + is_supported = TRUE; + break; + case PF_XSAVE_ENABLED: // 17 + is_supported = TRUE; + break; + case PF_ARM_VFP_32_REGISTERS_AVAILABLE: // 18 + is_supported = FALSE; + break; + default: + is_supported = FALSE; + break; + } + + printf("[*] IsProcessorFeaturePresent: Feature=0x%x, Supported=%d\n", + feature_number, is_supported); + + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &is_supported); +} + +auto Api___set_app_type(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + int32_t appType = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = appType + uint64_t temp_type; + uc_reg_read(uc, UC_X86_REG_RCX, &temp_type); + appType = static_cast(temp_type); + } 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, &appType, sizeof(int32_t)); + } + + // 简单地返回0表示成功 + int32_t result = 0; + printf("[*] __set_app_type: AppType=%d\n", appType); + + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &result); +} + +auto Api___p__fmode(void* sandbox, uc_engine* uc, uint64_t address) -> void { + auto sb = static_cast(sandbox); + + // 检查是否已经创建了 _fmode 变量 + static uint64_t fmode_address = 0; + static int32_t fmode_value = 0; // 默认为文本模式 (_O_TEXT) + + if (fmode_address == 0) { + // 为 _fmode 变量分配内存 + // 使用特定堆地址,与其他 API 一致 + uint64_t heap_handle = + sb->GetPeInfo()->isX64 ? HEAP_ADDRESS_64 : HEAP_ADDRESS_32; + + // 在堆上分配空间 + HeapSegment* segment = nullptr; + auto it = sb->m_heapSegments.find(heap_handle); + if (it != sb->m_heapSegments.end()) { + segment = it->second; + } else { + // 创建新的堆段 + segment = sb->CreateHeapSegment(heap_handle, 0x10000); + sb->m_heapSegments[heap_handle] = segment; + } + + if (segment) { + fmode_address = sb->AllocateFromSegment(segment, sizeof(int32_t)); + if (fmode_address) { + // 初始化 _fmode 为文本模式 + uc_mem_write(uc, fmode_address, &fmode_value, sizeof(int32_t)); + printf( + "[*] __p__fmode: Allocated _fmode at 0x%llx with value " + "%d\n", + fmode_address, fmode_value); + } + } + } + + // 返回 _fmode 变量的地址 + printf("[*] __p__fmode: Returning address 0x%llx\n", fmode_address); + + // 设置返回值 + if (sb->GetPeInfo()->isX64) { + uc_reg_write(uc, UC_X86_REG_RAX, &fmode_address); + } else { + uint32_t eax = static_cast(fmode_address); + uc_reg_write(uc, UC_X86_REG_EAX, &eax); + } +} + // 实现 AreFileApisANSI API auto Api_AreFileApisANSI(void* sandbox, uc_engine* uc, uint64_t address) -> void { @@ -687,18 +1138,21 @@ auto Api_HeapAlloc(void* sandbox, uc_engine* uc, uint64_t address) -> void { uc_mem_read(uc, esp_address, &temp_bytes, sizeof(uint32_t)); dwBytes = temp_bytes; } - + // 这里如果想检查有效,得先跑main,再跑其他的,浪费时间了,操 + // 检查堆句柄是否有效 + /* uint64_t expected_handle = context->GetPeInfo()->isX64 ? HEAP_ADDRESS_64 : HEAP_ADDRESS_32; if (hHeap != expected_handle) { uint64_t null_ptr = 0; + hHeap = expected_handle; uc_reg_write( uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &null_ptr); return; } - + */ // 获取或创建堆段 HeapSegment* segment = nullptr; auto it = context->m_heapSegments.find(hHeap); @@ -1512,4 +1966,162 @@ auto Sandbox::AllocateFromSegment(HeapSegment* segment, size_t size) } return 0; // 分配失败 -} \ No newline at end of file +} + +auto Api_CloseHandle(void* sandbox, uc_engine* uc, uint64_t address) -> void { + auto context = static_cast(sandbox); + uint64_t handle = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = handle + uc_reg_read(uc, UC_X86_REG_RCX, &handle); + } else { + // x86: 从栈上读取参数 + uint32_t esp = 0; + 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)); + handle = temp_handle; + } + + bool success = true; + + // 如果是进程快照句柄 (0x1337),清理进程枚举状态 + if (handle == 0x1337) { + auto it = context->process_enum_state.find(handle); + if (it != context->process_enum_state.end()) { + context->process_enum_state.erase(it); + } + } + // 其他类型的句柄也返回成功 + // 实际应用中可能需要根据句柄类型进行不同的处理 + + printf("[*] CloseHandle: Handle=0x%llx, Success=%d\n", handle, success); + + // 设置返回值 + uint64_t result = success ? 1 : 0; + if (context->GetPeInfo()->isX64) { + uc_reg_write(uc, UC_X86_REG_RAX, &result); + } else { + uint32_t result32 = static_cast(result); + uc_reg_write(uc, UC_X86_REG_EAX, &result32); + } + + // 设置错误码 + DWORD error = success ? 0 : ERROR_INVALID_HANDLE; + if (context->GetPeInfo()->isX64) { + context->GetTeb64()->LastErrorValue = error; + } else { + context->GetTeb32()->LastErrorValue = error; + } +} + +// 添加RtlFormatCurrentUserKeyPath API实现 +auto Api_RtlFormatCurrentUserKeyPath(void* sandbox, uc_engine* uc, + uint64_t address) -> void { + auto context = static_cast(sandbox); + uint64_t keyPathBuffer = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = KeyPathBuffer + uc_reg_read(uc, UC_X86_REG_RCX, &keyPathBuffer); + } else { + // x86: 从栈上读取参数 + uint32_t esp_address = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); + esp_address += 0x4; // 跳过返回地址 + uint32_t temp_buffer; + uc_mem_read(uc, esp_address, &temp_buffer, sizeof(uint32_t)); + keyPathBuffer = temp_buffer; + } + + // 构造当前用户的注册表路径 + // 同时在这里实现查询MCP服务器的功能 + wchar_t userKeyPath[256] = + L"\\Registry\\User\\S-1-5-21-1234567890-1234567890-1234567890-1001"; + + // 模拟查询MCP服务器,这里可以根据需要实现实际的服务器查询 + // 例如可以修改userKeyPath或在日志中记录查询操作 + printf("[*] RtlFormatCurrentUserKeyPath: 正在查询MCP服务器获取用户SID\n"); + + // 将路径写入到提供的缓冲区 + if (keyPathBuffer != 0) { + uc_mem_write(uc, keyPathBuffer, userKeyPath, + (wcslen(userKeyPath) + 1) * sizeof(wchar_t)); + } + + // 返回NTSTATUS成功代码 (0x00000000 = STATUS_SUCCESS) + uint64_t status = 0; + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &status); + + printf("[*] RtlFormatCurrentUserKeyPath: Buffer=0x%llx, Path=%ls\n", + keyPathBuffer, userKeyPath); +} + +// 添加FlsSetValue API实现 +auto Api_FlsSetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void { + auto context = static_cast(sandbox); + uint64_t dwFlsIndex = 0; + uint64_t lpFlsData = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = dwFlsIndex, rdx = lpFlsData + uc_reg_read(uc, UC_X86_REG_RCX, &dwFlsIndex); + uc_reg_read(uc, UC_X86_REG_RDX, &lpFlsData); + } else { + // x86: 从栈上读取参数 + uint32_t esp_address = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); + esp_address += 0x4; // 跳过返回地址 + uint32_t temp_index; + uint32_t temp_data; + uc_mem_read(uc, esp_address, &temp_index, sizeof(uint32_t)); + uc_mem_read(uc, esp_address + 0x4, &temp_data, sizeof(uint32_t)); + dwFlsIndex = temp_index; + lpFlsData = temp_data; + } + + // 模拟FLS存储操作,类似于TLS存储 + bool success = false; + if (dwFlsIndex < 64) { // 使用与TLS相同的槽位大小 + // 存储数据到模拟的FLS槽中(复用TLS槽) + if (context->GetPeInfo()->isX64) { + auto teb = context->GetTeb64(); + if (teb->TlsSlots[dwFlsIndex] != (void*)0x1337ffffff) { + teb->TlsSlots[dwFlsIndex] = (void*)lpFlsData; + success = true; + } + } else { + auto teb = context->GetTeb32(); + if (teb->TlsSlots[dwFlsIndex] != 0x1337) { + teb->TlsSlots[dwFlsIndex] = static_cast(lpFlsData); + success = true; + } + } + } + + printf("[*] FlsSetValue: Index=%llu, Data=0x%llx, Success=%d\n", dwFlsIndex, + lpFlsData, success); + + // 设置返回值 + uint64_t result = success ? 1 : 0; + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &result); + + // 如果失败,设置错误码 + if (!success) { + DWORD error = ERROR_INVALID_PARAMETER; + if (context->GetPeInfo()->isX64) { + context->GetTeb64()->LastErrorValue = error; + } else { + context->GetTeb32()->LastErrorValue = error; + } + } +} diff --git a/ai_anti_malware/sandbox_api_wfp.cpp b/ai_anti_malware/sandbox_api_wfp.cpp new file mode 100644 index 0000000..0d0cdb2 --- /dev/null +++ b/ai_anti_malware/sandbox_api_wfp.cpp @@ -0,0 +1,220 @@ +#include "sandbox.h" +#include "sandbox_callbacks.h" +#include + +// FwpmEngineOpen0 API模拟 +auto Api_FwpmEngineOpen0(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + uint64_t serverName = 0; + uint64_t authnService = 0; + uint64_t authIdentity = 0; + uint64_t session = 0; + uint64_t engineHandle = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + uc_reg_read(uc, UC_X86_REG_RCX, &serverName); + uc_reg_read(uc, UC_X86_REG_RDX, &authnService); + uc_reg_read(uc, UC_X86_REG_R8, &authIdentity); + uc_reg_read(uc, UC_X86_REG_R9, &session); + uint64_t rsp; + uc_reg_read(uc, UC_X86_REG_RSP, &rsp); + uc_mem_read(uc, rsp + 0x28, &engineHandle, sizeof(engineHandle)); + } else { + uint32_t esp; + uc_reg_read(uc, UC_X86_REG_ESP, &esp); + esp += 4; // 跳过返回地址 + uint32_t temp; + uc_mem_read(uc, esp, &temp, sizeof(temp)); + serverName = temp; + esp += 4; + uc_mem_read(uc, esp, &temp, sizeof(temp)); + authnService = temp; + esp += 4; + uc_mem_read(uc, esp, &temp, sizeof(temp)); + authIdentity = temp; + esp += 4; + uc_mem_read(uc, esp, &temp, sizeof(temp)); + session = temp; + esp += 4; + uc_mem_read(uc, esp, &temp, sizeof(temp)); + engineHandle = temp; + } + + // 创建新的WFP引擎实例 + auto engine = new Sandbox::FakeWFPEngine(); + engine->isOpen = true; + HANDLE handle = context->GetNextWfpEngineHandle(); + context->GetWfpEngines()[handle] = engine; + + // 写回引擎句柄 + if (context->GetPeInfo()->isX64) { + uc_mem_write(uc, engineHandle, &handle, sizeof(handle)); + } else { + uint32_t handle32 = (uint32_t)(uint64_t)handle; + uc_mem_write(uc, engineHandle, &handle32, sizeof(handle32)); + } + + // 返回成功 + uint64_t result = ERROR_SUCCESS; + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &result); + + printf("[*] FwpmEngineOpen0: Handle=0x%llx\n", (uint64_t)handle); +} + +// FwpmProviderAdd0 API模拟 +auto Api_FwpmProviderAdd0(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + uint64_t engineHandle = 0; + uint64_t provider = 0; + uint64_t sd = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + uc_reg_read(uc, UC_X86_REG_RCX, &engineHandle); + uc_reg_read(uc, UC_X86_REG_RDX, &provider); + uc_reg_read(uc, UC_X86_REG_R8, &sd); + } else { + uint32_t esp; + uc_reg_read(uc, UC_X86_REG_ESP, &esp); + esp += 4; + uint32_t temp; + uc_mem_read(uc, esp, &temp, sizeof(temp)); + engineHandle = temp; + esp += 4; + uc_mem_read(uc, esp, &temp, sizeof(temp)); + provider = temp; + esp += 4; + uc_mem_read(uc, esp, &temp, sizeof(temp)); + sd = temp; + } + + // 检查引擎句柄是否有效 + auto& engines = context->GetWfpEngines(); + auto it = engines.find((HANDLE)engineHandle); + if (it == engines.end()) { + uint64_t result = ERROR_INVALID_HANDLE; + uc_reg_write( + uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &result); + return; + } + + // 添加提供者 + FWPM_PROVIDER0 providerData; + uc_mem_read(uc, provider, &providerData, sizeof(FWPM_PROVIDER0)); + it->second->providers.push_back(providerData); + + // 返回成功 + uint64_t result = ERROR_SUCCESS; + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &result); + + printf("[*] FwpmProviderAdd0: Handle=0x%llx\n", engineHandle); +} + +// FwpmFilterAdd0 API模拟 +auto Api_FwpmFilterAdd0(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + uint64_t engineHandle = 0; + uint64_t filter = 0; + uint64_t sd = 0; + uint64_t id = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + uc_reg_read(uc, UC_X86_REG_RCX, &engineHandle); + uc_reg_read(uc, UC_X86_REG_RDX, &filter); + uc_reg_read(uc, UC_X86_REG_R8, &sd); + uc_reg_read(uc, UC_X86_REG_R9, &id); + } else { + uint32_t esp; + uc_reg_read(uc, UC_X86_REG_ESP, &esp); + esp += 4; + uint32_t temp; + uc_mem_read(uc, esp, &temp, sizeof(temp)); + engineHandle = temp; + esp += 4; + uc_mem_read(uc, esp, &temp, sizeof(temp)); + filter = temp; + esp += 4; + uc_mem_read(uc, esp, &temp, sizeof(temp)); + sd = temp; + esp += 4; + uc_mem_read(uc, esp, &temp, sizeof(temp)); + id = temp; + } + + // 检查引擎句柄是否有效 + auto& engines = context->GetWfpEngines(); + auto it = engines.find((HANDLE)engineHandle); + if (it == engines.end()) { + uint64_t result = ERROR_INVALID_HANDLE; + uc_reg_write( + uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &result); + return; + } + + // 添加过滤器 + FWPM_FILTER0 filterData; + uc_mem_read(uc, filter, &filterData, sizeof(FWPM_FILTER0)); + it->second->filters.push_back(filterData); + + // 生成并写回过滤器ID + static uint64_t nextFilterId = 1; + uint64_t filterId = nextFilterId++; + if (id != 0) { + uc_mem_write(uc, id, &filterId, sizeof(filterId)); + } + + // 返回成功 + uint64_t result = ERROR_SUCCESS; + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &result); + + printf("[*] FwpmFilterAdd0: Handle=0x%llx, FilterId=0x%llx\n", engineHandle, + filterId); +} + +// FwpmEngineClose0 API模拟 +auto Api_FwpmEngineClose0(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + uint64_t engineHandle = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + uc_reg_read(uc, UC_X86_REG_RCX, &engineHandle); + } else { + uint32_t esp; + uc_reg_read(uc, UC_X86_REG_ESP, &esp); + esp += 4; + uint32_t temp; + uc_mem_read(uc, esp, &temp, sizeof(temp)); + engineHandle = temp; + } + + // 检查并关闭引擎 + auto& engines = context->GetWfpEngines(); + auto it = engines.find((HANDLE)engineHandle); + if (it != engines.end()) { + delete it->second; + engines.erase(it); + } + + // 返回成功 + uint64_t result = ERROR_SUCCESS; + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &result); + + printf("[*] FwpmEngineClose0: Handle=0x%llx\n", engineHandle); +} \ No newline at end of file diff --git a/ai_anti_malware/sandbox_api_wlan.cpp b/ai_anti_malware/sandbox_api_wlan.cpp new file mode 100644 index 0000000..46ad3ba --- /dev/null +++ b/ai_anti_malware/sandbox_api_wlan.cpp @@ -0,0 +1,286 @@ +#include "sandbox.h" +#include "sandbox_callbacks.h" +#include "sandbox_api_winhttp.h" +#include + +// WLAN API 实现 +auto Api_WlanOpenHandle(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + uint64_t dwClientVersion = 0; + uint64_t pReserved = 0; + uint64_t pdwNegotiatedVersion = 0; + uint64_t phClientHandle = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + uc_reg_read(uc, UC_X86_REG_RCX, &dwClientVersion); + uc_reg_read(uc, UC_X86_REG_RDX, &pReserved); + uc_reg_read(uc, UC_X86_REG_R8, &pdwNegotiatedVersion); + uc_reg_read(uc, UC_X86_REG_R9, &phClientHandle); + } else { + uint32_t esp; + uc_reg_read(uc, UC_X86_REG_ESP, &esp); + esp += 4; + uc_mem_read(uc, esp, &dwClientVersion, sizeof(uint32_t)); + esp += 4; + uint32_t temp_reserved; + uc_mem_read(uc, esp, &temp_reserved, sizeof(uint32_t)); + pReserved = temp_reserved; + esp += 4; + uint32_t temp_version; + uc_mem_read(uc, esp, &temp_version, sizeof(uint32_t)); + pdwNegotiatedVersion = temp_version; + esp += 4; + uint32_t temp_handle; + uc_mem_read(uc, esp, &temp_handle, sizeof(uint32_t)); + phClientHandle = temp_handle; + } + + // 修改常量定义 + uint32_t negotiatedVersion = 2; // 返回请求的版本 + uint64_t clientHandle = 0x13370000; // 使用有效的十六进制常量 + + // 写入协商版本 + if (pdwNegotiatedVersion != 0) { + uc_mem_write(uc, pdwNegotiatedVersion, &negotiatedVersion, + sizeof(uint32_t)); + } + + // 写入客户端句柄 + if (phClientHandle != 0) { + if (context->GetPeInfo()->isX64) { + uc_mem_write(uc, phClientHandle, &clientHandle, sizeof(uint64_t)); + } else { + uint32_t handle32 = static_cast(clientHandle); + uc_mem_write(uc, phClientHandle, &handle32, sizeof(uint32_t)); + } + } + + // 返回成功(0) + uint64_t result = 0; + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &result); + + printf("[*] WlanOpenHandle: Version=%u, Handle=0x%llx\n", negotiatedVersion, + clientHandle); +} + +auto Api_WlanEnumInterfaces(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + uint64_t hClientHandle = 0; + uint64_t pReserved = 0; + uint64_t ppInterfaceList = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + uc_reg_read(uc, UC_X86_REG_RCX, &hClientHandle); + uc_reg_read(uc, UC_X86_REG_RDX, &pReserved); + uc_reg_read(uc, UC_X86_REG_R8, &ppInterfaceList); + } else { + uint32_t esp; + uc_reg_read(uc, UC_X86_REG_ESP, &esp); + esp += 4; + uint32_t temp_handle; + uc_mem_read(uc, esp, &temp_handle, sizeof(uint32_t)); + hClientHandle = temp_handle; + esp += 4; + uint32_t temp_reserved; + uc_mem_read(uc, esp, &temp_reserved, sizeof(uint32_t)); + pReserved = temp_reserved; + esp += 4; + uint32_t temp_list; + uc_mem_read(uc, esp, &temp_list, sizeof(uint32_t)); + ppInterfaceList = temp_list; + } + + // 修改句柄检查 + if (hClientHandle != 0x13370000) { + uint64_t result = 1; // ERROR_INVALID_HANDLE + uc_reg_write( + uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &result); + return; + } + + // 分配内存用于接口列表 + uint64_t interfaceListAddr = context->AllocateMemory(1024); // 足够大的空间 + + // 创建一个模拟的WLAN接口列表 + struct WLAN_INTERFACE_INFO { + GUID InterfaceGuid; + WCHAR strInterfaceDescription[256]; + DWORD isState; + }; + + struct WLAN_INTERFACE_INFO_LIST { + DWORD dwNumberOfItems; + DWORD dwIndex; + WLAN_INTERFACE_INFO InterfaceInfo[1]; + }; + + WLAN_INTERFACE_INFO_LIST interfaceList = {0}; + interfaceList.dwNumberOfItems = 1; + interfaceList.dwIndex = 0; + + // 创建一个假的GUID + GUID fakeGuid = {0x12345678, + 0x1234, + 0x1234, + {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF}}; + interfaceList.InterfaceInfo[0].InterfaceGuid = fakeGuid; + + // 设置接口描述 + const wchar_t* description = L"Simulated Wi-Fi Adapter"; + wcscpy_s(interfaceList.InterfaceInfo[0].strInterfaceDescription, + description); + interfaceList.InterfaceInfo[0].isState = 1; // connected + + // 写入接口列表 + uc_mem_write(uc, interfaceListAddr, &interfaceList, + sizeof(WLAN_INTERFACE_INFO_LIST)); + + // 写入接口列表指针 + if (context->GetPeInfo()->isX64) { + uc_mem_write(uc, ppInterfaceList, &interfaceListAddr, sizeof(uint64_t)); + } else { + uint32_t addr32 = static_cast(interfaceListAddr); + uc_mem_write(uc, ppInterfaceList, &addr32, sizeof(uint32_t)); + } + + // 返回成功(0) + uint64_t result = 0; + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &result); + + printf("[*] WlanEnumInterfaces: Handle=0x%llx, InterfaceList=0x%llx\n", + hClientHandle, interfaceListAddr); +} + +auto Api_WlanGetProfileList(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + uint64_t hClientHandle = 0; + uint64_t pInterfaceGuid = 0; + uint64_t pReserved = 0; + uint64_t ppProfileList = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + uc_reg_read(uc, UC_X86_REG_RCX, &hClientHandle); + uc_reg_read(uc, UC_X86_REG_RDX, &pInterfaceGuid); + uc_reg_read(uc, UC_X86_REG_R8, &pReserved); + uc_reg_read(uc, UC_X86_REG_R9, &ppProfileList); + } else { + uint32_t esp; + uc_reg_read(uc, UC_X86_REG_ESP, &esp); + esp += 4; + uint32_t temp_values[4]; + uc_mem_read(uc, esp, temp_values, sizeof(uint32_t) * 4); + hClientHandle = temp_values[0]; + pInterfaceGuid = temp_values[1]; + pReserved = temp_values[2]; + ppProfileList = temp_values[3]; + } + + // 分配内存用于配置文件列表 + uint64_t profileListAddr = context->AllocateMemory(1024); + + // 创建模拟的配置文件列表 + struct WLAN_PROFILE_INFO { + WCHAR strProfileName[256]; + DWORD dwFlags; + }; + + struct WLAN_PROFILE_INFO_LIST { + DWORD dwNumberOfItems; + DWORD dwIndex; + WLAN_PROFILE_INFO ProfileInfo[1]; + }; + + WLAN_PROFILE_INFO_LIST profileList = {0}; + profileList.dwNumberOfItems = 1; + profileList.dwIndex = 0; + + // 设置一个模拟的配置文件 + const wchar_t* profileName = L"Home Network"; + wcscpy_s(profileList.ProfileInfo[0].strProfileName, profileName); + profileList.ProfileInfo[0].dwFlags = 1; + + // 写入配置文件列表 + uc_mem_write(uc, profileListAddr, &profileList, + sizeof(WLAN_PROFILE_INFO_LIST)); + + // 写入配置文件列表指针 + if (context->GetPeInfo()->isX64) { + uc_mem_write(uc, ppProfileList, &profileListAddr, sizeof(uint64_t)); + } else { + uint32_t addr32 = static_cast(profileListAddr); + uc_mem_write(uc, ppProfileList, &addr32, sizeof(uint32_t)); + } + + // 返回成功(0) + uint64_t result = 0; + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &result); + + printf("[*] WlanGetProfileList: Handle=0x%llx, ProfileList=0x%llx\n", + hClientHandle, profileListAddr); +} + +auto Api_WlanFreeMemory(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + uint64_t pMemory = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + uc_reg_read(uc, UC_X86_REG_RCX, &pMemory); + } else { + uint32_t esp; + uc_reg_read(uc, UC_X86_REG_ESP, &esp); + esp += 4; + uint32_t temp_memory; + uc_mem_read(uc, esp, &temp_memory, sizeof(uint32_t)); + pMemory = temp_memory; + } + + // 实际上我们不需要释放内存,因为这是在模拟环境中 + printf("[*] WlanFreeMemory: Memory=0x%llx\n", pMemory); +} + +auto Api_WlanCloseHandle(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + uint64_t hClientHandle = 0; + uint64_t pReserved = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + uc_reg_read(uc, UC_X86_REG_RCX, &hClientHandle); + uc_reg_read(uc, UC_X86_REG_RDX, &pReserved); + } else { + uint32_t esp; + uc_reg_read(uc, UC_X86_REG_ESP, &esp); + esp += 4; + uint32_t temp_handle; + uc_mem_read(uc, esp, &temp_handle, sizeof(uint32_t)); + hClientHandle = temp_handle; + esp += 4; + uint32_t temp_reserved; + uc_mem_read(uc, esp, &temp_reserved, sizeof(uint32_t)); + pReserved = temp_reserved; + } + + // 返回成功(0) + uint64_t result = 0; + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &result); + + printf("[*] WlanCloseHandle: Handle=0x%llx\n", hClientHandle); +} diff --git a/ai_anti_malware/sandbox_callbacks.cpp b/ai_anti_malware/sandbox_callbacks.cpp index fb19911..c495a3d 100644 --- a/ai_anti_malware/sandbox_callbacks.cpp +++ b/ai_anti_malware/sandbox_callbacks.cpp @@ -5,6 +5,7 @@ void handleCodeRun(uc_engine* uc, uint64_t address, uint32_t size, uint64_t currentRip = 0; uint64_t currentRsp = 0; uint64_t currentRax = 0; + static uint64_t lastRip = 0; auto* sandbox = static_cast(userData); if (!sandbox) return; @@ -61,12 +62,15 @@ void handleCodeRun(uc_engine* uc, uint64_t address, uint32_t size, for (auto item : module->export_function) { const auto vmAddress = module->base + item->function_address; if (vmAddress == currentRip) { - printf("[%s] call function %s at file address: %llx\n", - module->name, item->name, address); + printf( + "[%s] call function %s at file address: %llx lastRip: " + "%llx\n", + module->name, item->name, address, lastRip); sandbox->EmulateApi(uc, vmAddress, currentRip, item->name); } } } + lastRip = currentRip; if (LOG_LEVEL > 0) { // 使用Capstone反汇编 cs_insn* instruction; diff --git a/ai_anti_malware/tiny_wfp_structs.h b/ai_anti_malware/tiny_wfp_structs.h new file mode 100644 index 0000000..6a0b34c --- /dev/null +++ b/ai_anti_malware/tiny_wfp_structs.h @@ -0,0 +1,3 @@ +#pragma once +#include "head.h" +#include \ No newline at end of file