Files
awesome_anti_virus_engine/ai_anti_malware/sandbox_api_emu.cpp
2025-03-06 20:08:12 +08:00

1322 lines
47 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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*>(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*>(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*>(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*>(sandbox);
uint64_t params_address = 0;
// 获取参数地址
if (context->GetPeInfo()->isX64) {
uc_reg_read(uc, UC_X86_REG_RCX, &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, &params_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*>(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*>(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_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);
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*>(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*>(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<uint32_t>(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*>(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<uint32_t>(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*>(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<uint32_t>(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] != (void*)0x1337ffffff) {
return_value =
reinterpret_cast<uint64_t>(teb->TlsSlots[dwTlsIndex]);
} else {
// 槽未分配设置LastError
DWORD error = ERROR_INVALID_PARAMETER;
teb->LastErrorValue = error;
}
} else {
auto teb = context->GetTeb32();
// 检查槽是否已分配不为0
if (teb->TlsSlots[dwTlsIndex] != 0x1337) {
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*>(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<uint32_t>(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*>(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*>(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*>(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*>(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<int32_t>(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<HANDLE>(0x1000); // 模拟标准输入句柄
break;
case STD_OUTPUT_HANDLE: // -11
handle = reinterpret_cast<HANDLE>(0x2000); // 模拟标准输出句柄
break; // End of Selection
break;
case STD_ERROR_HANDLE: // -12
handle = reinterpret_cast<HANDLE>(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<uint64_t>(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*>(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<HANDLE>(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<HANDLE>(static_cast<uint64_t>(temp_handle));
}
DWORD file_type = FILE_TYPE_UNKNOWN;
// 根据标准句柄类型返回相应的文件类型
if (hFile == reinterpret_cast<HANDLE>(0x1000) || // STD_INPUT_HANDLE
hFile == reinterpret_cast<HANDLE>(0x2000) || // STD_OUTPUT_HANDLE
hFile == reinterpret_cast<HANDLE>(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*>(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*>(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;
}