From 2c18f7fd15dfcf8b172953ed3e3810491f7b6d3a Mon Sep 17 00:00:00 2001 From: huoji Date: Thu, 6 Mar 2025 18:39:01 +0800 Subject: [PATCH] update --- ai_anti_malware/.vscode/c_cpp_properties.json | 21 + ai_anti_malware/.vscode/settings.json | 57 + ai_anti_malware/ai_anti_malware.cpp | 4 +- ai_anti_malware/ai_anti_malware.vcxproj | 3 +- .../ai_anti_malware.vcxproj.filters | 3 + ai_anti_malware/native_struct.h | 1 + ai_anti_malware/sandbox.cpp | 79 +- ai_anti_malware/sandbox.h | 71 +- ai_anti_malware/sandbox_api_emu.cpp | 1321 +++++++++++++++++ ai_anti_malware/sandbox_callbacks.cpp | 96 ++ ai_anti_malware/sandbox_callbacks.h | 76 +- 11 files changed, 1642 insertions(+), 90 deletions(-) create mode 100644 ai_anti_malware/.vscode/c_cpp_properties.json create mode 100644 ai_anti_malware/.vscode/settings.json create mode 100644 ai_anti_malware/sandbox_api_emu.cpp diff --git a/ai_anti_malware/.vscode/c_cpp_properties.json b/ai_anti_malware/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..a0835a1 --- /dev/null +++ b/ai_anti_malware/.vscode/c_cpp_properties.json @@ -0,0 +1,21 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [ + "_DEBUG", + "UNICODE", + "_UNICODE" + ], + "compilerPath": "E:/Program Files/LLVM/bin/clang++.exe", + "cStandard": "c11", + "cppStandard": "c++23", + "intelliSenseMode": "windows-clang-x64", + "windowsSdkVersion": "10.0.22000.0" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/ai_anti_malware/.vscode/settings.json b/ai_anti_malware/.vscode/settings.json new file mode 100644 index 0000000..9ef98c4 --- /dev/null +++ b/ai_anti_malware/.vscode/settings.json @@ -0,0 +1,57 @@ +{ + "files.associations": { + "stdexcept": "cpp", + "algorithm": "cpp", + "atomic": "cpp", + "bit": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "compare": "cpp", + "concepts": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "exception": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "initializer_list": "cpp", + "ios": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "iterator": "cpp", + "limits": "cpp", + "memory": "cpp", + "new": "cpp", + "ostream": "cpp", + "sstream": "cpp", + "streambuf": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "typeinfo": "cpp", + "utility": "cpp", + "xfacet": "cpp", + "xhash": "cpp", + "xiosbase": "cpp", + "xlocale": "cpp", + "xlocinfo": "cpp", + "xlocnum": "cpp", + "xmemory": "cpp", + "xstddef": "cpp", + "xstring": "cpp", + "xtr1common": "cpp", + "xtree": "cpp", + "xutility": "cpp", + "functional": "cpp" + } +} \ 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 a8fbefd..794794f 100644 --- a/ai_anti_malware/ai_anti_malware.cpp +++ b/ai_anti_malware/ai_anti_malware.cpp @@ -32,9 +32,7 @@ auto getPeInfo(std::string inputFilePath) -> std::shared_ptr { return sampleInfo; } int main() { - auto sampleInfo = getPeInfo( - "E:\\对战平台\\CrowAntiCheat\\CrowAntiCheat\\client\\Console_" - "Test\\Release\\Console_Test.exe"); + auto sampleInfo = getPeInfo("C:\\ConsoleApplication1.exe"); printf("input new file %s \n", sampleInfo->inputFilePath); printf("is x64: %d\n", sampleInfo->isX64); printf("is relocated: %d\n", sampleInfo->isRelocated); diff --git a/ai_anti_malware/ai_anti_malware.vcxproj b/ai_anti_malware/ai_anti_malware.vcxproj index d59176d..78124b2 100644 --- a/ai_anti_malware/ai_anti_malware.vcxproj +++ b/ai_anti_malware/ai_anti_malware.vcxproj @@ -115,7 +115,7 @@ Level3 true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) false stdcpplatest false @@ -171,6 +171,7 @@ + diff --git a/ai_anti_malware/ai_anti_malware.vcxproj.filters b/ai_anti_malware/ai_anti_malware.vcxproj.filters index fe53946..0deb7f8 100644 --- a/ai_anti_malware/ai_anti_malware.vcxproj.filters +++ b/ai_anti_malware/ai_anti_malware.vcxproj.filters @@ -114,6 +114,9 @@ 源文件\sandbox + + 源文件\sandbox + diff --git a/ai_anti_malware/native_struct.h b/ai_anti_malware/native_struct.h index 293f3cb..e7c8dce 100644 --- a/ai_anti_malware/native_struct.h +++ b/ai_anti_malware/native_struct.h @@ -937,6 +937,7 @@ struct moudle_export { char name[MAX_PATH]; uint64_t function_address; void* function_callback; + uint64_t ordinal; }; struct moudle_import { char name[MAX_PATH]; diff --git a/ai_anti_malware/sandbox.cpp b/ai_anti_malware/sandbox.cpp index f8fa875..1172591 100644 --- a/ai_anti_malware/sandbox.cpp +++ b/ai_anti_malware/sandbox.cpp @@ -1,5 +1,7 @@ #include "sandbox.h" + #include "sandbox_callbacks.h" + std::string getDllNameFromApiSetMap(const std::string& apiSet) { const std::wstring wApiSet(apiSet.begin(), apiSet.end()); @@ -129,7 +131,37 @@ class cListImportNames : public peconv::ImportThunksCallback { std::vector>& nameToAddr; }; +class cFixImprot : public peconv::t_function_resolver { + public: + // 构造函数接收Sandbox实例的引用 + explicit cFixImprot(Sandbox* sandbox) : m_sandbox(sandbox) {} + // 实现导入函数解析 + virtual FARPROC resolve_func(LPSTR lib_name, LPSTR func_name) override { + // 遍历所有已加载的模块 + for (const auto& module : m_sandbox->m_moduleList) { + // 检查模块名是否匹配 + if (_stricmp(module->name, lib_name) == 0) { + // 遍历模块的导出函数 + for (const auto& exp : m_sandbox->m_exportFuncDict) { + // 检查函数名是否匹配 + if (strcmp(exp->name, func_name) == 0) { + auto newBase = reinterpret_cast( + module->base + exp->function_address); + printf("fix import: %s => %llx \n", func_name, newBase); + // 返回在模拟器中的虚拟地址 + return newBase; + } + } + } + } + __debugbreak(); + return nullptr; + } + + private: + Sandbox* m_sandbox; // Sandbox实例的指针 +}; Sandbox::Sandbox() {} Sandbox::~Sandbox() {} @@ -167,7 +199,6 @@ auto Sandbox::PushModuleToVM(const char* dllName, uint64_t moduleBase) -> void { newModule.real_base = moduleBase; newModule.entry = ntHeaders->OptionalHeader.AddressOfEntryPoint; newModule.size = ntHeaders->OptionalHeader.SizeOfImage; - // 处理区段 for (WORD i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++) { const auto& section = sectionHeader[i]; @@ -208,9 +239,13 @@ auto Sandbox::PushModuleToVM(const char* dllName, uint64_t moduleBase) -> void { uc_mem_map(m_ucEngine, newModule.base, newModule.size, UC_PROT_READ | UC_PROT_EXEC); uc_mem_write(m_ucEngine, newModule.base, (void*)moduleBase, newModule.size); + if (peconv::relocate_module((BYTE*)moduleBase, newModule.size, + newModule.base) == false) { + throw std::runtime_error("Failed to relocate module"); + } } - -auto Sandbox::ResolveExport() -> void { +auto Sandbox::ResolveExport(uint64_t moduleBase) + -> std::vector> { DWORD exportSize = 0; static RtlImageDirectoryEntryToDataFn fnRtlImageDirectoryEntryToData; if (fnRtlImageDirectoryEntryToData == nullptr) { @@ -221,25 +256,25 @@ auto Sandbox::ResolveExport() -> void { // 获取导出表 PIMAGE_EXPORT_DIRECTORY exportDirectory = static_cast(fnRtlImageDirectoryEntryToData( - m_peInfo->peBuffer, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, - &exportSize)); + reinterpret_cast(moduleBase), TRUE, + IMAGE_DIRECTORY_ENTRY_EXPORT, &exportSize)); if (exportDirectory) { const DWORD numberOfNames = exportDirectory->NumberOfNames; PDWORD addressOfFunctions = - reinterpret_cast(static_cast(m_peInfo->peBuffer) + + reinterpret_cast(reinterpret_cast(moduleBase) + exportDirectory->AddressOfFunctions); PDWORD addressOfNames = - reinterpret_cast(static_cast(m_peInfo->peBuffer) + + reinterpret_cast(reinterpret_cast(moduleBase) + exportDirectory->AddressOfNames); PWORD addressOfNameOrdinals = - reinterpret_cast(static_cast(m_peInfo->peBuffer) + + reinterpret_cast(reinterpret_cast(moduleBase) + exportDirectory->AddressOfNameOrdinals); // 遍历导出函数 for (size_t i = 0; i < numberOfNames; i++) { PCHAR functionName = reinterpret_cast( - static_cast(m_peInfo->peBuffer) + addressOfNames[i]); + reinterpret_cast(moduleBase) + addressOfNames[i]); // 获取函数RVA const DWORD functionRva = @@ -249,11 +284,24 @@ auto Sandbox::ResolveExport() -> void { moudle_export exportData{}; memcpy(exportData.name, functionName, strlen(functionName)); exportData.function_address = functionRva; + exportData.ordinal = static_cast( + addressOfNameOrdinals[i] + exportDirectory->Base); // 设置序号 m_exportFuncDict.push_back( std::make_shared(exportData)); } } + return m_exportFuncDict; +} +auto Sandbox::ResolveImportExports() -> void { + for (auto module : m_moduleList) { + const auto exports = ResolveExport(module->real_base); + for (const auto item : exports) { + printf("import export: [%s] %s => %llx\n", module->name, item->name, + item->function_address); + module->export_function.push_back(item); + } + } } auto Sandbox::processImportModule(const moudle_import* importModule) -> void { @@ -442,7 +490,6 @@ auto Sandbox::SetupVirtualMachine() -> void { } auto Sandbox::InitEnv(std::shared_ptr peInfo) -> void { m_peInfo = peInfo; - if (cs_open(CS_ARCH_X86, peInfo->isX64 ? CS_MODE_64 : CS_MODE_32, &m_csHandle) != CS_ERR_OK) { throw std::runtime_error("Failed to initialize Capstone"); @@ -453,7 +500,14 @@ auto Sandbox::InitEnv(std::shared_ptr peInfo) -> void { throw std::runtime_error("Failed to initialize Unicorn"); } ResoveImport(); - ResolveExport(); + ResolveImportExports(); + + // 修复导入表 + cFixImprot importFixer(this); + if (!peconv::load_imports(m_peInfo->peBuffer, &importFixer)) { + throw std::runtime_error("Failed to fix imports"); + } + uc_err ucErr = uc_mem_map(m_ucEngine, m_peInfo->RecImageBase, m_peInfo->peSize, UC_PROT_ALL); if (ucErr != UC_ERR_OK) { @@ -464,6 +518,8 @@ auto Sandbox::InitEnv(std::shared_ptr peInfo) -> void { printf("map file to vm file: %llx\n", m_peInfo->RecImageBase); printf("map file to vm size: %llx\n", m_peInfo->peSize); SetupVirtualMachine(); + InitCommandLine(peInfo->inputFilePath); + } auto Sandbox::Run() -> void { @@ -551,6 +607,7 @@ auto Sandbox::Run() -> void { // 开始执行 std::cout << "Starting execution at " << std::hex << entryPoint << std::endl; + InitApiHooks(); err = uc_emu_start(m_ucEngine, entryPoint, m_peInfo->imageEnd, 0, 0); if (err != UC_ERR_OK) { std::cerr << "Emulation error: " << uc_strerror(err) << std::endl; diff --git a/ai_anti_malware/sandbox.h b/ai_anti_malware/sandbox.h index 04095e9..89b99c0 100644 --- a/ai_anti_malware/sandbox.h +++ b/ai_anti_malware/sandbox.h @@ -1,6 +1,8 @@ #pragma once -#include "head.h" +#include +#include +#include "head.h" #define PAGE_SIZE 0x1000 #define CF_MASK (1 << 0) #define PF_MASK (1 << 2) @@ -17,8 +19,10 @@ #define HEAP_ADDRESS_32 0x5000000 #define HEAP_SIZE_32 0x5000000 -#define PEB_BASE 0x80000 +#define PEB_BASE 0x90000 #define TEB_BASE 0x90000 +#define CMDLINE_ADDRESS 0x100000 // 命令行字符串的固定地址 +#define CMDLINEW_ADDRESS 0x110000 // 宽字符命令行字符串的固定地址 #define X86_GDT_ADDR 0x30000 #define X86_GDT_LIMIT 0x1000 @@ -45,20 +49,60 @@ enum class WinVer { kWin1019H2 = 0x0A07, // November 2019 update 19H2 kWin1020H1 = 0x0A08 // April 2020 update 20H1 }; +struct _fakeApi { + std::function func; + uint32_t paramCount; +}; + +// 添加堆管理相关的结构定义 +struct HeapBlock { + uint64_t address; // 块的起始地址 + size_t size; // 块的大小 + bool is_free; // 是否是空闲块 + HeapBlock* next; // 下一个块 + HeapBlock* prev; // 上一个块 +}; + +struct HeapSegment { + uint64_t base; // 堆段的基址 + size_t size; // 堆段的总大小 + HeapBlock* blocks; // 块链表 +}; class Sandbox { + friend class cFixImprot; // 声明cFixImprot为友元类 public: Sandbox(); ~Sandbox(); // Public methods auto InitEnv(std::shared_ptr peInfo) -> void; - auto Run() -> 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; } + auto GetModuleList() const -> std::vector> { + return m_moduleList; + } + auto EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip, + std::string ApiName) -> void; + auto GetPeb32() -> X32PEB* { return &m_peb32; } + auto GetPeb64() -> X64PEB* { return &m_peb64; } + auto GetTeb32() -> X32TEB* { return &m_teb32; } + auto GetTeb64() -> X64TEB* { return &m_teb64; } + auto GetCommandLine() const -> const char* { return m_commandLine.c_str(); } + auto GetCommandLineAddress() const -> uint64_t { return CMDLINE_ADDRESS; } + auto GetCommandLineWAddress() const -> uint64_t { return CMDLINEW_ADDRESS; } + auto InitCommandLine() -> void; + + // 堆管理相关的公共方法 + auto CreateHeapSegment(uint64_t base, size_t size) -> HeapSegment*; + auto AllocateFromSegment(HeapSegment* segment, size_t size) -> uint64_t; + auto FreeBlock(uint64_t address) -> bool; + auto FindHeapSegment(uint64_t address) -> HeapSegment*; + auto MergeBlocks(HeapBlock* block) -> void; + auto SplitBlock(HeapBlock* block, size_t size) -> void; + std::map m_heapSegments; // 堆段映射表 private: std::shared_ptr m_peInfo; @@ -75,19 +119,26 @@ class Sandbox { uint64_t m_heapSize; uint64_t m_heapEnd; uint64_t m_fakeBase; - struct_gs_base m_gsBaseStruct; - X64TEB m_teb64; - X64PEB m_peb64; - X32TEB m_teb32; - X32PEB m_peb32; + struct_gs_base m_gsBaseStruct = {0}; + X64TEB m_teb64 = {0}; + X64PEB m_peb64 = {0}; + X32TEB m_teb32 = {0}; + X32PEB m_peb32 = {0}; csh m_csHandle; // Capstone handle uc_engine* m_ucEngine; // Unicorn engine handle std::vector> m_impFuncDict; std::vector> m_exportFuncDict; std::vector> m_moduleList; + std::map> api_map; + std::string m_commandLine; // 存储命令行字符串 + auto ResoveImport() -> void; auto SetupVirtualMachine() -> void; - auto ResolveExport() -> void; auto PushModuleToVM(const char* dllName, uint64_t moduleBase) -> void; auto processImportModule(const moudle_import* importModule) -> void; + auto ResolveImportExports() -> void; + auto ResolveExport(uint64_t moduleBase) + -> std::vector>; + auto InitApiHooks() -> void; + auto InitCommandLine(std::string commandLine) -> void; }; diff --git a/ai_anti_malware/sandbox_api_emu.cpp b/ai_anti_malware/sandbox_api_emu.cpp new file mode 100644 index 0000000..2651aba --- /dev/null +++ b/ai_anti_malware/sandbox_api_emu.cpp @@ -0,0 +1,1321 @@ +#include "sandbox.h" +std::string getDllNameFromApiSetMap(const std::string& apiSet); +auto Api_QueryPerformanceCounter(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + uint64_t return_params_address = 0; + LARGE_INTEGER data; + BOOL origin_return_value = QueryPerformanceCounter(&data); + if (context->GetPeInfo()->isX64) { + uc_reg_read(uc, UC_X86_REG_RCX, &return_params_address); + } else { + uint64_t ebp_address = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &ebp_address); + ebp_address += 0x4; + uc_mem_read(uc, ebp_address, &return_params_address, 0x4); + } + uc_mem_write(uc, return_params_address, &data, sizeof(LARGE_INTEGER)); + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &origin_return_value); +} +auto Api_GetSystemTimeAsFileTime(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + uint64_t rcx; + FILETIME file_time; + GetSystemTimeAsFileTime(&file_time); + uc_reg_read(uc, UC_X86_REG_RCX, &rcx); + uc_mem_write(uc, rcx, &file_time, sizeof(FILETIME)); +} +void Api_GetCurrentThreadId(void* sandbox, uc_engine* uc, uint64_t address) { + auto context = static_cast(sandbox); + if (context->GetPeInfo()->isX64) { + uc_reg_write(uc, UC_X86_REG_RAX, + &context->GetTeb64()->ClientId.UniqueThread); + } else { + uc_reg_write(uc, UC_X86_REG_RAX, + &context->GetTeb32()->ClientId.UniqueThread); + } +} +void Api_GetCurrentProcessId(void* sandbox, uc_engine* uc, uint64_t address) { + auto context = static_cast(sandbox); + if (context->GetPeInfo()->isX64) { + uc_reg_write(uc, UC_X86_REG_RAX, + &context->GetTeb64()->ClientId.UniqueProcess); + } else { + uc_reg_write(uc, UC_X86_REG_RAX, + &context->GetTeb32()->ClientId.UniqueProcess); + } +} +auto Api_LoadLibraryA(void* sandbox, uc_engine* uc, uint64_t address) -> void { + auto context = static_cast(sandbox); + uint64_t params_address = 0; + + // 获取参数地址 + if (context->GetPeInfo()->isX64) { + uc_reg_read(uc, UC_X86_REG_RCX, ¶ms_address); + } else { + uint64_t ebp_address = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &ebp_address); + ebp_address += 0x4; + uc_mem_read(uc, ebp_address, ¶ms_address, 0x4); + } + + uint64_t return_address = 0; + std::string module_name; + char buffer[MAX_PATH]; + size_t i = 0; + + // 读取模块名称 + if (params_address != 0) { + do { + uint8_t byte; + uc_mem_read(uc, params_address + i, &byte, 1); + buffer[i] = byte; + i++; + } while (buffer[i - 1] != 0 && i < MAX_PATH); + + if (i > 0 && i < MAX_PATH) { + module_name = std::string(buffer); + // 确保模块名以.dll结尾(不区分大小写) + if (module_name.length() > 4) { + std::string ext = module_name.substr(module_name.length() - 4); + if (_stricmp(ext.c_str(), ".dll") != 0) { + module_name += ".dll"; + } + } else { + module_name += ".dll"; + } + std::string fuck_up_api_ms = module_name; + if (fuck_up_api_ms.find("api-ms-") != std::string::npos) { + module_name = getDllNameFromApiSetMap(fuck_up_api_ms); + if (module_name.size() <= 1) __debugbreak(); + } + + // 从模块列表中查找对应模块 + for (const auto& module : context->GetModuleList()) { + if (_stricmp((*module).name, module_name.c_str()) == 0) { + return_address = (*module).base; + break; + } + } + } + } + + printf("[*] LoadLibraryA: Module=%s, Base=0x%llx\n", module_name.c_str(), + return_address); + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &return_address); +} +auto Api_LoadLibraryExW(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + uint64_t module_name_address = 0; + uint64_t flags = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = lpLibFileName, r8 = dwFlags + uc_reg_read(uc, UC_X86_REG_RCX, &module_name_address); + uc_reg_read(uc, UC_X86_REG_R8, &flags); + } else { + // x86: 从栈上读取参数 + uint64_t esp_address = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); + esp_address += 0x4; // 跳过返回地址 + uc_mem_read(uc, esp_address, &module_name_address, 0x4); + esp_address += 0x8; // 跳过hFile参数 + uc_mem_read(uc, esp_address, &flags, 0x4); + } + + uint64_t return_address = 0; + std::wstring module_name; + wchar_t buffer[MAX_PATH]; + size_t i = 0; + bool isApiSetMapMeme = false; + // 读取宽字符模块名称 + if (module_name_address != 0) { + do { + uint16_t wchar; + uc_mem_read(uc, module_name_address + (i * 2), &wchar, 2); + buffer[i] = wchar; + i++; + } while (buffer[i - 1] != 0 && i < MAX_PATH); + + if (i > 0 && i < MAX_PATH) { + module_name = std::wstring(buffer); + std::string ansi_name(module_name.begin(), module_name.end()); + + std::string fuck_up_api_ms = ansi_name; + if (ansi_name.length() > 4) { + std::string ext = ansi_name.substr(ansi_name.length() - 4); + if (_stricmp(ext.c_str(), ".dll") != 0) { + ansi_name += ".dll"; + } + } else { + ansi_name += ".dll"; + } + if (ansi_name.find("api-ms-") != std::string::npos) { + ansi_name = getDllNameFromApiSetMap(ansi_name); + isApiSetMapMeme = true; + // if (ansi_name.size() <= 1) __debugbreak(); + } + + // 从模块列表中查找对应模块 + for (const auto& module : context->GetModuleList()) { + if (_stricmp((*module).name, ansi_name.c_str()) == 0) { + return_address = (*module).base; + break; + } + } + } + } + + printf("[*] LoadLibraryExW: Module=%ls, Flags=0x%llx, Base=0x%llx\n", + module_name.c_str(), flags, return_address); + if (return_address == 0 && isApiSetMapMeme) { + // 找不到就不管他了,操 + return_address = 0x1337; + } + uc_reg_write(uc, + 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_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] == nullptr) { + teb->TlsSlots[i] = (void*)1; // 标记为已使用 + tls_index = i; + break; + } + } + } else { + auto teb = context->GetTeb32(); + // 在TLS槽中查找第一个可用的位置 + for (DWORD i = 0; i < 64; i++) { // TEB中TlsSlots数组大小为64 + if (teb->TlsSlots[i] == 0) { + teb->TlsSlots[i] = 1; // 标记为已使用 + 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] != nullptr) { + teb->TlsSlots[dwTlsIndex] = (void*)lpTlsValue; + success = TRUE; + } + } else { + auto teb = context->GetTeb32(); + // 检查槽是否已分配(不为0) + if (teb->TlsSlots[dwTlsIndex] != 0) { + 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); + uint64_t moduleHandle = 0; + uint64_t functionNameAddr = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = hModule, rdx = lpProcName + uc_reg_read(uc, UC_X86_REG_RCX, &moduleHandle); + uc_reg_read(uc, UC_X86_REG_RDX, &functionNameAddr); + } else { + // x86: 从栈上读取参数 + uint64_t esp_address = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); + esp_address += 0x4; // 跳过返回地址 + uint32_t temp_handle = 0; + uint32_t temp_name_addr = 0; + uc_mem_read(uc, esp_address, &temp_handle, sizeof(uint32_t)); + uc_mem_read(uc, esp_address + 0x4, &temp_name_addr, sizeof(uint32_t)); + moduleHandle = temp_handle; + functionNameAddr = temp_name_addr; + } + + uint64_t return_address = 0; + + // 读取函数名 + if (functionNameAddr == 0) { + __debugbreak(); + } + // 通过名称查找 + char functionName[256] = {0}; + size_t i = 0; + do { + uint8_t byte; + uc_mem_read(uc, functionNameAddr + i, &byte, 1); + functionName[i] = byte; + i++; + } while (functionName[i - 1] != 0 && i < sizeof(functionName)); + + // 在模块列表中查找对应模块 + for (const auto& module : context->GetModuleList()) { + if (module->base == moduleHandle) { + // 遍历导出函数查找对应名称 + for (const auto& exp : module->export_function) { + // 使用 _stricmp 进行大小写不敏感的比较 + if (_stricmp(exp->name, functionName) == 0) { + return_address = module->base + exp->function_address; + break; + } + } + break; + } + } + + printf("[*] GetProcAddress: Module=0x%llx, Function=%s, Address=0x%llx\n", + moduleHandle, functionName, return_address); + + // 设置返回值 + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &return_address); +} + +auto Api_GetProcessHeap(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + // 返回默认堆句柄(使用堆基址作为句柄) + uint64_t heap_handle = + context->GetPeInfo()->isX64 ? HEAP_ADDRESS_64 : HEAP_ADDRESS_32; + + printf("[*] GetProcessHeap: Handle=0x%llx\n", heap_handle); + + // 返回堆句柄 + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &heap_handle); +} + +// 实现HeapAlloc API +auto Api_HeapAlloc(void* sandbox, uc_engine* uc, uint64_t address) -> void { + auto context = static_cast(sandbox); + uint64_t hHeap = 0; + uint32_t dwFlags = 0; + uint64_t dwBytes = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = hHeap, rdx = dwFlags, r8 = dwBytes + uc_reg_read(uc, UC_X86_REG_RCX, &hHeap); + uint64_t temp_flags; + uc_reg_read(uc, UC_X86_REG_RDX, &temp_flags); + dwFlags = static_cast(temp_flags); + uc_reg_read(uc, UC_X86_REG_R8, &dwBytes); + } else { + // x86: 从栈上读取参数 + uint32_t esp_address = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); + esp_address += 0x4; // 跳过返回地址 + uint32_t temp_heap; + uc_mem_read(uc, esp_address, &temp_heap, sizeof(uint32_t)); + hHeap = temp_heap; + esp_address += 0x4; + uc_mem_read(uc, esp_address, &dwFlags, sizeof(uint32_t)); + esp_address += 0x4; + uint32_t temp_bytes; + uc_mem_read(uc, esp_address, &temp_bytes, sizeof(uint32_t)); + dwBytes = temp_bytes; + } + + // 检查堆句柄是否有效 + uint64_t expected_handle = + context->GetPeInfo()->isX64 ? HEAP_ADDRESS_64 : HEAP_ADDRESS_32; + if (hHeap != expected_handle) { + uint64_t null_ptr = 0; + uc_reg_write( + uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &null_ptr); + return; + } + + // 获取或创建堆段 + HeapSegment* segment = nullptr; + auto it = context->m_heapSegments.find(hHeap); + if (it == context->m_heapSegments.end()) { + segment = context->CreateHeapSegment( + hHeap, context->GetPeInfo()->isX64 ? HEAP_SIZE_64 : HEAP_SIZE_32); + context->m_heapSegments[hHeap] = segment; + } else { + segment = it->second; + } + + // 分配内存 + uint64_t allocated_address = context->AllocateFromSegment(segment, dwBytes); + + printf( + "[*] HeapAlloc: Handle=0x%llx, Flags=0x%x, Size=0x%llx, " + "Address=0x%llx\n", + hHeap, dwFlags, dwBytes, allocated_address); + + // 返回分配的地址 + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &allocated_address); +} + +// 实现HeapFree API +auto Api_HeapFree(void* sandbox, uc_engine* uc, uint64_t address) -> void { + auto context = static_cast(sandbox); + uint64_t hHeap = 0; + uint32_t dwFlags = 0; + uint64_t lpMem = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = hHeap, rdx = dwFlags, r8 = lpMem + uc_reg_read(uc, UC_X86_REG_RCX, &hHeap); + uint64_t temp_flags; + uc_reg_read(uc, UC_X86_REG_RDX, &temp_flags); + dwFlags = static_cast(temp_flags); + uc_reg_read(uc, UC_X86_REG_R8, &lpMem); + } else { + // x86: 从栈上读取参数 + uint32_t esp_address = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); + esp_address += 0x4; // 跳过返回地址 + uint32_t temp_heap; + uc_mem_read(uc, esp_address, &temp_heap, sizeof(uint32_t)); + hHeap = temp_heap; + esp_address += 0x4; + uc_mem_read(uc, esp_address, &dwFlags, sizeof(uint32_t)); + esp_address += 0x4; + uint32_t temp_mem; + uc_mem_read(uc, esp_address, &temp_mem, sizeof(uint32_t)); + lpMem = temp_mem; + } + + // 释放内存 + bool success = context->FreeBlock(lpMem); + + printf( + "[*] HeapFree: Handle=0x%llx, Flags=0x%x, Address=0x%llx, Success=%d\n", + hHeap, dwFlags, lpMem, success); + + // 返回操作是否成功 + uint64_t result = success ? 1 : 0; + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &result); +} + +// 实现TlsGetValue API +auto Api_TlsGetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void { + auto context = static_cast(sandbox); + uint32_t dwTlsIndex = 0; + uint64_t return_value = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = dwTlsIndex + uint64_t temp_index; + uc_reg_read(uc, UC_X86_REG_RCX, &temp_index); + dwTlsIndex = static_cast(temp_index); + } else { + // x86: 从栈上读取参数 + uint32_t esp_address = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); + esp_address += 0x4; // 跳过返回地址 + uc_mem_read(uc, esp_address, &dwTlsIndex, sizeof(uint32_t)); + } + + // 检查索引是否有效(小于64) + if (dwTlsIndex < 64) { + if (context->GetPeInfo()->isX64) { + auto teb = context->GetTeb64(); + // 检查槽是否已分配(不为nullptr) + if (teb->TlsSlots[dwTlsIndex] != nullptr) { + return_value = + reinterpret_cast(teb->TlsSlots[dwTlsIndex]); + } else { + // 槽未分配,设置LastError + DWORD error = ERROR_INVALID_PARAMETER; + teb->LastErrorValue = error; + } + } else { + auto teb = context->GetTeb32(); + // 检查槽是否已分配(不为0) + if (teb->TlsSlots[dwTlsIndex] != 0) { + return_value = teb->TlsSlots[dwTlsIndex]; + } else { + // 槽未分配,设置LastError + DWORD error = ERROR_INVALID_PARAMETER; + teb->LastErrorValue = error; + } + } + } else { + // 索引无效,设置LastError + DWORD error = ERROR_INVALID_PARAMETER; + if (context->GetPeInfo()->isX64) { + context->GetTeb64()->LastErrorValue = error; + } else { + context->GetTeb32()->LastErrorValue = error; + } + } + + printf("[*] TlsGetValue: Index=0x%x, Value=0x%llx\n", dwTlsIndex, + return_value); + + // 返回TLS槽中的值 + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &return_value); +} + +auto Api_SetLastError(void* sandbox, uc_engine* uc, uint64_t address) -> void { + auto context = static_cast(sandbox); + uint32_t dwErrCode = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = dwErrCode + uint64_t temp_error; + uc_reg_read(uc, UC_X86_REG_RCX, &temp_error); + dwErrCode = static_cast(temp_error); + } else { + // x86: 从栈上读取参数 + uint32_t esp_address = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); + esp_address += 0x4; // 跳过返回地址 + uc_mem_read(uc, esp_address, &dwErrCode, sizeof(uint32_t)); + } + + // 设置LastError值 + if (context->GetPeInfo()->isX64) { + context->GetTeb64()->LastErrorValue = dwErrCode; + } else { + context->GetTeb32()->LastErrorValue = dwErrCode; + } + + printf("[*] SetLastError: Error=0x%x\n", dwErrCode); +} + +auto Api_EnterCriticalSection(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + uint64_t lpCriticalSection = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = lpCriticalSection + uc_reg_read(uc, UC_X86_REG_RCX, &lpCriticalSection); + } else { + // x86: 从栈上读取参数 + uint32_t esp_address = 0; + uint32_t temp_cs = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); + esp_address += 0x4; // 跳过返回地址 + uc_mem_read(uc, esp_address, &temp_cs, sizeof(uint32_t)); + lpCriticalSection = temp_cs; + } + + if (lpCriticalSection != 0) { + RTL_CRITICAL_SECTION cs; + uc_mem_read(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION)); + + // 获取当前线程ID + HANDLE currentThreadHandle = nullptr; + if (context->GetPeInfo()->isX64) { + currentThreadHandle = + (HANDLE)(ULONG_PTR)context->GetTeb64()->ClientId.UniqueThread; + } else { + currentThreadHandle = + (HANDLE)(ULONG_PTR)context->GetTeb32()->ClientId.UniqueThread; + } + + // 如果当前线程已经拥有锁,增加递归计数 + if (cs.OwningThread == currentThreadHandle) { + cs.RecursionCount++; + } else { + // 如果没有线程拥有锁,获取它 + if (cs.LockCount == -1) { + cs.OwningThread = currentThreadHandle; + cs.RecursionCount = 1; + cs.LockCount = 0; + } else { + // 在实际情况下这里应该自旋等待,但在模拟环境中我们直接获取锁 + cs.OwningThread = currentThreadHandle; + cs.RecursionCount = 1; + cs.LockCount++; + } + } + + // 写回更新后的关键段结构 + uc_mem_write(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION)); + } + + printf("[*] EnterCriticalSection: CS=0x%llx\n", lpCriticalSection); +} + +auto Api_LeaveCriticalSection(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + uint64_t lpCriticalSection = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = lpCriticalSection + uc_reg_read(uc, UC_X86_REG_RCX, &lpCriticalSection); + } else { + // x86: 从栈上读取参数 + uint32_t esp_address = 0; + uint32_t temp_cs = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); + esp_address += 0x4; // 跳过返回地址 + uc_mem_read(uc, esp_address, &temp_cs, sizeof(uint32_t)); + lpCriticalSection = temp_cs; + } + + if (lpCriticalSection != 0) { + RTL_CRITICAL_SECTION cs; + uc_mem_read(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION)); + + // 获取当前线程ID + HANDLE currentThreadHandle = nullptr; + if (context->GetPeInfo()->isX64) { + currentThreadHandle = + (HANDLE)(ULONG_PTR)context->GetTeb64()->ClientId.UniqueThread; + } else { + currentThreadHandle = + (HANDLE)(ULONG_PTR)context->GetTeb32()->ClientId.UniqueThread; + } + + // 检查当前线程是否拥有锁 + if (cs.OwningThread == currentThreadHandle) { + cs.RecursionCount--; + if (cs.RecursionCount == 0) { + // 完全释放锁 + cs.OwningThread = nullptr; + cs.LockCount = -1; + } + + // 写回更新后的关键段结构 + uc_mem_write(uc, lpCriticalSection, &cs, + sizeof(RTL_CRITICAL_SECTION)); + } + } + + printf("[*] LeaveCriticalSection: CS=0x%llx\n", lpCriticalSection); +} + +auto Api_GetStartupInfoW(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + uint64_t lpStartupInfo = 0; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = lpStartupInfo + uc_reg_read(uc, UC_X86_REG_RCX, &lpStartupInfo); + } else { + // x86: 从栈上读取参数 + uint32_t esp_address = 0; + uint32_t temp_info = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); + esp_address += 0x4; // 跳过返回地址 + uc_mem_read(uc, esp_address, &temp_info, sizeof(uint32_t)); + lpStartupInfo = temp_info; + } + + if (lpStartupInfo != 0) { + // 创建一个默认的 STARTUPINFOW 结构 + STARTUPINFOW si = {0}; + si.cb = sizeof(STARTUPINFOW); + si.dwFlags = STARTF_USESHOWWINDOW; + si.wShowWindow = SW_SHOWNORMAL; + si.lpDesktop = nullptr; + si.lpTitle = nullptr; + si.dwX = 0; + si.dwY = 0; + si.dwXSize = 0; + si.dwYSize = 0; + si.dwXCountChars = 0; + si.dwYCountChars = 0; + si.dwFillAttribute = 0; + si.cbReserved2 = 0; + si.lpReserved2 = nullptr; + si.hStdInput = nullptr; + si.hStdOutput = nullptr; + si.hStdError = nullptr; + + // 写入结构到目标内存 + uc_mem_write(uc, lpStartupInfo, &si, sizeof(STARTUPINFOW)); + } + + printf("[*] GetStartupInfoW: lpStartupInfo=0x%llx\n", lpStartupInfo); +} + +// 实现 GetStdHandle API +auto Api_GetStdHandle(void* sandbox, uc_engine* uc, uint64_t address) -> void { + auto context = static_cast(sandbox); + int32_t nStdHandle = 0; + HANDLE handle = INVALID_HANDLE_VALUE; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = nStdHandle + uint64_t temp_handle; + uc_reg_read(uc, UC_X86_REG_RCX, &temp_handle); + nStdHandle = static_cast(temp_handle); + } else { + // x86: 从栈上读取参数 + uint32_t esp_address = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); + esp_address += 0x4; // 跳过返回地址 + uc_mem_read(uc, esp_address, &nStdHandle, sizeof(int32_t)); + } + + // 根据请求的标准句柄类型返回相应的句柄 + switch ((unsigned long)nStdHandle) { + case STD_INPUT_HANDLE: // -10 + handle = reinterpret_cast(0x1000); // 模拟标准输入句柄 + break; + case STD_OUTPUT_HANDLE: // -11 + handle = reinterpret_cast(0x2000); // 模拟标准输出句柄 + break; // End of Selection + break; + case STD_ERROR_HANDLE: // -12 + handle = reinterpret_cast(0x3000); // 模拟标准错误句柄 + break; + default: + handle = INVALID_HANDLE_VALUE; + // 设置错误码 + if (context->GetPeInfo()->isX64) { + context->GetTeb64()->LastErrorValue = ERROR_INVALID_PARAMETER; + } else { + context->GetTeb32()->LastErrorValue = ERROR_INVALID_PARAMETER; + } + break; + } + + printf("[*] GetStdHandle: Type=%d, Handle=0x%p\n", nStdHandle, handle); + + // 返回句柄值 + uint64_t return_value = reinterpret_cast(handle); + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &return_value); +} + +// 实现 GetFileType API +auto Api_GetFileType(void* sandbox, uc_engine* uc, uint64_t address) -> void { + auto context = static_cast(sandbox); + HANDLE hFile = nullptr; + + // 获取参数 + if (context->GetPeInfo()->isX64) { + // x64: rcx = hFile + uint64_t temp_handle; + uc_reg_read(uc, UC_X86_REG_RCX, &temp_handle); + hFile = reinterpret_cast(temp_handle); + } else { + // x86: 从栈上读取参数 + uint32_t esp_address = 0; + uint32_t temp_handle = 0; + uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); + esp_address += 0x4; // 跳过返回地址 + uc_mem_read(uc, esp_address, &temp_handle, sizeof(uint32_t)); + hFile = reinterpret_cast(static_cast(temp_handle)); + } + + DWORD file_type = FILE_TYPE_UNKNOWN; + + // 根据标准句柄类型返回相应的文件类型 + if (hFile == reinterpret_cast(0x1000) || // STD_INPUT_HANDLE + hFile == reinterpret_cast(0x2000) || // STD_OUTPUT_HANDLE + hFile == reinterpret_cast(0x3000)) { // STD_ERROR_HANDLE + file_type = FILE_TYPE_CHAR; // 控制台句柄通常是字符设备 + } else { + // 对于无效句柄,设置错误码 + if (context->GetPeInfo()->isX64) { + context->GetTeb64()->LastErrorValue = ERROR_INVALID_HANDLE; + } else { + context->GetTeb32()->LastErrorValue = ERROR_INVALID_HANDLE; + } + file_type = FILE_TYPE_UNKNOWN; + } + + printf("[*] GetFileType: Handle=0x%p, Type=0x%x\n", hFile, file_type); + + // 返回文件类型 + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &file_type); +} + +// 实现 GetCommandLineA API +auto Api_GetCommandLineA(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + printf("[*] GetCommandLineA: CommandLine=%s\n", context->GetCommandLine()); + + // 返回命令行字符串的地址 + uint64_t return_value = context->GetCommandLineAddress(); + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &return_value); +} + +// 实现 GetCommandLineW API +auto Api_GetCommandLineW(void* sandbox, uc_engine* uc, uint64_t address) + -> void { + auto context = static_cast(sandbox); + printf("[*] GetCommandLineW: CommandLine=%s\n", context->GetCommandLine()); + + // 返回宽字符命令行字符串的地址 + uint64_t return_value = context->GetCommandLineWAddress(); + uc_reg_write(uc, + context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + &return_value); +} + +auto Sandbox::CreateHeapSegment(uint64_t base, size_t size) -> HeapSegment* { + auto segment = new HeapSegment(); + segment->base = base; + segment->size = size; + + // 创建初始空闲块 + auto block = new HeapBlock(); + block->address = base; + block->size = size; + block->is_free = true; + block->next = nullptr; + block->prev = nullptr; + + segment->blocks = block; + return segment; +} + +auto Sandbox::AllocateFromSegment(HeapSegment* segment, size_t size) + -> uint64_t { + // 对齐大小到16字节 + size = (size + 15) & ~15; + + // 查找合适的空闲块 + HeapBlock* current = segment->blocks; + while (current != nullptr) { + if (current->is_free && current->size >= size) { + // 如果块太大,分割它 + if (current->size > size + 32) { // 32字节为最小块大小 + SplitBlock(current, size); + } + + current->is_free = false; + return current->address; + } + current = current->next; + } + + return 0; // 分配失败 +} + +auto Sandbox::FreeBlock(uint64_t address) -> bool { + // 查找包含此地址的堆段 + HeapSegment* segment = FindHeapSegment(address); + if (!segment) return false; + + // 查找对应的块 + HeapBlock* current = segment->blocks; + while (current != nullptr) { + if (current->address == address) { + if (current->is_free) return false; // 已经是空闲的 + + current->is_free = true; + MergeBlocks(current); // 尝试合并相邻的空闲块 + return true; + } + current = current->next; + } + + return false; +} + +auto Sandbox::FindHeapSegment(uint64_t address) -> HeapSegment* { + for (auto& pair : m_heapSegments) { + HeapSegment* segment = pair.second; + if (address >= segment->base && + address < segment->base + segment->size) { + return segment; + } + } + return nullptr; +} + +auto Sandbox::MergeBlocks(HeapBlock* block) -> void { + // 与后一个块合并 + if (block->next && block->next->is_free) { + block->size += block->next->size; + HeapBlock* temp = block->next; + block->next = temp->next; + if (block->next) { + block->next->prev = block; + } + delete temp; + } + + // 与前一个块合并 + if (block->prev && block->prev->is_free) { + block->prev->size += block->size; + block->prev->next = block->next; + if (block->next) { + block->next->prev = block->prev; + } + delete block; + } +} + +auto Sandbox::SplitBlock(HeapBlock* block, size_t size) -> void { + size_t remaining_size = block->size - size; + block->size = size; + + auto new_block = new HeapBlock(); + new_block->address = block->address + size; + new_block->size = remaining_size; + new_block->is_free = true; + new_block->next = block->next; + new_block->prev = block; + + if (block->next) { + block->next->prev = new_block; + } + block->next = new_block; +} + +auto Sandbox::InitCommandLine(std::string commandLine) -> void { + // 设置默认的命令行字符串 + m_commandLine = commandLine; + + // 将ANSI命令行字符串写入模拟内存 + uc_mem_map(m_ucEngine, CMDLINE_ADDRESS, PAGE_SIZE, + UC_PROT_READ | UC_PROT_WRITE); + uc_mem_write(m_ucEngine, CMDLINE_ADDRESS, m_commandLine.c_str(), + m_commandLine.length() + 1); + + // 为宽字符命令行分配内存 + uc_mem_map(m_ucEngine, CMDLINEW_ADDRESS, PAGE_SIZE, + UC_PROT_READ | UC_PROT_WRITE); + + // 将ANSI字符串转换为宽字符字符串 + std::wstring wCommandLine(m_commandLine.begin(), m_commandLine.end()); + + // 写入宽字符命令行字符串 + uc_mem_write(m_ucEngine, CMDLINEW_ADDRESS, wCommandLine.c_str(), + (wCommandLine.length() + 1) * sizeof(wchar_t)); +} + +auto Sandbox::InitApiHooks() -> void { + auto FakeApi_GetSystemTimeAsFileTime = + _fakeApi{.func = Api_GetSystemTimeAsFileTime, .paramCount = 1}; + auto FakeApi_GetCurrentThreadId = + _fakeApi{.func = Api_GetCurrentThreadId, .paramCount = 0}; + auto FakeApi_GetCurrentProcessId = + _fakeApi{.func = Api_GetCurrentProcessId, .paramCount = 0}; + auto FakeApi_QueryPerformanceCounter = + _fakeApi{.func = Api_QueryPerformanceCounter, .paramCount = 1}; + auto FakeApi_LoadLibraryA = + _fakeApi{.func = Api_LoadLibraryA, .paramCount = 1}; + auto FakeApi_LoadLibraryExW = + _fakeApi{.func = Api_LoadLibraryExW, .paramCount = 3}; + auto FakeApi_GetLastError = + _fakeApi{.func = Api_GetLastError, .paramCount = 0}; + auto FakeApi_InitializeCriticalSectionAndSpinCount = _fakeApi{ + .func = Api_InitializeCriticalSectionAndSpinCount, .paramCount = 2}; + auto FakeApi_TlsAlloc = _fakeApi{.func = Api_TlsAlloc, .paramCount = 0}; + auto FakeApi_TlsSetValue = + _fakeApi{.func = Api_TlsSetValue, .paramCount = 2}; + auto FakeApi_DeleteCriticalSection = + _fakeApi{.func = Api_DeleteCriticalSection, .paramCount = 1}; + auto FakeApi_IsProcessorFeaturePresent = + _fakeApi{.func = Api_IsProcessorFeaturePresent, .paramCount = 1}; + auto FakeApi_GetProcAddress = + _fakeApi{.func = Api_GetProcAddress, .paramCount = 2}; + auto FakeApi_GetProcessHeap = + _fakeApi{.func = Api_GetProcessHeap, .paramCount = 0}; + auto FakeApi_HeapAlloc = _fakeApi{.func = Api_HeapAlloc, .paramCount = 3}; + auto FakeApi_HeapFree = _fakeApi{.func = Api_HeapFree, .paramCount = 3}; + auto FakeApi_TlsGetValue = + _fakeApi{.func = Api_TlsGetValue, .paramCount = 1}; + auto FakeApi_SetLastError = + _fakeApi{.func = Api_SetLastError, .paramCount = 1}; + auto FakeApi_EnterCriticalSection = + _fakeApi{.func = Api_EnterCriticalSection, .paramCount = 1}; + auto FakeApi_LeaveCriticalSection = + _fakeApi{.func = Api_LeaveCriticalSection, .paramCount = 1}; + auto FakeApi_GetStartupInfoW = + _fakeApi{.func = Api_GetStartupInfoW, .paramCount = 1}; + auto FakeApi_GetStdHandle = + _fakeApi{.func = Api_GetStdHandle, .paramCount = 1}; + auto FakeApi_GetFileType = + _fakeApi{.func = Api_GetFileType, .paramCount = 1}; + auto FakeApi_GetCommandLineA = + _fakeApi{.func = Api_GetCommandLineA, .paramCount = 0}; + auto FakeApi_GetCommandLineW = + _fakeApi{.func = Api_GetCommandLineW, .paramCount = 0}; + + api_map = { + {"GetSystemTimeAsFileTime", + std::make_shared<_fakeApi>(FakeApi_GetSystemTimeAsFileTime)}, + {"GetCurrentThreadId", + std::make_shared<_fakeApi>(FakeApi_GetCurrentThreadId)}, + {"GetCurrentProcessId", + std::make_shared<_fakeApi>(FakeApi_GetCurrentProcessId)}, + {"QueryPerformanceCounter", + std::make_shared<_fakeApi>(FakeApi_QueryPerformanceCounter)}, + {"LoadLibraryA", std::make_shared<_fakeApi>(FakeApi_LoadLibraryA)}, + {"LoadLibraryExW", std::make_shared<_fakeApi>(FakeApi_LoadLibraryExW)}, + {"GetLastError", std::make_shared<_fakeApi>(FakeApi_GetLastError)}, + {"InitializeCriticalSectionAndSpinCount", + std::make_shared<_fakeApi>( + FakeApi_InitializeCriticalSectionAndSpinCount)}, + {"DeleteCriticalSection", + std::make_shared<_fakeApi>(FakeApi_DeleteCriticalSection)}, + {"TlsAlloc", std::make_shared<_fakeApi>(FakeApi_TlsAlloc)}, + {"TlsSetValue", std::make_shared<_fakeApi>(FakeApi_TlsSetValue)}, + {"IsProcessorFeaturePresent", + std::make_shared<_fakeApi>(FakeApi_IsProcessorFeaturePresent)}, + {"GetProcAddress", std::make_shared<_fakeApi>(FakeApi_GetProcAddress)}, + {"GetProcessHeap", std::make_shared<_fakeApi>(FakeApi_GetProcessHeap)}, + {"HeapAlloc", std::make_shared<_fakeApi>(FakeApi_HeapAlloc)}, + {"HeapFree", std::make_shared<_fakeApi>(FakeApi_HeapFree)}, + {"TlsGetValue", std::make_shared<_fakeApi>(FakeApi_TlsGetValue)}, + {"SetLastError", std::make_shared<_fakeApi>(FakeApi_SetLastError)}, + {"EnterCriticalSection", + std::make_shared<_fakeApi>(FakeApi_EnterCriticalSection)}, + {"LeaveCriticalSection", + std::make_shared<_fakeApi>(FakeApi_LeaveCriticalSection)}, + {"GetStartupInfoW", + std::make_shared<_fakeApi>(FakeApi_GetStartupInfoW)}, + {"GetStdHandle", std::make_shared<_fakeApi>(FakeApi_GetStdHandle)}, + {"GetFileType", std::make_shared<_fakeApi>(FakeApi_GetFileType)}, + {"GetCommandLineA", + std::make_shared<_fakeApi>(FakeApi_GetCommandLineA)}, + {"GetCommandLineW", + std::make_shared<_fakeApi>(FakeApi_GetCommandLineW)}}; +} +auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip, + std::string ApiName) -> void { + auto it = api_map.find(ApiName); + if (it != api_map.end()) { + // 调用API函数 + it->second->func(this, uc, address); + + // 获取参数数量 + int paramCount = it->second->paramCount; + + // 获取当前的栈指针 + uint64_t rsp; + uc_reg_read(uc, + this->GetPeInfo()->isX64 ? UC_X86_REG_RSP : UC_X86_REG_ESP, + &rsp); + + // 从栈上读取返回地址 + uint64_t return_address; + if (this->GetPeInfo()->isX64) { // 64位系统 + // 读取8字节的返回地址 + uc_mem_read(uc, rsp, &return_address, 8); + + // x64下,前4个参数通过寄存器传递,超过的部分通过栈传递 + int stack_params = (paramCount > 4) ? (paramCount - 4) : 0; + // 调整栈指针:每个参数8字节 + 返回地址8字节 + rsp += (stack_params * 8) + 8; + + // 设置RIP为返回地址 + uc_reg_write(uc, UC_X86_REG_RIP, &return_address); + } else { // 32位系统 + // 读取4字节的返回地址 + uint32_t return_address_32; + uc_mem_read(uc, rsp, &return_address_32, 4); + + // x86下,所有参数都通过栈传递 + // 调整栈指针:每个参数4字节 + 返回地址4字节 + rsp += (paramCount * 4) + 4; + + // 设置EIP为返回地址 + uc_reg_write(uc, UC_X86_REG_EIP, &return_address_32); + } + + // 更新栈指针,使用正确的寄存器 + uc_reg_write(uc, + this->GetPeInfo()->isX64 ? UC_X86_REG_RSP : UC_X86_REG_ESP, + &rsp); + return; + } + printf("ApiName: %s not found\n", ApiName.c_str()); + uc_emu_stop(uc); + return; +} diff --git a/ai_anti_malware/sandbox_callbacks.cpp b/ai_anti_malware/sandbox_callbacks.cpp index fe45d2b..cb2645b 100644 --- a/ai_anti_malware/sandbox_callbacks.cpp +++ b/ai_anti_malware/sandbox_callbacks.cpp @@ -1 +1,97 @@ #include "sandbox_callbacks.h" +#define LOG_LEVEL 0 +namespace sandboxCallbacks { +void handleCodeRun(uc_engine* uc, uint64_t address, uint32_t size, + void* userData) { + uint64_t currentRip = 0; + uint64_t currentRsp = 0; + uint64_t currentRax = 0; + auto* sandbox = static_cast(userData); + if (!sandbox) return; + + // 读取当前执行的代码 + auto codeBuffer = std::make_unique(size); + if (uc_mem_read(uc, address, codeBuffer.get(), size) != UC_ERR_OK) { + return; + } + + uc_reg_read(uc, + sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + ¤tRax); + uc_reg_read(uc, + sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RIP : UC_X86_REG_EIP, + ¤tRip); + uc_reg_read(uc, + sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RSP : UC_X86_REG_ESP, + ¤tRsp); + for (auto module : sandbox->GetModuleList()) { + 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); + sandbox->EmulateApi(uc, vmAddress, currentRip, item->name); + } + } + } + if (LOG_LEVEL > 0) { + // 使用Capstone反汇编 + cs_insn* instruction; + size_t instructionCount = + cs_disasm(sandbox->GetCapstoneHandle(), codeBuffer.get(), size, + address, 0, &instruction); + if (instructionCount > 0) { + // 打印地址和反汇编结果 + printf("0x%016" PRIx64 " %-12s %s\n", instruction[0].address, + instruction[0].mnemonic, instruction[0].op_str); + } + cs_free(instruction, instructionCount); + } +} + +void handleMemoryRead(uc_engine* uc, uc_mem_type type, uint64_t address, + int size, int64_t value, void* userData) { + auto* sandbox = static_cast(userData); + if (!sandbox) return; + + uint64_t regRax, regRip; + uc_reg_read(uc, + sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, + ®Rax); + uc_reg_read(uc, + sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RIP : UC_X86_REG_EIP, + ®Rip); + + uint64_t readAddress; + auto readError = + uc_mem_read(sandbox->GetUnicornHandle(), address, &readAddress, size); + if (LOG_LEVEL > 0) { + printf( + "[handleMemoryRead] Address: %p Size: %p Rax: %p Rip: %p Error: %d " + "ReadData: %p\n", + address, size, regRax, regRip, readError, readAddress); + } +} + +void handleMemoryUnmapRead(uc_engine* uc, uc_mem_type type, uint64_t address, + int size, int64_t value, void* userData) { + // 待实现 + auto* sandbox = static_cast(userData); + uint64_t Rip = 0; + uc_reg_read(uc, + sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RIP : UC_X86_REG_EIP, + &Rip); + printf("[handleMemoryUnmapRead] Address: %p Size: %p Value: %p Rip: %p\n", + address, size, value, Rip); +} + +void handleMemoryWrite(uc_engine* uc, uc_mem_type type, uint64_t address, + int size, int64_t value, void* userData) { + // 待实现 +} + +void handleSyscall(uc_engine* uc, void* userData) { + // 待实现 +} + +} // namespace sandboxCallbacks diff --git a/ai_anti_malware/sandbox_callbacks.h b/ai_anti_malware/sandbox_callbacks.h index 153ce60..74f390b 100644 --- a/ai_anti_malware/sandbox_callbacks.h +++ b/ai_anti_malware/sandbox_callbacks.h @@ -1,70 +1,16 @@ #pragma once #include "sandbox.h" - namespace sandboxCallbacks { -static void handleCodeRun(uc_engine* uc, uint64_t address, uint32_t size, - void* userData) { - auto* sandbox = static_cast(userData); - if (!sandbox) return; - - // 读取当前执行的代码 - uint8_t* codeBuffer = new uint8_t[size]; - if (uc_mem_read(uc, address, codeBuffer, size) != UC_ERR_OK) { - delete[] codeBuffer; - return; - } - - // 使用Capstone反汇编 - cs_insn* instruction; - size_t instructionCount = - cs_disasm(sandbox->GetCapstoneHandle(), codeBuffer, size, address, 0, - &instruction); - - if (instructionCount > 0) { - // 打印地址和反汇编结果 - printf("0x%016" PRIx64 " %-12s %s\n", instruction[0].address, - instruction[0].mnemonic, instruction[0].op_str); - cs_free(instruction, instructionCount); - } - - delete[] codeBuffer; -} - -static void handleMemoryRead(uc_engine* uc, uc_mem_type type, uint64_t address, - int size, int64_t value, void* userData) { - auto* sandbox = static_cast(userData); - if (!sandbox) return; - - uint64_t regRax, regRip; - uc_reg_read(uc, - sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, - ®Rax); - uc_reg_read(uc, - sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RIP : UC_X86_REG_EIP, - ®Rip); - - uint64_t readAddress; - auto readError = - uc_mem_read(sandbox->GetUnicornHandle(), address, &readAddress, size); - printf( - "[handleMemoryRead] Address: %p Size: %p Rax: %p Rip: %p Error: %d " - "ReadData: %p\n", - address, size, regRax, regRip, readError, readAddress); -} - -static void handleMemoryUnmapRead(uc_engine* uc, uc_mem_type type, +void handleCodeRun(uc_engine* uc, uint64_t address, uint32_t size, + void* userData); +void handleMemoryRead(uc_engine* uc, uc_mem_type type, uint64_t address, + int size, int64_t value, void* userData); +void handleMemoryUnmapRead(uc_engine* uc, uc_mem_type type, uint64_t address, int size, int64_t value, - void* userData) { - // 待实现 -} + void* userData); +void handleMemoryWrite(uc_engine* uc, uc_mem_type type, uint64_t address, + int size, int64_t value, void* userData); +void handleSyscall(uc_engine* uc, void* userData); +auto InitApiHooks() -> void; -static void handleMemoryWrite(uc_engine* uc, uc_mem_type type, uint64_t address, - int size, int64_t value, void* userData) { - // 待实现 -} - -static void handleSyscall(uc_engine* uc, void* userData) { - // 待实现 -} - -} // namespace sandboxCallbacks +}; // namespace sandboxCallbacks