- 在沙箱中实现了新的功能,包括内存分配和API钩子初始化 - 更新了沙箱类,增加了对WFP引擎的支持 - 添加了多个API的实现,如GetLastError、InitializeCriticalSection等 - 修改了主函数以使用新的沙箱功能,替换了恶意软件扫描功能 - 更新了项目文件以包含新的源文件和API实现 - 改进了错误处理和日志记录功能
976 lines
39 KiB
C++
976 lines
39 KiB
C++
#include "sandbox.h"
|
||
#include "sandbox_callbacks.h"
|
||
#include "sandbox_api_winhttp.h"
|
||
#include <tlhelp32.h>
|
||
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_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;
|
||
|
||
// 获取参数地址
|
||
if (context->GetPeInfo()->isX64) {
|
||
uc_reg_read(uc, UC_X86_REG_RCX, ¶ms_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, ¶ms_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);
|
||
}
|
||
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));
|
||
context->CheckMalwareActive_GetProcAddress(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 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 Api_GetModuleFileNameW(void* sandbox, uc_engine* uc, uint64_t address)
|
||
-> void {
|
||
auto context = static_cast<Sandbox*>(sandbox);
|
||
uint64_t hModule = 0;
|
||
uint64_t lpFilename = 0;
|
||
uint32_t nSize = 0;
|
||
|
||
// 获取参数
|
||
if (context->GetPeInfo()->isX64) {
|
||
// x64: rcx = hModule, rdx = lpFilename, r8 = nSize
|
||
uc_reg_read(uc, UC_X86_REG_RCX, &hModule);
|
||
uc_reg_read(uc, UC_X86_REG_RDX, &lpFilename);
|
||
uint64_t temp_size;
|
||
uc_reg_read(uc, UC_X86_REG_R8, &temp_size);
|
||
nSize = static_cast<uint32_t>(temp_size);
|
||
} else {
|
||
// x86: 从栈上读取参数
|
||
uint32_t esp_address = 0;
|
||
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
|
||
esp_address += 0x4; // 跳过返回地址
|
||
uint32_t temp_module = 0;
|
||
uint32_t temp_filename = 0;
|
||
uc_mem_read(uc, esp_address, &temp_module, sizeof(uint32_t));
|
||
uc_mem_read(uc, esp_address + 0x4, &temp_filename, sizeof(uint32_t));
|
||
uc_mem_read(uc, esp_address + 0x8, &nSize, sizeof(uint32_t));
|
||
hModule = temp_module;
|
||
lpFilename = temp_filename;
|
||
}
|
||
|
||
uint32_t result = 0;
|
||
|
||
// 验证参数
|
||
if (lpFilename == 0 || nSize == 0) {
|
||
DWORD error = ERROR_INVALID_PARAMETER;
|
||
if (context->GetPeInfo()->isX64) {
|
||
context->GetTeb64()->LastErrorValue = error;
|
||
} else {
|
||
context->GetTeb32()->LastErrorValue = error;
|
||
}
|
||
uc_reg_write(
|
||
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||
&result);
|
||
return;
|
||
}
|
||
|
||
std::wstring modulePath;
|
||
if (hModule == 0) {
|
||
// 如果hModule为NULL,返回主模块(PE文件)的路径
|
||
modulePath = std::wstring(context->GetPeInfo()->inputFilePath.begin(),
|
||
context->GetPeInfo()->inputFilePath.end());
|
||
} else {
|
||
// 在模块列表中查找对应模块
|
||
bool found = false;
|
||
for (const auto& module : context->GetModuleList()) {
|
||
if (module->base == hModule) {
|
||
// 构建完整的模块路径
|
||
char windowsPath[MAX_PATH];
|
||
GetWindowsDirectoryA(windowsPath, sizeof(windowsPath));
|
||
|
||
// 根据PE架构选择正确的系统目录
|
||
const std::string systemDir = context->GetPeInfo()->isX64
|
||
? "\\System32\\"
|
||
: "\\SysWOW64\\";
|
||
|
||
std::string fullPath =
|
||
std::string(windowsPath) + systemDir + module->name;
|
||
modulePath = std::wstring(fullPath.begin(), fullPath.end());
|
||
found = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (!found) {
|
||
DWORD error = ERROR_MOD_NOT_FOUND;
|
||
if (context->GetPeInfo()->isX64) {
|
||
context->GetTeb64()->LastErrorValue = error;
|
||
} else {
|
||
context->GetTeb32()->LastErrorValue = error;
|
||
}
|
||
uc_reg_write(
|
||
uc,
|
||
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||
&result);
|
||
return;
|
||
}
|
||
}
|
||
|
||
// 检查缓冲区大小是否足够
|
||
if (nSize < modulePath.length() + 1) {
|
||
// 缓冲区太小,返回所需大小
|
||
result = static_cast<uint32_t>(modulePath.length() + 1);
|
||
DWORD error = ERROR_INSUFFICIENT_BUFFER;
|
||
if (context->GetPeInfo()->isX64) {
|
||
context->GetTeb64()->LastErrorValue = error;
|
||
} else {
|
||
context->GetTeb32()->LastErrorValue = error;
|
||
}
|
||
} else {
|
||
// 写入路径到缓冲区
|
||
if (uc_mem_write(uc, lpFilename, modulePath.c_str(),
|
||
(modulePath.length() + 1) * sizeof(wchar_t)) ==
|
||
UC_ERR_OK) {
|
||
result = static_cast<uint32_t>(modulePath.length());
|
||
} else {
|
||
result = 0;
|
||
DWORD error = ERROR_INVALID_PARAMETER;
|
||
if (context->GetPeInfo()->isX64) {
|
||
context->GetTeb64()->LastErrorValue = error;
|
||
} else {
|
||
context->GetTeb32()->LastErrorValue = error;
|
||
}
|
||
}
|
||
}
|
||
|
||
printf(
|
||
"[*] GetModuleFileNameW: Module=0x%llx, Buffer=0x%llx, Size=%u, "
|
||
"Result=%u, Path=%ls\n",
|
||
hModule, lpFilename, nSize, result, modulePath.c_str());
|
||
|
||
uc_reg_write(uc,
|
||
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||
&result);
|
||
}
|
||
|
||
// 实现 SetUnhandledExceptionFilter API
|
||
auto Api_SetUnhandledExceptionFilter(void* sandbox, uc_engine* uc,
|
||
uint64_t address) -> void {
|
||
auto context = static_cast<Sandbox*>(sandbox);
|
||
uint64_t lpTopLevelExceptionFilter = 0;
|
||
|
||
// 获取参数
|
||
if (context->GetPeInfo()->isX64) {
|
||
// x64: rcx = lpTopLevelExceptionFilter
|
||
uc_reg_read(uc, UC_X86_REG_RCX, &lpTopLevelExceptionFilter);
|
||
} else {
|
||
// x86: 从栈上读取参数
|
||
uint32_t esp_address = 0;
|
||
uint32_t temp_filter = 0;
|
||
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
|
||
esp_address += 0x4; // 跳过返回地址
|
||
uc_mem_read(uc, esp_address, &temp_filter, sizeof(uint32_t));
|
||
lpTopLevelExceptionFilter = temp_filter;
|
||
}
|
||
|
||
// 简单实现:返回NULL表示没有之前的过滤器
|
||
uint64_t prev_filter = 0;
|
||
|
||
printf("[*] SetUnhandledExceptionFilter: Filter=0x%llx\n",
|
||
lpTopLevelExceptionFilter);
|
||
|
||
// 返回之前的过滤器(在这里始终返回NULL)
|
||
uc_reg_write(uc,
|
||
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||
&prev_filter);
|
||
}
|
||
|
||
// 将Windows VirtualProtect保护标志转换为Unicorn内存保护标志
|
||
uint32_t WindowsToUnicornProtect(uint32_t windowsProtect) {
|
||
uint32_t unicornProtect = UC_PROT_NONE;
|
||
|
||
// 转换基本属性
|
||
if (windowsProtect & (PAGE_READONLY | PAGE_READWRITE | PAGE_EXECUTE_READ |
|
||
PAGE_EXECUTE_READWRITE)) {
|
||
unicornProtect |= UC_PROT_READ;
|
||
}
|
||
|
||
if (windowsProtect & (PAGE_READWRITE | PAGE_WRITECOPY |
|
||
PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) {
|
||
unicornProtect |= UC_PROT_WRITE;
|
||
}
|
||
|
||
if (windowsProtect & (PAGE_EXECUTE | PAGE_EXECUTE_READ |
|
||
PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) {
|
||
unicornProtect |= UC_PROT_EXEC;
|
||
}
|
||
|
||
// 如果没有有效标志,至少给予读权限以防崩溃
|
||
if (unicornProtect == UC_PROT_NONE && windowsProtect != PAGE_NOACCESS) {
|
||
unicornProtect = UC_PROT_READ;
|
||
}
|
||
|
||
return unicornProtect;
|
||
}
|
||
|
||
auto Api_VirtualProtect(void* sandbox, uc_engine* uc, uint64_t address)
|
||
-> void {
|
||
auto context = static_cast<Sandbox*>(sandbox);
|
||
uint64_t lpAddress = 0;
|
||
uint64_t dwSize = 0;
|
||
uint32_t flNewProtect = 0;
|
||
uint64_t lpflOldProtect = 0;
|
||
|
||
// 获取参数
|
||
if (context->GetPeInfo()->isX64) {
|
||
// x64: rcx = lpAddress, rdx = dwSize, r8 = flNewProtect, r9 =
|
||
// lpflOldProtect
|
||
uc_reg_read(uc, UC_X86_REG_RCX, &lpAddress);
|
||
uc_reg_read(uc, UC_X86_REG_RDX, &dwSize);
|
||
uint64_t temp_protect;
|
||
uc_reg_read(uc, UC_X86_REG_R8, &temp_protect);
|
||
flNewProtect = static_cast<uint32_t>(temp_protect);
|
||
uc_reg_read(uc, UC_X86_REG_R9, &lpflOldProtect);
|
||
} else {
|
||
// x86: 从栈上读取参数
|
||
uint32_t esp_address = 0;
|
||
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
|
||
esp_address += 0x4; // 跳过返回地址
|
||
|
||
uint32_t temp_address;
|
||
uc_mem_read(uc, esp_address, &temp_address, sizeof(uint32_t));
|
||
lpAddress = temp_address;
|
||
esp_address += 0x4;
|
||
|
||
uint32_t temp_size;
|
||
uc_mem_read(uc, esp_address, &temp_size, sizeof(uint32_t));
|
||
dwSize = temp_size;
|
||
esp_address += 0x4;
|
||
|
||
uc_mem_read(uc, esp_address, &flNewProtect, sizeof(uint32_t));
|
||
esp_address += 0x4;
|
||
|
||
uint32_t temp_old_protect;
|
||
uc_mem_read(uc, esp_address, &temp_old_protect, sizeof(uint32_t));
|
||
lpflOldProtect = temp_old_protect;
|
||
}
|
||
|
||
// 检查参数有效性
|
||
if (lpAddress == 0 || dwSize == 0 || lpflOldProtect == 0) {
|
||
uint64_t result = 0; // FALSE
|
||
uc_reg_write(
|
||
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||
&result);
|
||
|
||
// 设置错误码 - ERROR_INVALID_PARAMETER
|
||
DWORD error = ERROR_INVALID_PARAMETER;
|
||
if (context->GetPeInfo()->isX64) {
|
||
context->GetTeb64()->LastErrorValue = error;
|
||
} else {
|
||
context->GetTeb32()->LastErrorValue = error;
|
||
}
|
||
return;
|
||
}
|
||
|
||
// 检查地址范围是否已映射
|
||
uint32_t unicornProtect = WindowsToUnicornProtect(flNewProtect);
|
||
uc_err err = uc_mem_protect(uc, lpAddress, dwSize, unicornProtect);
|
||
if (err != UC_ERR_OK) {
|
||
uint64_t result = 0; // FALSE
|
||
uc_reg_write(
|
||
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||
&result);
|
||
|
||
// 设置错误码 - ERROR_INVALID_ADDRESS
|
||
DWORD error = ERROR_INVALID_ADDRESS;
|
||
if (context->GetPeInfo()->isX64) {
|
||
context->GetTeb64()->LastErrorValue = error;
|
||
} else {
|
||
context->GetTeb32()->LastErrorValue = error;
|
||
}
|
||
return;
|
||
}
|
||
|
||
// 模拟的旧保护属性,这里简化为一个默认值
|
||
// 实际应用中,应该从内存映射表中获取
|
||
uint32_t oldProtect = PAGE_READWRITE;
|
||
|
||
// 写入旧保护值到lpflOldProtect指向的内存
|
||
uc_mem_write(uc, lpflOldProtect, &oldProtect, sizeof(uint32_t));
|
||
|
||
// 调试输出
|
||
printf(
|
||
"[*] VirtualProtect: Address=0x%llx, Size=0x%llx, WindowsProtect=0x%x, "
|
||
"UnicornProtect=0x%x, OldProtect=0x%x\n",
|
||
lpAddress, dwSize, flNewProtect, unicornProtect, oldProtect);
|
||
|
||
// 设置返回值为TRUE
|
||
uint64_t result = 1; // TRUE
|
||
uc_reg_write(uc,
|
||
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||
&result);
|
||
}
|
||
|
||
auto Api_Sleep(void* sandbox, uc_engine* uc, uint64_t address) -> void {
|
||
auto context = static_cast<Sandbox*>(sandbox);
|
||
uint64_t milliseconds;
|
||
|
||
// 获取参数:dwMilliseconds
|
||
if (context->GetPeInfo()->isX64) {
|
||
// 在x64中,参数通过寄存器传递,第一个参数在RCX
|
||
uc_reg_read(uc, UC_X86_REG_RCX, &milliseconds);
|
||
} else {
|
||
// 在x86中,参数通过栈传递
|
||
uint32_t esp;
|
||
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
|
||
// 返回地址之后的4字节是第一个参数
|
||
uc_mem_read(uc, esp + 4, &milliseconds, sizeof(milliseconds));
|
||
}
|
||
|
||
// 打印日志
|
||
printf("Sleep API called with %u milliseconds\n", milliseconds);
|
||
}
|
||
|
||
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_GetCurrentThread =
|
||
_fakeApi{.func = Api_GetCurrentThread, .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_InitializeCriticalSectionEx =
|
||
_fakeApi{.func = Api_InitializeCriticalSectionEx, .paramCount = 3};
|
||
auto FakeApi_DeleteCriticalSection =
|
||
_fakeApi{.func = Api_DeleteCriticalSection, .paramCount = 1};
|
||
auto FakeApi_TlsAlloc = _fakeApi{.func = Api_TlsAlloc, .paramCount = 0};
|
||
auto FakeApi_TlsSetValue =
|
||
_fakeApi{.func = Api_TlsSetValue, .paramCount = 2};
|
||
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};
|
||
auto FakeApi_GetACP = _fakeApi{.func = Api_GetACP, .paramCount = 0};
|
||
auto FakeApi_GetCPInfo = _fakeApi{.func = Api_GetCPInfo, .paramCount = 2};
|
||
auto FakeApi_MultiByteToWideChar =
|
||
_fakeApi{.func = Api_MultiByteToWideChar, .paramCount = 6};
|
||
auto FakeApi_GetModuleFileNameW =
|
||
_fakeApi{.func = Api_GetModuleFileNameW, .paramCount = 3};
|
||
auto FakeApi_AreFileApisANSI =
|
||
_fakeApi{.func = Api_AreFileApisANSI, .paramCount = 0};
|
||
auto FakeApi_WideCharToMultiByte =
|
||
_fakeApi{.func = Api_WideCharToMultiByte, .paramCount = 8};
|
||
auto FakeApi_InitializeSListHead =
|
||
_fakeApi{.func = Api_InitializeSListHead, .paramCount = 1};
|
||
auto FakeApi_GetEnvironmentStringsW =
|
||
_fakeApi{.func = Api_GetEnvironmentStringsW, .paramCount = 0};
|
||
auto FakeApi_FreeEnvironmentStringsW =
|
||
_fakeApi{.func = Api_FreeEnvironmentStringsW, .paramCount = 1};
|
||
auto FakeApi_SetUnhandledExceptionFilter =
|
||
_fakeApi{.func = Api_SetUnhandledExceptionFilter, .paramCount = 1};
|
||
auto FakeApi_VirtualProtect =
|
||
_fakeApi{.func = Api_VirtualProtect, .paramCount = 4};
|
||
auto FakeApi_RegOpenKeyExW =
|
||
_fakeApi{.func = Api_RegOpenKeyExW, .paramCount = 5};
|
||
auto FakeApi_RegCloseKey =
|
||
_fakeApi{.func = Api_RegCloseKey, .paramCount = 1};
|
||
auto FakeApi___set_app_type =
|
||
_fakeApi{.func = Api___set_app_type, .paramCount = 1};
|
||
auto FakeApi___p__fmode = _fakeApi{.func = Api___p__fmode, .paramCount = 0};
|
||
auto FakeApi_Sleep = _fakeApi{.func = Api_Sleep, .paramCount = 1};
|
||
auto FakeApi_SHGetKnownFolderPath =
|
||
_fakeApi{.func = Api_SHGetKnownFolderPath, .paramCount = 4};
|
||
// 添加新的Internet API函数
|
||
auto FakeApi_InternetOpenA =
|
||
_fakeApi{.func = Api_InternetOpenA, .paramCount = 5};
|
||
auto FakeApi_InternetOpenUrlA =
|
||
_fakeApi{.func = Api_InternetOpenUrlA, .paramCount = 6};
|
||
auto FakeApi_InternetCloseHandle =
|
||
_fakeApi{.func = Api_InternetCloseHandle, .paramCount = 1};
|
||
auto FakeApi_InternetReadFile =
|
||
_fakeApi{.func = Api_InternetReadFile, .paramCount = 4};
|
||
auto FakeApi_EncodePointer =
|
||
_fakeApi{.func = Api_EncodePointer, .paramCount = 1};
|
||
auto FakeApi_HeapCreate = _fakeApi{.func = Api_HeapCreate, .paramCount = 3};
|
||
auto FakeApi_GetModuleHandleA =
|
||
_fakeApi{.func = Api_GetModuleHandleA, .paramCount = 1};
|
||
auto FakeApi_GetModuleHandleW =
|
||
_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)},
|
||
{"GetCurrentThreadId",
|
||
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)},
|
||
{"LoadLibraryExW", std::make_shared<_fakeApi>(FakeApi_LoadLibraryExW)},
|
||
{"GetLastError", std::make_shared<_fakeApi>(FakeApi_GetLastError)},
|
||
{"InitializeCriticalSectionAndSpinCount",
|
||
std::make_shared<_fakeApi>(
|
||
FakeApi_InitializeCriticalSectionAndSpinCount)},
|
||
{"InitializeCriticalSectionEx",
|
||
std::make_shared<_fakeApi>(FakeApi_InitializeCriticalSectionEx)},
|
||
{"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)},
|
||
{"GetACP", std::make_shared<_fakeApi>(FakeApi_GetACP)},
|
||
{"GetCPInfo", std::make_shared<_fakeApi>(FakeApi_GetCPInfo)},
|
||
{"MultiByteToWideChar",
|
||
std::make_shared<_fakeApi>(FakeApi_MultiByteToWideChar)},
|
||
{"GetModuleFileNameW",
|
||
std::make_shared<_fakeApi>(FakeApi_GetModuleFileNameW)},
|
||
{"AreFileApisANSI",
|
||
std::make_shared<_fakeApi>(FakeApi_AreFileApisANSI)},
|
||
{"WideCharToMultiByte",
|
||
std::make_shared<_fakeApi>(FakeApi_WideCharToMultiByte)},
|
||
{"InitializeSListHead",
|
||
std::make_shared<_fakeApi>(FakeApi_InitializeSListHead)},
|
||
{"GetEnvironmentStringsW",
|
||
std::make_shared<_fakeApi>(FakeApi_GetEnvironmentStringsW)},
|
||
{"FreeEnvironmentStringsW",
|
||
std::make_shared<_fakeApi>(FakeApi_FreeEnvironmentStringsW)},
|
||
{"SetUnhandledExceptionFilter",
|
||
std::make_shared<_fakeApi>(FakeApi_SetUnhandledExceptionFilter)},
|
||
{"VirtualProtect", std::make_shared<_fakeApi>(FakeApi_VirtualProtect)},
|
||
{"RegOpenKeyExW", std::make_shared<_fakeApi>(FakeApi_RegOpenKeyExW)},
|
||
{"RegCloseKey", std::make_shared<_fakeApi>(FakeApi_RegCloseKey)},
|
||
{"_set_app_type", std::make_shared<_fakeApi>(FakeApi___set_app_type)},
|
||
{"_p__fmode", std::make_shared<_fakeApi>(FakeApi___p__fmode)},
|
||
{"Sleep", std::make_shared<_fakeApi>(FakeApi_Sleep)},
|
||
{"SHGetKnownFolderPath",
|
||
std::make_shared<_fakeApi>(FakeApi_SHGetKnownFolderPath)},
|
||
// 添加新的Internet API映射
|
||
{"InternetOpenA", std::make_shared<_fakeApi>(FakeApi_InternetOpenA)},
|
||
{"InternetOpenUrlA",
|
||
std::make_shared<_fakeApi>(FakeApi_InternetOpenUrlA)},
|
||
{"InternetCloseHandle",
|
||
std::make_shared<_fakeApi>(FakeApi_InternetCloseHandle)},
|
||
{"InternetReadFile",
|
||
std::make_shared<_fakeApi>(FakeApi_InternetReadFile)},
|
||
{"EncodePointer", std::make_shared<_fakeApi>(FakeApi_EncodePointer)},
|
||
{"HeapCreate", std::make_shared<_fakeApi>(FakeApi_HeapCreate)},
|
||
{"GetModuleHandleA",
|
||
std::make_shared<_fakeApi>(FakeApi_GetModuleHandleA)},
|
||
{"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,
|
||
std::string ApiName) -> void {
|
||
auto it = api_map.find(ApiName);
|
||
if (it != api_map.end()) {
|
||
it->second->func(this, uc, address);
|
||
this->ApiCallList.push_back(ApiName);
|
||
|
||
// 获取参数数量
|
||
int paramCount = it->second->paramCount;
|
||
uint32_t esp;
|
||
uint64_t rsp;
|
||
|
||
// 从栈上读取返回地址
|
||
uint64_t return_address;
|
||
if (this->GetPeInfo()->isX64) { // 64位系统
|
||
uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
|
||
// 读取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;
|
||
rsp += 8;
|
||
// 设置RIP为返回地址
|
||
uc_reg_write(uc, UC_X86_REG_RIP, &return_address);
|
||
} else { // 32位系统
|
||
// 读取4字节的返回地址
|
||
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
|
||
uc_mem_read(uc, esp, &return_address, 4);
|
||
|
||
uint32_t return_address_32;
|
||
uc_mem_read(uc, esp, &return_address_32, 4);
|
||
printf("return_address_32: %x\n", return_address_32);
|
||
// x86下,所有参数都通过栈传递
|
||
// 调整栈指针:每个参数4字节 + 返回地址4字节
|
||
esp += (paramCount * 4) + 4;
|
||
// 设置EIP为返回地址
|
||
uc_reg_write(uc, UC_X86_REG_EIP, &return_address_32);
|
||
}
|
||
if (this->GetPeInfo()->isX64) {
|
||
uc_reg_write(uc, UC_X86_REG_RSP, &rsp);
|
||
} else {
|
||
uc_reg_write(uc, UC_X86_REG_ESP, &esp);
|
||
}
|
||
|
||
return;
|
||
}
|
||
printf("ApiName: %s not found\n", ApiName.c_str());
|
||
uc_emu_stop(uc);
|
||
return;
|
||
}
|