This commit is contained in:
huoji
2025-03-20 19:56:39 +08:00
parent 662e2398eb
commit 8e2e0c19ec
7 changed files with 268 additions and 180 deletions

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#define LOG_LEVEL 0 #define LOG_LEVEL 1
#define _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS
#include <iostream> #include <iostream>

View File

@@ -1000,6 +1000,10 @@ struct moudle_import {
void* function_callback; void* function_callback;
bool is_delayed_import; bool is_delayed_import;
}; };
struct moudle_import_ordinal {
uint64_t function_address;
uint64_t ordinal;
};
struct moudle_section { struct moudle_section {
char name[9]; char name[9];
ULONG base; ULONG base;

View File

@@ -103,9 +103,11 @@ class ImportResolver : public peconv::t_function_resolver {
class cListImportNames : public peconv::ImportThunksCallback { class cListImportNames : public peconv::ImportThunksCallback {
public: public:
cListImportNames(BYTE* _modulePtr, size_t _moduleSize, cListImportNames(BYTE* _modulePtr, size_t _moduleSize,
std::vector<std::shared_ptr<moudle_import>>& name_to_addr) std::vector<std::shared_ptr<moudle_import>>& name_to_addr,
std::vector<std::shared_ptr<moudle_import_ordinal>>& name_to_ordinal)
: ImportThunksCallback(_modulePtr, _moduleSize), : ImportThunksCallback(_modulePtr, _moduleSize),
nameToAddr(name_to_addr) {} nameToAddr(name_to_addr),
ordinalImportFunc(name_to_ordinal) {}
virtual bool processThunks(LPSTR lib_name, ULONG_PTR origFirstThunkPtr, virtual bool processThunks(LPSTR lib_name, ULONG_PTR origFirstThunkPtr,
ULONG_PTR firstThunkPtr) { ULONG_PTR firstThunkPtr) {
@@ -148,10 +150,19 @@ class cListImportNames : public peconv::ImportThunksCallback {
import_data->is_delayed_import = false; import_data->is_delayed_import = false;
nameToAddr.push_back(import_data); nameToAddr.push_back(import_data);
} }
else {
auto importFunc = std::make_shared<moudle_import_ordinal>();
T_FIELD raw_ordinal = desc->u1.Ordinal & (~ordinal_flag);
importFunc->function_address = call_via_rva;
importFunc->ordinal = raw_ordinal;
ordinalImportFunc.push_back(importFunc);
}
return true; return true;
} }
std::vector<std::shared_ptr<moudle_import>>& nameToAddr; std::vector<std::shared_ptr<moudle_import>>& nameToAddr;
std::vector<std::shared_ptr<moudle_import_ordinal>>& ordinalImportFunc;
}; };
class cFixImprot : public peconv::t_function_resolver { class cFixImprot : public peconv::t_function_resolver {
public: public:
@@ -455,8 +466,7 @@ auto Sandbox::ResoveImport() -> void {
peconv::load_delayed_imports(static_cast<BYTE*>(m_peInfo->peBuffer), 0); peconv::load_delayed_imports(static_cast<BYTE*>(m_peInfo->peBuffer), 0);
// 解析导入表 // 解析导入表
cListImportNames importCallback(static_cast<BYTE*>(m_peInfo->peBuffer), cListImportNames importCallback(static_cast<BYTE*>(m_peInfo->peBuffer), m_peInfo->peSize, m_impFuncDict, m_impFuncOrdinalDict);
m_peInfo->peSize, m_impFuncDict);
if (!peconv::process_import_table(static_cast<BYTE*>(m_peInfo->peBuffer), if (!peconv::process_import_table(static_cast<BYTE*>(m_peInfo->peBuffer),
m_peInfo->peSize, &importCallback)) { m_peInfo->peSize, &importCallback)) {

View File

@@ -275,6 +275,8 @@ class Sandbox {
std::vector<std::shared_ptr<moudle_import>> m_impFuncDict; std::vector<std::shared_ptr<moudle_import>> m_impFuncDict;
std::vector<std::shared_ptr<moudle_export>> m_exportFuncDict; std::vector<std::shared_ptr<moudle_export>> m_exportFuncDict;
std::vector<std::shared_ptr<struct_moudle>> m_moduleList; std::vector<std::shared_ptr<struct_moudle>> m_moduleList;
std::vector<std::shared_ptr<moudle_import_ordinal>> m_impFuncOrdinalDict;
std::map<std::string, std::shared_ptr<_fakeApi>> api_map; std::map<std::string, std::shared_ptr<_fakeApi>> api_map;
std::string m_commandLine; // 存储命令行字符串 std::string m_commandLine; // 存储命令行字符串
// 创建一些基本的环境变量 // 创建一些基本的环境变量

View File

@@ -4,179 +4,274 @@
#include <tlhelp32.h> #include <tlhelp32.h>
#include "sandbox_api_com.h" #include "sandbox_api_com.h"
// COM 初始化状态跟踪
static bool g_comInitialized = false;
// 计划任务COM组件具体实现 // 自定义函数将GUID转换为字符串
class TaskServiceImpl : public TaskServiceSimulator { void GUIDToString(const GUID& guid, char* str, size_t size) {
private: // GUID格式: {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
ULONG m_refCount = 1; 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],
public: guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5],
HRESULT QueryInterface(REFIID riid, void** ppv) override { guid.Data4[6], guid.Data4[7]);
// 这里只模拟基本的ITaskService接口
*ppv = this;
AddRef();
return S_OK;
}
ULONG AddRef() override { return ++m_refCount; }
ULONG Release() override {
ULONG ref = --m_refCount;
if (ref == 0) {
delete this;
}
return ref;
}
HRESULT Connect(VARIANT ServerName, VARIANT User, VARIANT Domain,
VARIANT Password) override {
// 模拟连接成功
return S_OK;
}
HRESULT GetFolder(BSTR path, ITaskFolder** ppFolder) override {
// 模拟获取文件夹成功
*ppFolder = nullptr; // 实际使用时需要创建ITaskFolder实现
return S_OK;
}
HRESULT NewTask(DWORD flags, ITaskDefinition** ppDefinition) override {
// 模拟创建新任务成功
*ppDefinition = nullptr; // 实际使用时需要创建ITaskDefinition实现
return S_OK;
}
};
// COM 组件工厂实现
bool ComObjectFactory::IsTaskSchedulerCLSID(const CLSID& clsid) {
// 检查是否是Task Scheduler 2.0 的CLSID
static const CLSID CLSID_TaskScheduler = {
0x0f87369f,
0xa4e5,
0x4cfc,
{0xbd, 0x3e, 0x73, 0xe6, 0x15, 0x45, 0x72, 0xdd}};
return IsEqualCLSID(clsid, CLSID_TaskScheduler);
}
ComObjectSimulator* ComObjectFactory::CreateInstance(const CLSID& clsid) {
if (IsTaskSchedulerCLSID(clsid)) {
return new TaskServiceImpl();
}
return nullptr;
} }
// COM API 实现 // COM API 实现
void Api_CoInitializeEx(void* sandbox, uc_engine* uc, uint64_t address) { void Api_CoInitializeEx(void* sandbox, uc_engine* uc, uint64_t address) {
Sandbox* sb = static_cast<Sandbox*>(sandbox); auto context = static_cast<Sandbox*>(sandbox);
uint64_t pvReserved = 0;
uint32_t dwCoInit = 0;
// 获取参数 // 获取参数
uint32_t pvReserved = 0; if (context->GetPeInfo()->isX64) {
uint32_t dwCoInit = 0; // x64: rcx = pvReserved, rdx = dwCoInit
uc_mem_read(uc, address + 4, &pvReserved, sizeof(pvReserved)); uc_reg_read(uc, UC_X86_REG_RCX, &pvReserved);
uc_mem_read(uc, address + 8, &dwCoInit, sizeof(dwCoInit)); 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; // 跳过返回地址
// 设置COM初始化状态 uint32_t temp_reserved;
g_comInitialized = true; 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;
}
// 返回成功 // 打印日志
uc_reg_write(uc, UC_X86_REG_EAX, &(uint32_t){S_OK}); 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) { void Api_CoCreateInstance(void* sandbox, uc_engine* uc, uint64_t address) {
Sandbox* sb = static_cast<Sandbox*>(sandbox); auto context = static_cast<Sandbox*>(sandbox);
uint64_t rclsid = 0; // REFCLSID
if (!g_comInitialized) { uint64_t pUnkOuter = 0; // LPUNKNOWN
uint32_t result = CO_E_NOTINITIALIZED; uint32_t dwClsContext = 0; // DWORD
uc_reg_write(uc, UC_X86_REG_EAX, &result); uint64_t riid = 0; // REFIID
return; uint64_t ppv = 0; // LPVOID*
}
// 获取参数 // 获取参数
CLSID rclsid; if (context->GetPeInfo()->isX64) {
uint32_t pUnkOuter = 0; // x64: rcx = rclsid, rdx = pUnkOuter, r8 = dwClsContext, r9 = riid
uint32_t dwClsContext = 0; uc_reg_read(uc, UC_X86_REG_RCX, &rclsid);
IID riid; uc_reg_read(uc, UC_X86_REG_RDX, &pUnkOuter);
uint32_t ppv = 0; uint64_t temp_context;
uc_reg_read(uc, UC_X86_REG_R8, &temp_context);
dwClsContext = static_cast<uint32_t>(temp_context);
uc_reg_read(uc, UC_X86_REG_R9, &riid);
uc_mem_read(uc, address + 4, &rclsid, sizeof(rclsid)); // 从栈上读取最后一个参数
uc_mem_read(uc, address + 20, &pUnkOuter, sizeof(pUnkOuter)); uint64_t rsp;
uc_mem_read(uc, address + 24, &dwClsContext, sizeof(dwClsContext)); uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
uc_mem_read(uc, address + 28, &riid, sizeof(riid)); uc_mem_read(uc, rsp + 0x28, &ppv, sizeof(uint64_t));
uc_mem_read(uc, address + 44, &ppv, sizeof(ppv)); } else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
// 创建COM对象 uint32_t temp_params[5]; // 所有参数都是32位的
ComObjectSimulator* obj = ComObjectFactory::CreateInstance(rclsid); for (int i = 0; i < 5; i++) {
if (obj == nullptr) { uc_mem_read(uc, esp_address + (i * 4), &temp_params[i],
uint32_t result = CLASS_E_CLASSNOTAVAILABLE; sizeof(uint32_t));
uc_reg_write(uc, UC_X86_REG_EAX, &result); }
return;
rclsid = temp_params[0];
pUnkOuter = temp_params[1];
dwClsContext = temp_params[2];
riid = temp_params[3];
ppv = temp_params[4];
} }
// 写入对象指针 // 读取并打印CLSID
uint32_t objPtr = reinterpret_cast<uint32_t>(obj); CLSID clsid;
uc_mem_write(uc, ppv, &objPtr, sizeof(objPtr)); if (rclsid != 0) {
uc_mem_read(uc, rclsid, &clsid, sizeof(CLSID));
uint32_t result = S_OK; // 将CLSID转换为字符串并打印
uc_reg_write(uc, UC_X86_REG_EAX, &result); 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<uint32_t>(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) { void Api_VariantInit(void* sandbox, uc_engine* uc, uint64_t address) {
Sandbox* sb = static_cast<Sandbox*>(sandbox); auto context = static_cast<Sandbox*>(sandbox);
uint64_t pvarg = 0; // 指向VARIANT的指针
// 获取VARIANT指针 // 获取参数
uint32_t pvarg = 0; if (context->GetPeInfo()->isX64) {
uc_mem_read(uc, address + 4, &pvarg, sizeof(pvarg)); // 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; // 跳过返回地址
// 初始化VARIANT结构体 uint32_t temp_pvarg;
VARIANT v; uc_mem_read(uc, esp_address, &temp_pvarg, sizeof(uint32_t));
VariantInit(&v); pvarg = temp_pvarg;
}
// 写回初始化后的VARIANT // 检查pvarg是否有效
uc_mem_write(uc, pvarg, &v, sizeof(VARIANT)); if (pvarg != 0) {
// 初始化VARIANT结构体为VT_EMPTY
VARTYPE vt = VT_EMPTY;
uc_mem_write(uc, pvarg, &vt, sizeof(VARTYPE));
uint32_t result = S_OK; // 清零VARIANT结构体的其余部分
uc_reg_write(uc, UC_X86_REG_EAX, &result); 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) { void Api_VariantClear(void* sandbox, uc_engine* uc, uint64_t address) {
Sandbox* sb = static_cast<Sandbox*>(sandbox); auto context = static_cast<Sandbox*>(sandbox);
uint64_t pvarg = 0; // 指向VARIANT的指针
// 获取VARIANT指针 // 获取参数
uint32_t pvarg = 0; if (context->GetPeInfo()->isX64) {
uc_mem_read(uc, address + 4, &pvarg, sizeof(pvarg)); // 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; // 跳过返回地址
// 读取VARIANT结构体 uint32_t temp_pvarg;
VARIANT v; uc_mem_read(uc, esp_address, &temp_pvarg, sizeof(uint32_t));
uc_mem_read(uc, pvarg, &v, sizeof(VARIANT)); pvarg = temp_pvarg;
}
// 清理VARIANT // 检查pvarg是否有效
VariantClear(&v); if (pvarg != 0) {
// 读取当前的VARIANT类型
VARTYPE vt;
uc_mem_read(uc, pvarg, &vt, sizeof(VARTYPE));
// 写回清理后的VARIANT // 将类型重置为VT_EMPTY并清零其余部分
uc_mem_write(uc, pvarg, &v, sizeof(VARIANT)); vt = VT_EMPTY;
uc_mem_write(uc, pvarg, &vt, sizeof(VARTYPE));
uint32_t result = S_OK; uint8_t zeros[14] = {0};
uc_reg_write(uc, UC_X86_REG_EAX, &result); 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) { void Api_SysAllocString(void* sandbox, uc_engine* uc, uint64_t address) {
Sandbox* sb = static_cast<Sandbox*>(sandbox); auto context = static_cast<Sandbox*>(sandbox);
uint64_t psz = 0; // 源字符串指针
// 获取字符串指针 // 获取参数
uint32_t psz = 0; if (context->GetPeInfo()->isX64) {
uc_mem_read(uc, address + 4, &psz, sizeof(psz)); // 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;
wchar_t buffer[MAX_PATH]; uc_mem_read(uc, esp_address, &temp_psz, sizeof(uint32_t));
uc_mem_read(uc, psz, buffer, sizeof(buffer)); psz = temp_psz;
}
// 分配BSTR uint64_t bstr_ptr = 0;
BSTR bstr = SysAllocString(buffer);
// 如果源字符串有效
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<uint32_t>(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指针 // 返回BSTR指针
uint32_t result = reinterpret_cast<uint32_t>(bstr); uc_reg_write(uc,
uc_reg_write(uc, UC_X86_REG_EAX, &result); 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);
} }

View File

@@ -1,52 +1,11 @@
#pragma once #pragma once
#include <windows.h> #include <windows.h>
#include <combaseapi.h> #include <combaseapi.h>
#include <unicorn/unicorn.h>
#include "sandbox.h" #include "sandbox.h"
// 辅助函数声明
void read_from_unicorn(uc_engine* uc, uint64_t address, void* buffer,
size_t size);
void write_to_unicorn(uc_engine* uc, uint64_t address, const void* buffer,
size_t size);
void set_return_value(uc_engine* uc, uint32_t value);
// COM 组件接口定义
struct ITaskService;
struct ITaskFolder;
struct ITaskDefinition;
struct IRegisteredTask;
// COM 组件模拟器基类
class ComObjectSimulator {
public:
virtual ~ComObjectSimulator() = default;
virtual HRESULT QueryInterface(REFIID riid, void** ppv) = 0;
virtual ULONG AddRef() = 0;
virtual ULONG Release() = 0;
};
// 计划任务COM组件模拟器
class TaskServiceSimulator : public ComObjectSimulator {
public:
virtual HRESULT Connect(VARIANT ServerName, VARIANT User, VARIANT Domain,
VARIANT Password) = 0;
virtual HRESULT GetFolder(BSTR path, ITaskFolder** ppFolder) = 0;
virtual HRESULT NewTask(DWORD flags, ITaskDefinition** ppDefinition) = 0;
};
// COM API 模拟函数声明 // COM API 模拟函数声明
void Api_CoInitializeEx(void* sandbox, uc_engine* uc, uint64_t address); void Api_CoInitializeEx(void* sandbox, uc_engine* uc, uint64_t address);
void Api_CoCreateInstance(void* sandbox, uc_engine* uc, uint64_t address); void Api_CoCreateInstance(void* sandbox, uc_engine* uc, uint64_t address);
void Api_VariantInit(void* sandbox, uc_engine* uc, uint64_t address); void Api_VariantInit(void* sandbox, uc_engine* uc, uint64_t address);
void Api_VariantClear(void* sandbox, uc_engine* uc, uint64_t address); void Api_VariantClear(void* sandbox, uc_engine* uc, uint64_t address);
void Api_SysAllocString(void* sandbox, uc_engine* uc, uint64_t address); void Api_SysAllocString(void* sandbox, uc_engine* uc, uint64_t address);
// COM 组件工厂
class ComObjectFactory {
public:
static ComObjectSimulator* CreateInstance(const CLSID& clsid);
private:
static bool IsTaskSchedulerCLSID(const CLSID& clsid);
};

View File

@@ -1,6 +1,7 @@
#include "sandbox.h" #include "sandbox.h"
#include "sandbox_callbacks.h" #include "sandbox_callbacks.h"
#include "sandbox_api_winhttp.h" #include "sandbox_api_winhttp.h"
#include "sandbox_api_com.h"
#include <tlhelp32.h> #include <tlhelp32.h>
auto Api_QueryPerformanceCounter(void* sandbox, uc_engine* uc, uint64_t address) auto Api_QueryPerformanceCounter(void* sandbox, uc_engine* uc, uint64_t address)
@@ -1362,6 +1363,17 @@ auto Sandbox::InitApiHooks() -> void {
auto FakeApi__initterm_e = auto FakeApi__initterm_e =
_fakeApi{.func = Api__initterm_e, .paramCount = 2}; _fakeApi{.func = Api__initterm_e, .paramCount = 2};
auto FakeApi_getenv = _fakeApi{.func = Api_getenv, .paramCount = 1}; auto FakeApi_getenv = _fakeApi{.func = Api_getenv, .paramCount = 1};
// 添加COM API
auto FakeApi_CoInitializeEx =
_fakeApi{.func = Api_CoInitializeEx, .paramCount = 2};
auto FakeApi_CoCreateInstance =
_fakeApi{.func = Api_CoCreateInstance, .paramCount = 5};
auto FakeApi_VariantInit =
_fakeApi{.func = Api_VariantInit, .paramCount = 1};
auto FakeApi_VariantClear =
_fakeApi{.func = Api_VariantClear, .paramCount = 1};
auto FakeApi_SysAllocString =
_fakeApi{.func = Api_SysAllocString, .paramCount = 1};
api_map = { api_map = {
{"GetSystemTimeAsFileTime", {"GetSystemTimeAsFileTime",
@@ -1499,6 +1511,12 @@ auto Sandbox::InitApiHooks() -> void {
{"GetStringTypeW", std::make_shared<_fakeApi>(FakeApi_GetStringTypeW)}, {"GetStringTypeW", std::make_shared<_fakeApi>(FakeApi_GetStringTypeW)},
{"LCMapStringW", std::make_shared<_fakeApi>(FakeApi_LCMapStringW)}, {"LCMapStringW", std::make_shared<_fakeApi>(FakeApi_LCMapStringW)},
{"getenv", std::make_shared<_fakeApi>(FakeApi_getenv)}, {"getenv", std::make_shared<_fakeApi>(FakeApi_getenv)},
{"CoInitializeEx", std::make_shared<_fakeApi>(FakeApi_CoInitializeEx)},
{"CoCreateInstance",
std::make_shared<_fakeApi>(FakeApi_CoCreateInstance)},
{"VariantInit", std::make_shared<_fakeApi>(FakeApi_VariantInit)},
{"VariantClear", std::make_shared<_fakeApi>(FakeApi_VariantClear)},
{"SysAllocString", std::make_shared<_fakeApi>(FakeApi_SysAllocString)},
}; };
} }
auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip, auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip,