#include "sandbox.h" #include "sandbox_callbacks.h" #include "sandbox_api_winhttp.h" #include #include "sandbox_api_com.h" // 自定义函数:将GUID转换为字符串 void GUIDToString(const GUID& guid, char* str, size_t size) { // GUID格式: {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} snprintf(str, size, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); } // COM API 实现 void Api_CoInitializeEx(void* sandbox, uc_engine* uc, uint64_t address) { auto context = static_cast(sandbox); uint64_t pvReserved = 0; uint32_t dwCoInit = 0; // 获取参数 if (context->GetPeInfo()->isX64) { // x64: rcx = pvReserved, rdx = dwCoInit uc_reg_read(uc, UC_X86_REG_RCX, &pvReserved); uc_reg_read(uc, UC_X86_REG_RDX, &dwCoInit); } else { // x86: 从栈上读取参数 uint32_t esp_address = 0; uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); esp_address += 0x4; // 跳过返回地址 uint32_t temp_reserved; uint32_t temp_coinit; uc_mem_read(uc, esp_address, &temp_reserved, sizeof(uint32_t)); uc_mem_read(uc, esp_address + 0x4, &temp_coinit, sizeof(uint32_t)); pvReserved = temp_reserved; dwCoInit = temp_coinit; } // 打印日志 printf("[*] CoInitializeEx: pvReserved=0x%llx, dwCoInit=0x%x\n", pvReserved, dwCoInit); // 返回S_OK (0) uint32_t result = 0; // S_OK = 0 uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result); } void Api_CoCreateInstance(void* sandbox, uc_engine* uc, uint64_t address) { auto context = static_cast(sandbox); uint64_t rclsid = 0; // REFCLSID uint64_t pUnkOuter = 0; // LPUNKNOWN uint32_t dwClsContext = 0; // DWORD uint64_t riid = 0; // REFIID uint64_t ppv = 0; // LPVOID* // 获取参数 if (context->GetPeInfo()->isX64) { // x64: rcx = rclsid, rdx = pUnkOuter, r8 = dwClsContext, r9 = riid uc_reg_read(uc, UC_X86_REG_RCX, &rclsid); uc_reg_read(uc, UC_X86_REG_RDX, &pUnkOuter); uint64_t temp_context; uc_reg_read(uc, UC_X86_REG_R8, &temp_context); dwClsContext = static_cast(temp_context); uc_reg_read(uc, UC_X86_REG_R9, &riid); // 从栈上读取最后一个参数 uint64_t rsp; uc_reg_read(uc, UC_X86_REG_RSP, &rsp); uc_mem_read(uc, rsp + 0x28, &ppv, 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_params[5]; // 所有参数都是32位的 for (int i = 0; i < 5; i++) { uc_mem_read(uc, esp_address + (i * 4), &temp_params[i], sizeof(uint32_t)); } rclsid = temp_params[0]; pUnkOuter = temp_params[1]; dwClsContext = temp_params[2]; riid = temp_params[3]; ppv = temp_params[4]; } // 读取并打印CLSID CLSID clsid; if (rclsid != 0) { uc_mem_read(uc, rclsid, &clsid, sizeof(CLSID)); // 将CLSID转换为字符串并打印 char clsidStr[40] = {0}; GUIDToString(clsid, clsidStr, sizeof(clsidStr)); printf("[*] CoCreateInstance: CLSID=%s, Context=0x%x\n", clsidStr, dwClsContext); // 也打印IID (接口ID) if (riid != 0) { IID iid; uc_mem_read(uc, riid, &iid, sizeof(IID)); char iidStr[40] = {0}; GUIDToString(iid, iidStr, sizeof(iidStr)); printf("[*] CoCreateInstance: IID=%s\n", iidStr); } } else { printf("[*] CoCreateInstance: CLSID=NULL, Context=0x%x\n", dwClsContext); } // 创建一个假的接口指针 uint64_t fake_interface = 0xABABABABAB; // 如果ppv有效,将fake_interface写入ppv指向的位置 if (ppv != 0) { if (context->GetPeInfo()->isX64) { uc_mem_write(uc, ppv, &fake_interface, sizeof(uint64_t)); } else { uint32_t interface_32 = static_cast(fake_interface); uc_mem_write(uc, (uint32_t)ppv, &interface_32, sizeof(uint32_t)); } } // 返回S_OK (0) uint32_t result = 0; // S_OK = 0 uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result); } void Api_VariantInit(void* sandbox, uc_engine* uc, uint64_t address) { auto context = static_cast(sandbox); uint64_t pvarg = 0; // 指向VARIANT的指针 // 获取参数 if (context->GetPeInfo()->isX64) { // x64: rcx = pvarg uc_reg_read(uc, UC_X86_REG_RCX, &pvarg); } else { // x86: 从栈上读取参数 uint32_t esp_address = 0; uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); esp_address += 0x4; // 跳过返回地址 uint32_t temp_pvarg; uc_mem_read(uc, esp_address, &temp_pvarg, sizeof(uint32_t)); pvarg = temp_pvarg; } // 检查pvarg是否有效 if (pvarg != 0) { // 初始化VARIANT结构体为VT_EMPTY VARTYPE vt = VT_EMPTY; uc_mem_write(uc, pvarg, &vt, sizeof(VARTYPE)); // 清零VARIANT结构体的其余部分 uint8_t zeros[14] = {0}; // VARIANT结构体大小为16字节,前2字节为vt uc_mem_write(uc, pvarg + sizeof(VARTYPE), zeros, sizeof(zeros)); } printf("[*] VariantInit: pvarg=0x%llx\n", pvarg); } void Api_VariantClear(void* sandbox, uc_engine* uc, uint64_t address) { auto context = static_cast(sandbox); uint64_t pvarg = 0; // 指向VARIANT的指针 // 获取参数 if (context->GetPeInfo()->isX64) { // x64: rcx = pvarg uc_reg_read(uc, UC_X86_REG_RCX, &pvarg); } else { // x86: 从栈上读取参数 uint32_t esp_address = 0; uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); esp_address += 0x4; // 跳过返回地址 uint32_t temp_pvarg; uc_mem_read(uc, esp_address, &temp_pvarg, sizeof(uint32_t)); pvarg = temp_pvarg; } // 检查pvarg是否有效 if (pvarg != 0) { // 读取当前的VARIANT类型 VARTYPE vt; uc_mem_read(uc, pvarg, &vt, sizeof(VARTYPE)); // 将类型重置为VT_EMPTY并清零其余部分 vt = VT_EMPTY; uc_mem_write(uc, pvarg, &vt, sizeof(VARTYPE)); uint8_t zeros[14] = {0}; uc_mem_write(uc, pvarg + sizeof(VARTYPE), zeros, sizeof(zeros)); } // 返回S_OK uint32_t result = 0; // S_OK uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &result); printf("[*] VariantClear: pvarg=0x%llx\n", pvarg); } void Api_SysAllocString(void* sandbox, uc_engine* uc, uint64_t address) { auto context = static_cast(sandbox); uint64_t psz = 0; // 源字符串指针 // 获取参数 if (context->GetPeInfo()->isX64) { // x64: rcx = psz uc_reg_read(uc, UC_X86_REG_RCX, &psz); } else { // x86: 从栈上读取参数 uint32_t esp_address = 0; uc_reg_read(uc, UC_X86_REG_ESP, &esp_address); esp_address += 0x4; // 跳过返回地址 uint32_t temp_psz; uc_mem_read(uc, esp_address, &temp_psz, sizeof(uint32_t)); psz = temp_psz; } uint64_t bstr_ptr = 0; // 如果源字符串有效 if (psz != 0) { // 计算源字符串长度 size_t len = 0; wchar_t wch; do { uc_mem_read(uc, psz + (len * sizeof(wchar_t)), &wch, sizeof(wchar_t)); len++; } while (wch != 0 && len < 1024); // 设置一个合理的最大长度限制 len--; // 不包括null终止符 // 为BSTR分配内存:4字节长度 + 字符串内容 + 终止符 size_t bstr_size = sizeof(uint32_t) + (len + 1) * sizeof(wchar_t); bstr_ptr = context->AllocateMemory(bstr_size); if (bstr_ptr != 0) { // 写入字符串长度(字节数) uint32_t byte_len = static_cast(len * sizeof(wchar_t)); uc_mem_write(uc, bstr_ptr, &byte_len, sizeof(uint32_t)); // 写入字符串内容 uint64_t string_offset = bstr_ptr + sizeof(uint32_t); uc_mem_write(uc, string_offset, (void*)psz, byte_len); // 添加终止符 wchar_t null_char = 0; uc_mem_write(uc, string_offset + byte_len, &null_char, sizeof(wchar_t)); // BSTR指针指向字符串内容,不包括长度前缀 bstr_ptr = string_offset; } } // 返回BSTR指针 uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &bstr_ptr); printf("[*] SysAllocString: psz=0x%llx, result=0x%llx\n", psz, bstr_ptr); }