添加沙箱功能和API钩子支持
- 在沙箱中实现了新的功能,包括内存分配和API钩子初始化 - 更新了沙箱类,增加了对WFP引擎的支持 - 添加了多个API的实现,如GetLastError、InitializeCriticalSection等 - 修改了主函数以使用新的沙箱功能,替换了恶意软件扫描功能 - 更新了项目文件以包含新的源文件和API实现 - 改进了错误处理和日志记录功能
This commit is contained in:
@@ -1,47 +1,7 @@
|
||||
#include "sandbox.h"
|
||||
#include "sandbox_callbacks.h"
|
||||
#include "sandbox_api_winhttp.h"
|
||||
std::string getDllNameFromApiSetMap(const std::string& apiSet);
|
||||
auto Api_RegOpenKeyExW(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||
auto Api_RegCloseKey(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||
auto Api_AreFileApisANSI(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void;
|
||||
auto Api_WideCharToMultiByte(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void;
|
||||
auto Api_InitializeSListHead(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void;
|
||||
;
|
||||
auto Api_GetEnvironmentStringsW(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void;
|
||||
;
|
||||
auto Api_FreeEnvironmentStringsW(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void;
|
||||
auto Api_GetProcessHeap(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||
auto Api_HeapAlloc(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||
auto Api_HeapFree(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||
auto Api_TlsGetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||
auto Api_SetLastError(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||
auto Api_EnterCriticalSection(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void;
|
||||
auto Api_LeaveCriticalSection(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void;
|
||||
auto Api_GetStartupInfoW(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void;
|
||||
auto Api_GetStdHandle(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||
auto Api_GetFileType(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||
auto Api_HeapCreate(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||
auto Api_GetCommandLineA(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void;
|
||||
auto Api_GetCommandLineW(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void;
|
||||
auto Api_GetACP(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||
auto Api_GetCPInfo(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||
auto Api_MultiByteToWideChar(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void;
|
||||
auto Api_SHGetKnownFolderPath(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void;
|
||||
auto Api_EncodePointer(void* sandbox, uc_engine* uc, uint64_t address) -> void;
|
||||
|
||||
#include <tlhelp32.h>
|
||||
auto Api_QueryPerformanceCounter(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void {
|
||||
auto context = static_cast<Sandbox*>(sandbox);
|
||||
@@ -89,6 +49,21 @@ void Api_GetCurrentProcessId(void* sandbox, uc_engine* uc, uint64_t address) {
|
||||
&context->GetTeb32()->ClientId.UniqueProcess);
|
||||
}
|
||||
}
|
||||
auto Api_GetCurrentThread(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void {
|
||||
auto context = static_cast<Sandbox*>(sandbox);
|
||||
|
||||
// GetCurrentThread 总是返回伪句柄值 -1 (0xFFFFFFFF)
|
||||
uint64_t pseudo_handle = static_cast<uint64_t>(-1);
|
||||
|
||||
// 根据架构写入返回值
|
||||
uc_reg_write(uc,
|
||||
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||||
&pseudo_handle);
|
||||
|
||||
printf("[*] GetCurrentThread called, returning pseudo-handle 0x%llx\n",
|
||||
pseudo_handle);
|
||||
}
|
||||
auto Api_LoadLibraryA(void* sandbox, uc_engine* uc, uint64_t address) -> void {
|
||||
auto context = static_cast<Sandbox*>(sandbox);
|
||||
uint64_t params_address = 0;
|
||||
@@ -224,380 +199,6 @@ auto Api_LoadLibraryExW(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||||
&return_address);
|
||||
}
|
||||
void Api_GetLastError(void* sandbox, uc_engine* uc, uint64_t address) {
|
||||
auto context = static_cast<Sandbox*>(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_GetProcAddress(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void {
|
||||
auto context = static_cast<Sandbox*>(sandbox);
|
||||
@@ -1038,83 +639,6 @@ auto Api_VirtualProtect(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
&result);
|
||||
}
|
||||
|
||||
auto Api___set_app_type(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void {
|
||||
auto context = static_cast<Sandbox*>(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);
|
||||
}
|
||||
}
|
||||
|
||||
auto Api_Sleep(void* sandbox, uc_engine* uc, uint64_t address) -> void {
|
||||
auto context = static_cast<Sandbox*>(sandbox);
|
||||
uint64_t milliseconds;
|
||||
@@ -1134,242 +658,7 @@ auto Api_Sleep(void* sandbox, uc_engine* uc, uint64_t address) -> void {
|
||||
// 打印日志
|
||||
printf("Sleep API called with %u milliseconds\n", milliseconds);
|
||||
}
|
||||
// 内部实现函数,处理实际的模块句柄获取逻辑
|
||||
auto GetModuleHandleInternal(void* sandbox, const std::wstring& moduleName)
|
||||
-> HMODULE {
|
||||
auto* sb = static_cast<Sandbox*>(sandbox);
|
||||
|
||||
// 如果模块名为空,返回当前进程的基址
|
||||
if (moduleName.empty()) {
|
||||
return reinterpret_cast<HMODULE>(sb->GetPeInfo()->RecImageBase);
|
||||
}
|
||||
|
||||
// 在已加载的模块中查找
|
||||
for (const auto& module : sb->GetModuleList()) {
|
||||
std::string currentModuleNameA = module->name;
|
||||
std::wstring currentModuleName =
|
||||
std::wstring(currentModuleNameA.begin(), currentModuleNameA.end());
|
||||
if (_wcsicmp(currentModuleName.c_str(), moduleName.c_str()) == 0) {
|
||||
return reinterpret_cast<HMODULE>(module->base);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// GetModuleHandleA的实现
|
||||
auto Api_GetModuleHandleA(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void {
|
||||
auto* sb = static_cast<Sandbox*>(sandbox);
|
||||
uint64_t esp = 0, rsp = 0;
|
||||
HMODULE result = nullptr;
|
||||
|
||||
if (sb->GetPeInfo()->isX64) {
|
||||
// 获取第一个参数 (rcx)
|
||||
uint64_t moduleNamePtr;
|
||||
uc_reg_read(uc, UC_X86_REG_RCX, &moduleNamePtr);
|
||||
uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
|
||||
|
||||
std::string moduleName;
|
||||
if (moduleNamePtr != 0) {
|
||||
// 读取ANSI字符串
|
||||
char ch;
|
||||
size_t i = 0;
|
||||
do {
|
||||
if (uc_mem_read(uc, moduleNamePtr + i, &ch, 1) != UC_ERR_OK) {
|
||||
break;
|
||||
}
|
||||
if (ch == 0) break;
|
||||
moduleName += ch;
|
||||
i++;
|
||||
} while (i < MAX_PATH);
|
||||
}
|
||||
|
||||
// 转换为宽字符
|
||||
std::wstring wModuleName;
|
||||
if (!moduleName.empty()) {
|
||||
wModuleName = std::wstring(moduleName.begin(), moduleName.end());
|
||||
}
|
||||
|
||||
// 获取模块句柄
|
||||
result = GetModuleHandleInternal(sandbox, wModuleName);
|
||||
|
||||
// 设置返回值
|
||||
uc_reg_write(uc, UC_X86_REG_RAX, &result);
|
||||
|
||||
} else {
|
||||
// 32位实现
|
||||
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
|
||||
uint32_t moduleNamePtr;
|
||||
uc_mem_read(uc, esp + 4, &moduleNamePtr, sizeof(moduleNamePtr));
|
||||
|
||||
std::string moduleName;
|
||||
if (moduleNamePtr != 0) {
|
||||
// 读取ANSI字符串
|
||||
char ch;
|
||||
size_t i = 0;
|
||||
do {
|
||||
if (uc_mem_read(uc, moduleNamePtr + i, &ch, 1) != UC_ERR_OK) {
|
||||
break;
|
||||
}
|
||||
if (ch == 0) break;
|
||||
moduleName += ch;
|
||||
i++;
|
||||
} while (i < MAX_PATH);
|
||||
}
|
||||
|
||||
// 转换为宽字符
|
||||
std::wstring wModuleName;
|
||||
if (!moduleName.empty()) {
|
||||
wModuleName = std::wstring(moduleName.begin(), moduleName.end());
|
||||
}
|
||||
|
||||
// 获取模块句柄
|
||||
result = GetModuleHandleInternal(sandbox, wModuleName);
|
||||
|
||||
// 设置返回值
|
||||
uint32_t result32 = reinterpret_cast<uint32_t>(result);
|
||||
uc_reg_write(uc, UC_X86_REG_EAX, &result32);
|
||||
}
|
||||
|
||||
// 设置错误码
|
||||
DWORD error = result ? 0 : ERROR_MOD_NOT_FOUND;
|
||||
if (sb->GetPeInfo()->isX64) {
|
||||
sb->GetTeb64()->LastErrorValue = error;
|
||||
} else {
|
||||
sb->GetTeb32()->LastErrorValue = error;
|
||||
}
|
||||
}
|
||||
|
||||
// GetModuleHandleW的实现
|
||||
auto Api_GetModuleHandleW(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void {
|
||||
auto* sb = static_cast<Sandbox*>(sandbox);
|
||||
uint64_t esp = 0, rsp = 0;
|
||||
HMODULE result = nullptr;
|
||||
|
||||
if (sb->GetPeInfo()->isX64) {
|
||||
// 获取第一个参数 (rcx)
|
||||
uint64_t moduleNamePtr;
|
||||
uc_reg_read(uc, UC_X86_REG_RCX, &moduleNamePtr);
|
||||
uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
|
||||
|
||||
std::wstring moduleName;
|
||||
if (moduleNamePtr != 0) {
|
||||
// 读取宽字符串
|
||||
wchar_t ch;
|
||||
size_t i = 0;
|
||||
do {
|
||||
if (uc_mem_read(uc, moduleNamePtr + (i * 2), &ch, 2) !=
|
||||
UC_ERR_OK) {
|
||||
break;
|
||||
}
|
||||
if (ch == 0) break;
|
||||
moduleName += ch;
|
||||
i++;
|
||||
} while (i < MAX_PATH);
|
||||
}
|
||||
|
||||
// 获取模块句柄
|
||||
result = GetModuleHandleInternal(sandbox, moduleName);
|
||||
|
||||
// 设置返回值
|
||||
uc_reg_write(uc, UC_X86_REG_RAX, &result);
|
||||
|
||||
} else {
|
||||
// 32位实现
|
||||
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
|
||||
uint32_t moduleNamePtr;
|
||||
uc_mem_read(uc, esp + 4, &moduleNamePtr, sizeof(moduleNamePtr));
|
||||
|
||||
std::wstring moduleName;
|
||||
if (moduleNamePtr != 0) {
|
||||
// 读取宽字符串
|
||||
wchar_t ch;
|
||||
size_t i = 0;
|
||||
do {
|
||||
if (uc_mem_read(uc, moduleNamePtr + (i * 2), &ch, 2) !=
|
||||
UC_ERR_OK) {
|
||||
break;
|
||||
}
|
||||
if (ch == 0) break;
|
||||
moduleName += ch;
|
||||
i++;
|
||||
} while (i < MAX_PATH);
|
||||
}
|
||||
|
||||
// 获取模块句柄
|
||||
result = GetModuleHandleInternal(sandbox, moduleName);
|
||||
|
||||
// 设置返回值
|
||||
uint32_t result32 = reinterpret_cast<uint32_t>(result);
|
||||
uc_reg_write(uc, UC_X86_REG_EAX, &result32);
|
||||
}
|
||||
|
||||
// 设置错误码
|
||||
DWORD error = result ? 0 : ERROR_MOD_NOT_FOUND;
|
||||
if (sb->GetPeInfo()->isX64) {
|
||||
sb->GetTeb64()->LastErrorValue = error;
|
||||
} else {
|
||||
sb->GetTeb32()->LastErrorValue = error;
|
||||
}
|
||||
}
|
||||
auto Api_VirtualQuery(void* sandbox, uc_engine* uc, uint64_t address) -> void {
|
||||
auto* context = static_cast<Sandbox*>(sandbox);
|
||||
uint64_t lpAddress = 0;
|
||||
uint64_t lpBuffer = 0;
|
||||
uint32_t dwLength = 0;
|
||||
|
||||
// 获取参数
|
||||
if (context->GetPeInfo()->isX64) {
|
||||
// 64位参数获取
|
||||
uc_reg_read(uc, UC_X86_REG_RCX, &lpAddress);
|
||||
uc_reg_read(uc, UC_X86_REG_RDX, &lpBuffer);
|
||||
uint64_t temp_length = 0;
|
||||
uc_reg_read(uc, UC_X86_REG_R8, &temp_length);
|
||||
dwLength = static_cast<uint32_t>(temp_length);
|
||||
} else {
|
||||
// 32位参数获取
|
||||
uint32_t esp = 0;
|
||||
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
|
||||
esp += 0x4; // 跳过返回地址
|
||||
|
||||
uint32_t temp_address = 0;
|
||||
uint32_t temp_buffer = 0;
|
||||
uc_mem_read(uc, esp, &temp_address, sizeof(uint32_t));
|
||||
uc_mem_read(uc, esp + 0x4, &temp_buffer, sizeof(uint32_t));
|
||||
uc_mem_read(uc, esp + 0x8, &dwLength, sizeof(uint32_t));
|
||||
|
||||
lpAddress = temp_address;
|
||||
lpBuffer = temp_buffer;
|
||||
}
|
||||
|
||||
// 构造MEMORY_BASIC_INFORMATION结构
|
||||
MEMORY_BASIC_INFORMATION mbi = {};
|
||||
mbi.BaseAddress =
|
||||
reinterpret_cast<void*>(static_cast<uintptr_t>(lpAddress));
|
||||
mbi.AllocationBase = mbi.BaseAddress;
|
||||
mbi.AllocationProtect = PAGE_EXECUTE_READWRITE; // 默认保护属性
|
||||
mbi.RegionSize = 0x1000; // 默认页大小
|
||||
mbi.State = MEM_COMMIT;
|
||||
mbi.Protect = PAGE_EXECUTE_READWRITE;
|
||||
mbi.Type = MEM_PRIVATE;
|
||||
|
||||
// 写入查询结果
|
||||
uint64_t return_value = 0;
|
||||
if (lpBuffer != 0 && dwLength >= sizeof(MEMORY_BASIC_INFORMATION)) {
|
||||
uc_mem_write(uc, lpBuffer, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
|
||||
return_value = sizeof(MEMORY_BASIC_INFORMATION);
|
||||
}
|
||||
|
||||
// 设置返回值
|
||||
if (context->GetPeInfo()->isX64) {
|
||||
uc_reg_write(uc, UC_X86_REG_RAX, &return_value);
|
||||
} else {
|
||||
uint32_t return_value_32 = static_cast<uint32_t>(return_value);
|
||||
uc_reg_write(uc, UC_X86_REG_EAX, &return_value_32);
|
||||
}
|
||||
}
|
||||
auto Sandbox::InitApiHooks() -> void {
|
||||
auto FakeApi_GetSystemTimeAsFileTime =
|
||||
_fakeApi{.func = Api_GetSystemTimeAsFileTime, .paramCount = 1};
|
||||
@@ -1377,6 +666,8 @@ auto Sandbox::InitApiHooks() -> void {
|
||||
_fakeApi{.func = Api_GetCurrentThreadId, .paramCount = 0};
|
||||
auto FakeApi_GetCurrentProcessId =
|
||||
_fakeApi{.func = Api_GetCurrentProcessId, .paramCount = 0};
|
||||
auto FakeApi_GetCurrentThread =
|
||||
_fakeApi{.func = Api_GetCurrentThread, .paramCount = 0};
|
||||
auto FakeApi_QueryPerformanceCounter =
|
||||
_fakeApi{.func = Api_QueryPerformanceCounter, .paramCount = 1};
|
||||
auto FakeApi_LoadLibraryA =
|
||||
@@ -1468,6 +759,48 @@ auto Sandbox::InitApiHooks() -> void {
|
||||
_fakeApi{.func = Api_GetModuleHandleW, .paramCount = 1};
|
||||
auto FakeApi_VirtualQuery =
|
||||
_fakeApi{.func = Api_VirtualQuery, .paramCount = 3};
|
||||
auto FakeApi_Process32FirstW =
|
||||
_fakeApi{.func = Api_Process32FirstW, .paramCount = 2};
|
||||
auto FakeApi_CreateToolhelp32Snapshot =
|
||||
_fakeApi{.func = Api_CreateToolhelp32Snapshot, .paramCount = 2};
|
||||
auto FakeApi_Process32NextW =
|
||||
_fakeApi{.func = Api_Process32NextW, .paramCount = 2};
|
||||
auto FakeApi_CloseHandle =
|
||||
_fakeApi{.func = Api_CloseHandle, .paramCount = 1};
|
||||
auto FakeApi_RtlFormatCurrentUserKeyPath =
|
||||
_fakeApi{.func = Api_RtlFormatCurrentUserKeyPath, .paramCount = 1};
|
||||
auto FakeApi_FlsSetValue =
|
||||
_fakeApi{.func = Api_FlsSetValue, .paramCount = 2};
|
||||
auto FakeApi_CreatePipe = _fakeApi{.func = Api_CreatePipe, .paramCount = 4};
|
||||
auto FakeApi_CreateProcessA =
|
||||
_fakeApi{.func = Api_CreateProcessA, .paramCount = 10};
|
||||
auto FakeApi_ReadFile = _fakeApi{.func = Api_ReadFile, .paramCount = 5};
|
||||
auto FakeApi_WlanOpenHandle =
|
||||
_fakeApi{.func = Api_WlanOpenHandle, .paramCount = 4};
|
||||
auto FakeApi_WlanEnumInterfaces =
|
||||
_fakeApi{.func = Api_WlanEnumInterfaces, .paramCount = 3};
|
||||
auto FakeApi_WlanGetProfileList =
|
||||
_fakeApi{.func = Api_WlanGetProfileList, .paramCount = 4};
|
||||
auto FakeApi_WlanFreeMemory =
|
||||
_fakeApi{.func = Api_WlanFreeMemory, .paramCount = 1};
|
||||
auto FakeApi_WlanCloseHandle =
|
||||
_fakeApi{.func = Api_WlanCloseHandle, .paramCount = 2};
|
||||
auto FakeApi_GetCurrentProcess =
|
||||
_fakeApi{.func = Api_GetCurrentProcess, .paramCount = 0};
|
||||
auto FakeApi_OpenProcessToken =
|
||||
_fakeApi{.func = Api_OpenProcessToken, .paramCount = 3};
|
||||
auto FakeApi_GetTokenInformation =
|
||||
_fakeApi{.func = Api_GetTokenInformation, .paramCount = 5};
|
||||
// 添加WFP相关API
|
||||
auto FakeApi_FwpmEngineOpen0 =
|
||||
_fakeApi{.func = Api_FwpmEngineOpen0, .paramCount = 5};
|
||||
auto FakeApi_FwpmProviderAdd0 =
|
||||
_fakeApi{.func = Api_FwpmProviderAdd0, .paramCount = 3};
|
||||
auto FakeApi_FwpmFilterAdd0 =
|
||||
_fakeApi{.func = Api_FwpmFilterAdd0, .paramCount = 4};
|
||||
auto FakeApi_FwpmEngineClose0 =
|
||||
_fakeApi{.func = Api_FwpmEngineClose0, .paramCount = 1};
|
||||
|
||||
api_map = {
|
||||
{"GetSystemTimeAsFileTime",
|
||||
std::make_shared<_fakeApi>(FakeApi_GetSystemTimeAsFileTime)},
|
||||
@@ -1475,6 +808,8 @@ auto Sandbox::InitApiHooks() -> void {
|
||||
std::make_shared<_fakeApi>(FakeApi_GetCurrentThreadId)},
|
||||
{"GetCurrentProcessId",
|
||||
std::make_shared<_fakeApi>(FakeApi_GetCurrentProcessId)},
|
||||
{"GetCurrentThread",
|
||||
std::make_shared<_fakeApi>(FakeApi_GetCurrentThread)},
|
||||
{"QueryPerformanceCounter",
|
||||
std::make_shared<_fakeApi>(FakeApi_QueryPerformanceCounter)},
|
||||
{"LoadLibraryA", std::make_shared<_fakeApi>(FakeApi_LoadLibraryA)},
|
||||
@@ -1550,6 +885,40 @@ auto Sandbox::InitApiHooks() -> void {
|
||||
{"GetModuleHandleW",
|
||||
std::make_shared<_fakeApi>(FakeApi_GetModuleHandleW)},
|
||||
{"VirtualQuery", std::make_shared<_fakeApi>(FakeApi_VirtualQuery)},
|
||||
{"Process32FirstW",
|
||||
std::make_shared<_fakeApi>(FakeApi_Process32FirstW)},
|
||||
{"CreateToolhelp32Snapshot",
|
||||
std::make_shared<_fakeApi>(FakeApi_CreateToolhelp32Snapshot)},
|
||||
{"Process32NextW", std::make_shared<_fakeApi>(FakeApi_Process32NextW)},
|
||||
{"CloseHandle", std::make_shared<_fakeApi>(FakeApi_CloseHandle)},
|
||||
{"RtlFormatCurrentUserKeyPath",
|
||||
std::make_shared<_fakeApi>(FakeApi_RtlFormatCurrentUserKeyPath)},
|
||||
{"FlsSetValue", std::make_shared<_fakeApi>(FakeApi_FlsSetValue)},
|
||||
{"CreatePipe", std::make_shared<_fakeApi>(FakeApi_CreatePipe)},
|
||||
{"CreateProcessA", std::make_shared<_fakeApi>(FakeApi_CreateProcessA)},
|
||||
{"ReadFile", std::make_shared<_fakeApi>(FakeApi_ReadFile)},
|
||||
{"WlanOpenHandle", std::make_shared<_fakeApi>(FakeApi_WlanOpenHandle)},
|
||||
{"WlanEnumInterfaces",
|
||||
std::make_shared<_fakeApi>(FakeApi_WlanEnumInterfaces)},
|
||||
{"WlanGetProfileList",
|
||||
std::make_shared<_fakeApi>(FakeApi_WlanGetProfileList)},
|
||||
{"WlanFreeMemory", std::make_shared<_fakeApi>(FakeApi_WlanFreeMemory)},
|
||||
{"WlanCloseHandle",
|
||||
std::make_shared<_fakeApi>(FakeApi_WlanCloseHandle)},
|
||||
{"GetCurrentProcess",
|
||||
std::make_shared<_fakeApi>(FakeApi_GetCurrentProcess)},
|
||||
{"OpenProcessToken",
|
||||
std::make_shared<_fakeApi>(FakeApi_OpenProcessToken)},
|
||||
{"GetTokenInformation",
|
||||
std::make_shared<_fakeApi>(FakeApi_GetTokenInformation)},
|
||||
// 添加WFP相关API映射
|
||||
{"FwpmEngineOpen0",
|
||||
std::make_shared<_fakeApi>(FakeApi_FwpmEngineOpen0)},
|
||||
{"FwpmProviderAdd0",
|
||||
std::make_shared<_fakeApi>(FakeApi_FwpmProviderAdd0)},
|
||||
{"FwpmFilterAdd0", std::make_shared<_fakeApi>(FakeApi_FwpmFilterAdd0)},
|
||||
{"FwpmEngineClose0",
|
||||
std::make_shared<_fakeApi>(FakeApi_FwpmEngineClose0)},
|
||||
};
|
||||
}
|
||||
auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip,
|
||||
@@ -1603,4 +972,4 @@ auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip,
|
||||
printf("ApiName: %s not found\n", ApiName.c_str());
|
||||
uc_emu_stop(uc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user