添加沙箱功能和API钩子支持

- 在沙箱中实现了新的功能,包括内存分配和API钩子初始化
- 更新了沙箱类,增加了对WFP引擎的支持
- 添加了多个API的实现,如GetLastError、InitializeCriticalSection等
- 修改了主函数以使用新的沙箱功能,替换了恶意软件扫描功能
- 更新了项目文件以包含新的源文件和API实现
- 改进了错误处理和日志记录功能
This commit is contained in:
huoji
2025-03-18 20:49:18 +08:00
parent 4f3f4c7205
commit 534b6a84a6
15 changed files with 2443 additions and 754 deletions

View File

@@ -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*>(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*>(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<uint32_t>(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*>(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<uint32_t>(temp_spin_count);
uint64_t temp_flags = 0;
uc_reg_read(uc, UC_X86_REG_R8, &temp_flags);
dwFlags = static_cast<uint32_t>(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*>(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*>(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<uint32_t>(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<uint32_t>(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*>(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*>(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<uint32_t>(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*>(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<int32_t>(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*>(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<uint32_t>(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; // 分配失败
}
}
auto Api_CloseHandle(void* sandbox, uc_engine* uc, uint64_t address) -> void {
auto context = static_cast<Sandbox*>(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<uint32_t>(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*>(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*>(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<uint32_t>(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;
}
}
}