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

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

19
.vscode/c_cpp_properties.json vendored Normal file
View File

@@ -0,0 +1,19 @@
{
"configurations": [
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"compilerPath": "E:/Program Files/LLVM/bin/clang++.exe",
"cStandard": "c11",
"cppStandard": "c++23"
}
],
"version": 4
}

View File

@@ -39,6 +39,7 @@ auto getPeInfo(std::string inputFilePath) -> std::shared_ptr<BasicPeInfo> {
sampleInfo->RecImageBase +
(sampleInfo->isX64 ? sampleInfo->ntHead64->OptionalHeader.SizeOfImage
: sampleInfo->ntHead32->OptionalHeader.SizeOfImage);
sampleInfo->isDll = peconv::is_module_dll((BYTE*)sampleInfo->peBuffer);
printf("Debug - Memory mapping parameters:\n");
printf("RecImageBase: 0x%llx\n", sampleInfo->RecImageBase);
printf("peSize: 0x%llx\n", sampleInfo->peSize);
@@ -310,9 +311,29 @@ auto doMalwareScan(int argc, char* argv[]) -> void {
auto sampleType = scanner.DetectMalware(filePath);
printf("sample type: %d \n", sampleType);
}
int doSandbox(int argc, char* argv[]) {
/*
if (argc < 3) {
std::cout << "用法: " << argv[0] << " <文件路径> <地址>" << std::endl;
return;
}
std::string filePath = argv[1];
*/
std::string filePath = "C:\\mso.dll";
auto peInfo = getPeInfo(filePath);
if (peInfo == nullptr) {
return 0;
}
Sandbox se;
se.InitEnv(peInfo);
se.Run(0x180003980);
return 0;
}
int main(int argc, char* argv[]) {
// doMl(argc, argv);
// doPredict(argc, argv);
doMalwareScan(argc, argv);
// doMalwareScan(argc, argv);
doSandbox(argc, argv);
return 0;
}

View File

@@ -174,9 +174,13 @@
<ClCompile Include="ml.cpp" />
<ClCompile Include="sandbox.cpp" />
<ClCompile Include="sandbox_api_emu.cpp" />
<ClCompile Include="sandbox_api_file.cpp" />
<ClCompile Include="sandbox_api_process.cpp" />
<ClCompile Include="sandbox_api_regs.cpp" />
<ClCompile Include="sandbox_api_stl.cpp" />
<ClCompile Include="sandbox_api_wfp.cpp" />
<ClCompile Include="sandbox_api_winhttp.cpp" />
<ClCompile Include="sandbox_api_wlan.cpp" />
<ClCompile Include="sandbox_callbacks.cpp" />
<ClCompile Include="sandbox_malware_check.cpp" />
</ItemGroup>

View File

@@ -28,6 +28,9 @@
<Filter Include="头文件\machine_learning">
<UniqueIdentifier>{65a79261-ea29-4842-b41c-7983eddbdc85}</UniqueIdentifier>
</Filter>
<Filter Include="源文件\sandbox\apis">
<UniqueIdentifier>{44f6b6b6-64fa-44ff-b7fa-af7f7294a3f2}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="ai_anti_malware.cpp">
@@ -120,9 +123,6 @@
<ClCompile Include="sandbox_callbacks.cpp">
<Filter>源文件\sandbox</Filter>
</ClCompile>
<ClCompile Include="sandbox_api_emu.cpp">
<Filter>源文件\sandbox</Filter>
</ClCompile>
<ClCompile Include="ml.cpp">
<Filter>源文件\machine_learning</Filter>
</ClCompile>
@@ -132,14 +132,29 @@
<ClCompile Include="sandbox_malware_check.cpp">
<Filter>源文件\sandbox</Filter>
</ClCompile>
<ClCompile Include="sandbox_api_winhttp.cpp">
<Filter>源文件\sandbox\apis</Filter>
</ClCompile>
<ClCompile Include="sandbox_api_emu.cpp">
<Filter>源文件\sandbox\apis</Filter>
</ClCompile>
<ClCompile Include="sandbox_api_process.cpp">
<Filter>源文件\sandbox\apis</Filter>
</ClCompile>
<ClCompile Include="sandbox_api_regs.cpp">
<Filter>源文件\sandbox</Filter>
<Filter>源文件\sandbox\apis</Filter>
</ClCompile>
<ClCompile Include="sandbox_api_stl.cpp">
<Filter>源文件\sandbox</Filter>
<Filter>源文件\sandbox\apis</Filter>
</ClCompile>
<ClCompile Include="sandbox_api_winhttp.cpp">
<Filter>源文件\sandbox</Filter>
<ClCompile Include="sandbox_api_file.cpp">
<Filter>源文件\sandbox\apis</Filter>
</ClCompile>
<ClCompile Include="sandbox_api_wlan.cpp">
<Filter>源文件\sandbox\apis</Filter>
</ClCompile>
<ClCompile Include="sandbox_api_wfp.cpp">
<Filter>源文件\sandbox\apis</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>

View File

@@ -3,21 +3,23 @@
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <iostream>
#include <winternl.h>
#include <WinSock2.h>
#include <vector>
#include <map>
#include <unordered_map>
#include <ntstatus.h>
#include <ctime>
#include <functional>
#include <string>
#include <vector>
#include "unicorn/include/unicorn/unicorn.h"
#include "capstone/include/capstone/capstone.h"
#pragma comment(lib, "unicorn/unicorn.lib")
#pragma comment(lib, "capstone/capstone.lib")
#include "libpeconv/include/peconv.h"
#include "native_struct.h"
#include "tiny_wfp_structs.h"
struct BasicPeInfo {
std::string inputFilePath;
bool isX64;
@@ -29,6 +31,7 @@ struct BasicPeInfo {
size_t peSize;
PIMAGE_NT_HEADERS ntHead64;
PIMAGE_NT_HEADERS32 ntHead32;
bool isDll;
};
#include "sandbox.h"
#include "ml.h"

View File

@@ -2,6 +2,28 @@
#include "sandbox_callbacks.h"
// 在文件开头添加AllocateMemory函数的声明
auto Sandbox::AllocateMemory(size_t size) -> uint64_t {
// 使用一个简单的内存分配策略
static uint64_t next_address = 0x60000000; // 起始地址
uint64_t allocated_address = next_address;
// 对齐到4KB
size = (size + 0xFFF) & ~0xFFF;
// 分配内存
uc_err err = uc_mem_map(m_ucEngine, allocated_address, size, UC_PROT_ALL);
if (err != UC_ERR_OK) {
printf("[!] Failed to allocate memory at 0x%llx: %u\n",
allocated_address, err);
return 0;
}
// 更新下一个可用地址
next_address += size + 0x1000; // 添加一个页面的间隔
return allocated_address;
}
std::string getDllNameFromApiSetMap(const std::string& apiSet) {
const std::wstring wApiSet(apiSet.begin(), apiSet.end());
@@ -174,9 +196,19 @@ class cFixImprot : public peconv::t_function_resolver {
private:
Sandbox* m_sandbox; // Sandbox实例的指针
};
Sandbox::Sandbox() {}
Sandbox::Sandbox() {
m_ucEngine = nullptr;
m_peInfo = nullptr;
m_nextWfpEngineHandle = (HANDLE)0x1000; // 初始化WFP引擎句柄
}
Sandbox::~Sandbox() {
// 清理WFP引擎资源
for (auto& pair : m_wfpEngines) {
delete pair.second;
}
m_wfpEngines.clear();
// 1. 先清理高层资源
m_crossSectionExecution.clear();
envStrings.clear();
@@ -631,7 +663,7 @@ auto Sandbox::InitEnv(std::shared_ptr<BasicPeInfo> peInfo) -> void {
InitCommandLine(peInfo->inputFilePath);
}
auto Sandbox::Run() -> void {
auto Sandbox::Run(uint64_t address) -> void {
// 初始化堆栈
uc_err err = uc_mem_map(m_ucEngine, m_stackBase, m_stackSize,
UC_PROT_READ | UC_PROT_WRITE);
@@ -659,7 +691,7 @@ auto Sandbox::Run() -> void {
&rbp);
// 设置入口点
uint64_t entryPoint = m_peInfo->RecImageBase + m_peInfo->entryPoint;
uint64_t entryPoint = (m_peInfo->RecImageBase + m_peInfo->entryPoint);
// 添加钩子
uc_hook hook_code, hook_mem, hook_mem_unmap, hook_mem_write, hook_syscall;
@@ -708,7 +740,7 @@ auto Sandbox::Run() -> void {
if (err != UC_ERR_OK) {
throw std::runtime_error("Failed to add syscall hook");
}
auto customIP = address;
// 设置EIP/RIP
err = uc_reg_write(m_ucEngine,
m_peInfo->isX64 ? UC_X86_REG_RIP : UC_X86_REG_EIP,
@@ -718,11 +750,26 @@ auto Sandbox::Run() -> void {
}
InitApiHooks();
std::cout << "Starting execution at " << std::hex << entryPoint
<< std::endl;
uint64_t timeout = 60 * 1000 * 1000;
// 1.入口点是必须跑的
if (m_peInfo->isDll) {
// 给rcx和rdx设置dll应该设置的
auto dll_fdwReason = 1;
uc_reg_write(m_ucEngine, UC_X86_REG_RCX, &m_peInfo->RecImageBase);
uc_reg_write(m_ucEngine, UC_X86_REG_RDX, &dll_fdwReason);
}
err = uc_emu_start(m_ucEngine, entryPoint, m_peInfo->imageEnd, timeout, 0);
std::cerr << "Emulation error: " << uc_strerror(err) << std::endl;
// 2. 有自定义地址 再跑自定义地址
std::cerr << "Entry Point Emulation error: " << uc_strerror(err)
<< std::endl;
if (address != 0) {
err = uc_emu_start(m_ucEngine, address, m_peInfo->imageEnd, timeout, 0);
std::cerr << "Custom Emulation error: " << uc_strerror(err)
<< std::endl;
}
}
auto Sandbox::GetEnvString() -> std::vector<wchar_t> {

View File

@@ -1,9 +1,7 @@
#pragma once
#include <functional>
#include <map>
#include "head.h"
#include <WinInet.h>
#include <wininet.h>
#define PAGE_SIZE 0x1000
#define CF_MASK (1 << 0)
#define PF_MASK (1 << 2)
@@ -87,12 +85,21 @@ struct InternetHandleInfo {
class Sandbox {
friend class cFixImprot; // 声明cFixImprot为友元类
public:
// WFP引擎相关结构体
struct FakeWFPEngine {
bool isOpen;
std::vector<FWPM_PROVIDER0> providers;
std::vector<FWPM_FILTER0> filters;
};
Sandbox();
~Sandbox();
std::map<uint64_t, size_t>
process_enum_state; // 用于跟踪每个句柄的枚举状态
// Public methods
auto InitEnv(std::shared_ptr<BasicPeInfo> peInfo) -> void;
auto Run() -> void;
auto Run(uint64_t address = 0) -> void;
auto GetCapstoneHandle() const -> csh { return m_csHandle; }
auto GetUnicornHandle() const -> uc_engine* { return m_ucEngine; }
auto GetPeInfo() const -> std::shared_ptr<BasicPeInfo> { return m_peInfo; }
@@ -115,6 +122,9 @@ class Sandbox {
auto GetEnvStringsSize() -> size_t;
auto InitCommandLine() -> void;
// 内存分配相关的方法
auto AllocateMemory(size_t size) -> uint64_t;
// 堆管理相关的公共方法
auto CreateHeapSegment(uint64_t base, size_t size) -> HeapSegment*;
auto AllocateFromSegment(HeapSegment* segment, size_t size) -> uint64_t;
@@ -213,6 +223,16 @@ class Sandbox {
}
std::vector<std::string> ApiCallList;
// WFP引擎相关方法
auto GetWfpEngines() -> std::map<HANDLE, FakeWFPEngine*>& {
return m_wfpEngines;
}
auto GetNextWfpEngineHandle() -> HANDLE {
auto handle = m_nextWfpEngineHandle;
m_nextWfpEngineHandle = (HANDLE)((uint64_t)m_nextWfpEngineHandle + 1);
return handle;
}
private:
std::shared_ptr<BasicPeInfo> m_peInfo;
uint64_t m_gsBase;
@@ -302,4 +322,106 @@ class Sandbox {
auto UpdateLdrLinks(const LDR_DATA_TABLE_ENTRY& entry,
uint64_t entryAddress, X64_PEB_LDR_DATA& ldrData)
-> void;
// WFP引擎相关成员
std::map<HANDLE, FakeWFPEngine*> m_wfpEngines;
HANDLE m_nextWfpEngineHandle;
};
std::string getDllNameFromApiSetMap(const std::string& apiSet);
void Api_GetLastError(void* sandbox, uc_engine* uc, uint64_t address);
auto Api_InitializeCriticalSectionAndSpinCount(void* sandbox, uc_engine* uc,
uint64_t address) -> void;
auto Api_InitializeCriticalSectionEx(void* sandbox, uc_engine* uc,
uint64_t address) -> void;
auto Api_IsProcessorFeaturePresent(void* sandbox, uc_engine* uc,
uint64_t address) -> void;
auto Api_DeleteCriticalSection(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto Api_TlsAlloc(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_TlsSetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api___set_app_type(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api___p__fmode(void* sandbox, uc_engine* uc, uint64_t address) -> void;
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;
auto Api_Process32NextW(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_CreateToolhelp32Snapshot(void* sandbox, uc_engine* uc,
uint64_t address) -> void;
auto Api_Process32FirstW(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto Api_VirtualQuery(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_GetModuleHandleW(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto Api_GetModuleHandleA(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto GetModuleHandleInternal(void* sandbox, const std::wstring& moduleName)
-> HMODULE;
auto Api_Process32NextW(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_WlanOpenHandle(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_WlanEnumInterfaces(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto Api_WlanGetProfileList(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto Api_WlanFreeMemory(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_WlanCloseHandle(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto Api_ReadFile(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_CreatePipe(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_CloseHandle(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_RtlFormatCurrentUserKeyPath(void* sandbox, uc_engine* uc,
uint64_t address) -> void;
auto Api_FlsSetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_CreateFileW(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_WriteFile(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_CreateProcessA(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_GetCurrentProcess(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto Api_GetCurrentThread(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto Api_OpenProcessToken(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto Api_GetTokenInformation(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
// WFP API函数声明
auto Api_FwpmEngineOpen0(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto Api_FwpmProviderAdd0(void* sandbox, uc_engine* uc, uint64_t address)
-> void;
auto Api_FwpmFilterAdd0(void* sandbox, uc_engine* uc, uint64_t address) -> void;
auto Api_FwpmEngineClose0(void* sandbox, uc_engine* uc, uint64_t address)
-> void;

View File

@@ -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;
}
}

View File

@@ -0,0 +1,180 @@
#include "sandbox.h"
#include "sandbox_callbacks.h"
#include "sandbox_api_winhttp.h"
#include <tlhelp32.h>
auto Api_ReadFile(void* sandbox, uc_engine* uc, uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t hFile = 0;
uint64_t lpBuffer = 0;
uint32_t nNumberOfBytesToRead = 0;
uint64_t lpNumberOfBytesRead = 0;
uint64_t lpOverlapped = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = hFile, rdx = lpBuffer, r8 = nNumberOfBytesToRead, r9 =
// lpNumberOfBytesRead
uc_reg_read(uc, UC_X86_REG_RCX, &hFile);
uc_reg_read(uc, UC_X86_REG_RDX, &lpBuffer);
uint64_t temp_bytes_to_read;
uc_reg_read(uc, UC_X86_REG_R8, &temp_bytes_to_read);
nNumberOfBytesToRead = static_cast<uint32_t>(temp_bytes_to_read);
uc_reg_read(uc, UC_X86_REG_R9, &lpNumberOfBytesRead);
// 从栈上读取lpOverlapped参数
uint64_t rsp;
uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
uc_mem_read(uc, rsp + 0x28, &lpOverlapped, sizeof(uint64_t));
} else {
// x86: 从栈上读取参数
uint32_t esp;
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
esp += 0x4; // 跳过返回地址
uint32_t temp_handle, temp_buffer, temp_bytes_read, temp_overlapped;
uc_mem_read(uc, esp, &temp_handle, sizeof(uint32_t));
uc_mem_read(uc, esp + 0x4, &temp_buffer, sizeof(uint32_t));
uc_mem_read(uc, esp + 0x8, &nNumberOfBytesToRead, sizeof(uint32_t));
uc_mem_read(uc, esp + 0xC, &temp_bytes_read, sizeof(uint32_t));
uc_mem_read(uc, esp + 0x10, &temp_overlapped, sizeof(uint32_t));
hFile = temp_handle;
lpBuffer = temp_buffer;
lpNumberOfBytesRead = temp_bytes_read;
lpOverlapped = temp_overlapped;
}
// 检查句柄是否为之前CreatePipe创建的读管道
bool success = false;
uint32_t bytesRead = 0;
// 检查是否为之前CreatePipe创建的读管道句柄 (0x1338)
if (hFile == 0x1338) {
// 模拟管道数据读取 - 这里我们可以根据之前的CreateProcessA来生成数据
// 生成一些模拟的ping命令输出数据
std::string pingOutput =
"Reply from 127.0.0.1: bytes=32 time<1ms TTL=45\r\n"
"Reply from 127.0.0.1: bytes=32 time<1ms TTL=45\r\n"
"Reply from 127.0.0.1: bytes=32 time<1ms TTL=45\r\n"
"Reply from 127.0.0.1: bytes=32 time<1ms TTL=45\r\n\r\n"
"Ping statistics for 127.0.0.1:\r\n"
" Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),\r\n"
"Approximate round trip times in milli-seconds:\r\n"
" Minimum = 0ms, Maximum = 0ms, Average = 0ms\r\n";
// 确保不超过缓冲区大小
bytesRead = min(static_cast<uint32_t>(pingOutput.length()),
nNumberOfBytesToRead);
// 写入数据到缓冲区
if (lpBuffer != 0 && bytesRead > 0) {
uc_mem_write(uc, lpBuffer, pingOutput.c_str(), bytesRead);
success = true;
}
}
// 写入实际读取的字节数
if (lpNumberOfBytesRead != 0) {
if (context->GetPeInfo()->isX64) {
uc_mem_write(uc, lpNumberOfBytesRead, &bytesRead, sizeof(uint32_t));
} else {
uc_mem_write(uc, lpNumberOfBytesRead, &bytesRead, sizeof(uint32_t));
}
}
printf(
"[*] ReadFile: Handle=0x%llx, Buffer=0x%llx, BytesToRead=%u, "
"BytesRead=%u, Success=%d\n",
hFile, lpBuffer, nNumberOfBytesToRead, bytesRead, success);
// 设置返回值
uint64_t result = success ? 1 : 0;
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
// 如果失败,设置错误码
if (!success) {
DWORD error = ERROR_INVALID_HANDLE;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
}
}
auto Api_CreatePipe(void* sandbox, uc_engine* uc, uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t hReadPipe = 0;
uint64_t hWritePipe = 0;
uint64_t lpPipeAttributes = 0;
uint32_t nSize = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = hReadPipe, rdx = hWritePipe, r8 = lpPipeAttributes, r9 =
// nSize
uc_reg_read(uc, UC_X86_REG_RCX, &hReadPipe);
uc_reg_read(uc, UC_X86_REG_RDX, &hWritePipe);
uc_reg_read(uc, UC_X86_REG_R8, &lpPipeAttributes);
uint64_t temp_size;
uc_reg_read(uc, UC_X86_REG_R9, &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_read_pipe;
uint32_t temp_write_pipe;
uint32_t temp_pipe_attributes;
uc_mem_read(uc, esp_address, &temp_read_pipe, sizeof(uint32_t));
uc_mem_read(uc, esp_address + 0x4, &temp_write_pipe, sizeof(uint32_t));
uc_mem_read(uc, esp_address + 0x8, &temp_pipe_attributes,
sizeof(uint32_t));
uc_mem_read(uc, esp_address + 0xC, &nSize, sizeof(uint32_t));
hReadPipe = temp_read_pipe;
hWritePipe = temp_write_pipe;
lpPipeAttributes = temp_pipe_attributes;
}
// 创建模拟的管道句柄
uint64_t read_handle = 0x1338; // 使用特殊值作为读取句柄
uint64_t write_handle = 0x1339; // 使用特殊值作为写入句柄
// 生成唯一的管道名称
char pipeName[MAX_PATH];
DWORD processId =
context->GetPeInfo()->isX64
? static_cast<DWORD>(context->GetTeb64()->ClientId.UniqueProcess)
: static_cast<DWORD>(context->GetTeb32()->ClientId.UniqueProcess);
snprintf(pipeName, sizeof(pipeName),
"\\\\.\\pipe\\sandbox_pipe_%lu_%llx_%llx", processId, read_handle,
write_handle);
// 写入句柄到输出参数
if (context->GetPeInfo()->isX64) {
uc_mem_write(uc, hReadPipe, &read_handle, sizeof(uint64_t));
uc_mem_write(uc, hWritePipe, &write_handle, sizeof(uint64_t));
} else {
uint32_t read_handle_32 = static_cast<uint32_t>(read_handle);
uint32_t write_handle_32 = static_cast<uint32_t>(write_handle);
uc_mem_write(uc, hReadPipe, &read_handle_32, sizeof(uint32_t));
uc_mem_write(uc, hWritePipe, &write_handle_32, sizeof(uint32_t));
}
// 设置返回值为TRUE
uint64_t result = 1;
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
printf(
"[*] CreatePipe: Name=%s, ReadHandle=0x%llx, WriteHandle=0x%llx, "
"Size=%u\n",
pipeName, read_handle, write_handle, nSize);
}

View File

@@ -0,0 +1,784 @@
#include "sandbox.h"
#include "sandbox_callbacks.h"
#include "sandbox_api_winhttp.h"
#include <tlhelp32.h>
// 内部实现函数,处理实际的模块句柄获取逻辑
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 Api_Process32FirstW(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto* context = static_cast<Sandbox*>(sandbox);
uint64_t hSnapshot = 0;
uint64_t lppe = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = hSnapshot, rdx = lppe (LPPROCESSENTRY32W)
uc_reg_read(uc, UC_X86_REG_RCX, &hSnapshot);
uc_reg_read(uc, UC_X86_REG_RDX, &lppe);
} else {
// x86: 从栈上读取参数
uint32_t esp = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
esp += 0x4; // 跳过返回地址
uint32_t temp_handle;
uint32_t temp_lppe;
uc_mem_read(uc, esp, &temp_handle, sizeof(uint32_t));
uc_mem_read(uc, esp + 0x4, &temp_lppe, sizeof(uint32_t));
hSnapshot = temp_handle;
lppe = temp_lppe;
}
// 验证句柄
bool success = false;
if (hSnapshot == 0x1337) { // 我们在CreateToolhelp32Snapshot中使用的魔数
// 读取结构体大小
DWORD structSize = 0;
if (uc_mem_read(uc, lppe, &structSize, sizeof(DWORD)) == UC_ERR_OK) {
if (structSize == sizeof(PROCESSENTRY32W)) {
// 获取第一个进程信息在我们的实现中是DingTalk.exe
PROCESSENTRY32W pe32 = {0};
pe32.dwSize = sizeof(PROCESSENTRY32W);
pe32.th32ProcessID = 1001; // DingTalk的PID
pe32.cntThreads = 1;
pe32.th32ParentProcessID = 4; // 父进程是System
pe32.pcPriClassBase = 8; // 正常优先级
// 设置进程名
std::wstring procName = L"DingTalk.exe";
wcscpy_s(pe32.szExeFile, procName.c_str());
// 写入进程信息到用户提供的缓冲区
if (uc_mem_write(uc, lppe, &pe32, sizeof(PROCESSENTRY32W)) ==
UC_ERR_OK) {
success = true;
}
}
}
}
printf("[*] Process32FirstW: Handle=0x%llx, Buffer=0x%llx, Success=%d\n",
hSnapshot, lppe, success);
// 设置返回值
uint64_t result = success ? 1 : 0;
if (context->GetPeInfo()->isX64) {
uc_reg_write(uc, UC_X86_REG_RAX, &result);
} else {
uint32_t result32 = static_cast<uint32_t>(result);
uc_reg_write(uc, UC_X86_REG_EAX, &result32);
}
// 设置错误码
DWORD error = success ? 0 : ERROR_NO_MORE_FILES;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
}
auto Api_CreateToolhelp32Snapshot(void* sandbox, uc_engine* uc,
uint64_t address) -> void {
auto* context = static_cast<Sandbox*>(sandbox);
uint32_t dwFlags = 0;
uint32_t th32ProcessID = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = dwFlags, rdx = th32ProcessID
uint64_t temp_flags;
uint64_t temp_pid;
uc_reg_read(uc, UC_X86_REG_RCX, &temp_flags);
uc_reg_read(uc, UC_X86_REG_RDX, &temp_pid);
dwFlags = static_cast<uint32_t>(temp_flags);
th32ProcessID = static_cast<uint32_t>(temp_pid);
} else {
// x86: 从栈上读取参数
uint32_t esp = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
esp += 0x4; // 跳过返回地址
uc_mem_read(uc, esp, &dwFlags, sizeof(uint32_t));
uc_mem_read(uc, esp + 0x4, &th32ProcessID, sizeof(uint32_t));
}
// 创建一个假的句柄值
uint64_t handle = 0x1337;
// 如果请求进程列表快照,初始化进程枚举状态
if (dwFlags & TH32CS_SNAPPROCESS) {
// 初始化进程枚举状态为-1这样Process32First会返回第一个进程
context->process_enum_state[handle] = -1;
// 清除错误码
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = 0;
} else {
context->GetTeb32()->LastErrorValue = 0;
}
}
printf(
"[*] CreateToolhelp32Snapshot: Flags=0x%x, ProcessID=0x%x, "
"Handle=0x%llx\n",
dwFlags, th32ProcessID, handle);
// 返回句柄
if (context->GetPeInfo()->isX64) {
uc_reg_write(uc, UC_X86_REG_RAX, &handle);
} else {
uint32_t handle32 = static_cast<uint32_t>(handle);
uc_reg_write(uc, UC_X86_REG_EAX, &handle32);
}
}
auto Api_Process32NextW(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto* context = static_cast<Sandbox*>(sandbox);
uint64_t hSnapshot = 0;
uint64_t lppe = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = hSnapshot, rdx = lppe (LPPROCESSENTRY32W)
uc_reg_read(uc, UC_X86_REG_RCX, &hSnapshot);
uc_reg_read(uc, UC_X86_REG_RDX, &lppe);
} else {
// x86: 从栈上读取参数
uint32_t esp = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
esp += 0x4; // 跳过返回地址
uint32_t temp_handle;
uint32_t temp_lppe;
uc_mem_read(uc, esp, &temp_handle, sizeof(uint32_t));
uc_mem_read(uc, esp + 0x4, &temp_lppe, sizeof(uint32_t));
hSnapshot = temp_handle;
lppe = temp_lppe;
}
// 验证句柄
bool success = false;
if (hSnapshot == 0x1337) { // 我们在CreateToolhelp32Snapshot中使用的魔数
// 读取结构体大小
DWORD structSize = 0;
if (uc_mem_read(uc, lppe, &structSize, sizeof(DWORD)) == UC_ERR_OK) {
if (structSize == sizeof(PROCESSENTRY32W)) {
// 获取当前进程索引
size_t currentIndex = 0;
auto it = context->process_enum_state.find(hSnapshot);
if (it != context->process_enum_state.end()) {
currentIndex = it->second;
currentIndex++; // 移动到下一个进程
}
// 定义进程列表
struct ProcessInfo {
const wchar_t* name;
uint32_t pid;
uint32_t parentPid;
};
ProcessInfo processes[] = {
{L"DingTalk.exe", 1001, 4}, // 钉钉
{L"Lanxin.exe", 1002, 4}, // 蓝信
{L"QQ.exe", 1003, 4}, // QQ
{L"Feishu.exe", 1004, 4}, // 飞书
{L"explorer.exe", 1005, 4}, // Windows 资源管理器
{L"svchost.exe", 1006, 4}, // 系统服务宿主进程
{L"System", 4, 0}, // 系统进程
{L"smss.exe", 376, 4}, // 会话管理器
{L"csrss.exe", 648, 376}, // 客户端服务器运行时子系统
{L"winlogon.exe", 672, 376}, // Windows 登录进程
};
const size_t processCount =
sizeof(processes) / sizeof(processes[0]);
// 检查是否还有更多进程
if (currentIndex < processCount) {
// 填充进程信息
PROCESSENTRY32W pe32 = {0};
pe32.dwSize = sizeof(PROCESSENTRY32W);
pe32.th32ProcessID = processes[currentIndex].pid;
pe32.th32ParentProcessID =
processes[currentIndex].parentPid;
pe32.cntThreads = 1;
pe32.pcPriClassBase = 8; // 正常优先级
// 设置进程名
wcscpy_s(pe32.szExeFile, processes[currentIndex].name);
// 写入进程信息到用户提供的缓冲区
if (uc_mem_write(uc, lppe, &pe32,
sizeof(PROCESSENTRY32W)) == UC_ERR_OK) {
success = true;
// 更新进程索引
context->process_enum_state[hSnapshot] = currentIndex;
}
}
}
}
}
printf("[*] Process32NextW: Handle=0x%llx, Buffer=0x%llx, Success=%d\n",
hSnapshot, lppe, success);
// 设置返回值
uint64_t result = success ? 1 : 0;
if (context->GetPeInfo()->isX64) {
uc_reg_write(uc, UC_X86_REG_RAX, &result);
} else {
uint32_t result32 = static_cast<uint32_t>(result);
uc_reg_write(uc, UC_X86_REG_EAX, &result32);
}
// 设置错误码
DWORD error = success ? 0 : ERROR_NO_MORE_FILES;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
}
auto Api_CreateProcessA(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t lpApplicationName = 0;
uint64_t lpCommandLine = 0;
uint64_t lpProcessInformation = 0;
uint64_t lpStartupInfo = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = lpApplicationName, rdx = lpCommandLine
uc_reg_read(uc, UC_X86_REG_RCX, &lpApplicationName);
uc_reg_read(uc, UC_X86_REG_RDX, &lpCommandLine);
// 从栈上获取 PROCESS_INFORMATION 和 STARTUPINFO
uint64_t rsp;
uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
rsp += 0x28; // 跳过前4个参数的影子空间
uc_mem_read(uc, rsp + 0x20, &lpProcessInformation, sizeof(uint64_t));
uc_mem_read(uc, rsp + 0x18, &lpStartupInfo, sizeof(uint64_t));
printf(
"[*] CreateProcessA Debug (x64): AppNameAddr=0x%llx, "
"CmdLineAddr=0x%llx\n",
lpApplicationName, lpCommandLine);
} else {
// x86: 从栈上读取参数
uint32_t esp;
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
esp += 0x4; // 跳过返回地址
uint32_t temp_app_name, temp_cmd_line, temp_proc_info,
temp_startup_info;
uc_mem_read(uc, esp, &temp_app_name, sizeof(uint32_t));
uc_mem_read(uc, esp + 0x4, &temp_cmd_line, sizeof(uint32_t));
// 修正x86下的参数读取偏移使用实际结构的偏移量
uc_mem_read(uc, esp + 0x24, &temp_proc_info, sizeof(uint32_t));
uc_mem_read(uc, esp + 0x1C, &temp_startup_info, sizeof(uint32_t));
lpApplicationName = temp_app_name;
lpCommandLine = temp_cmd_line;
lpProcessInformation = temp_proc_info;
lpStartupInfo = temp_startup_info;
printf(
"[*] CreateProcessA Debug (x86): ESP=0x%x, AppNameAddr=0x%x, "
"CmdLineAddr=0x%x\n",
esp, temp_app_name, temp_cmd_line);
}
// 读取应用程序名称
std::string applicationName;
if (lpApplicationName != 0) {
// 增加大小检测以避免内存溢出
char buffer[MAX_PATH] = {0};
size_t i = 0;
bool success = true;
do {
uint8_t byte;
uc_err err = uc_mem_read(uc, lpApplicationName + i, &byte, 1);
if (err != UC_ERR_OK) {
printf(
"[!] Error reading application name at address 0x%llx: "
"%u\n",
lpApplicationName + i, err);
success = false;
break;
}
buffer[i] = byte;
i++;
} while (buffer[i - 1] != 0 && i < MAX_PATH - 1);
// 确保字符串以 NULL 结尾
buffer[i] = 0;
if (success) {
applicationName = std::string(buffer);
printf("[*] Read ApplicationName: %s (Length: %zu)\n", buffer,
applicationName.length());
}
}
// 读取命令行
std::string commandLine;
if (lpCommandLine != 0) {
char buffer[MAX_PATH] = {0};
size_t i = 0;
bool success = true;
do {
uint8_t byte;
uc_err err = uc_mem_read(uc, lpCommandLine + i, &byte, 1);
if (err != UC_ERR_OK) {
printf("[!] Error reading command line at address 0x%llx: %u\n",
lpCommandLine + i, err);
success = false;
break;
}
buffer[i] = byte;
i++;
} while (buffer[i - 1] != 0 && i < MAX_PATH - 1);
// 确保字符串以 NULL 结尾
buffer[i] = 0;
if (success) {
commandLine = std::string(buffer);
printf("[*] Read CommandLine: %s (Length: %zu)\n", buffer,
commandLine.length());
}
}
printf("[*] CreateProcessA: ApplicationName=%s, CommandLine=%s\n",
applicationName.empty() ? "(null)" : applicationName.c_str(),
commandLine.empty() ? "(null)" : commandLine.c_str());
// 模拟创建进程设置进程和线程ID
DWORD processId = 0x1234;
DWORD threadId = 0x5678;
HANDLE hProcess = (HANDLE)0x1340;
HANDLE hThread = (HANDLE)0x1341;
// 写入进程信息
if (lpProcessInformation != 0) {
if (context->GetPeInfo()->isX64) {
struct PROCESS_INFORMATION64 {
HANDLE64 hProcess;
HANDLE64 hThread;
DWORD dwProcessId;
DWORD dwThreadId;
} pi;
pi.hProcess = (HANDLE64)hProcess;
pi.hThread = (HANDLE64)hThread;
pi.dwProcessId = processId;
pi.dwThreadId = threadId;
uc_mem_write(uc, lpProcessInformation, &pi, sizeof(pi));
printf("[*] Wrote process info (x64) to 0x%llx\n",
lpProcessInformation);
} else {
PROCESS_INFORMATION pi;
pi.hProcess = hProcess;
pi.hThread = hThread;
pi.dwProcessId = processId;
pi.dwThreadId = threadId;
uc_mem_write(uc, lpProcessInformation, &pi, sizeof(pi));
printf("[*] Wrote process info (x86) to 0x%llx\n",
lpProcessInformation);
}
}
// 返回成功
uint64_t result = 1;
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
}
auto Api_GetCurrentProcess(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
// GetCurrentProcess 总是返回伪句柄值 -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("[*] GetCurrentProcess called, returning pseudo-handle 0x%llx\n",
pseudo_handle);
}
auto Api_OpenProcessToken(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t ProcessHandle = 0;
uint32_t DesiredAccess = 0;
uint64_t TokenHandle = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = ProcessHandle, rdx = DesiredAccess, r8 = TokenHandle
uc_reg_read(uc, UC_X86_REG_RCX, &ProcessHandle);
uint64_t temp_access;
uc_reg_read(uc, UC_X86_REG_RDX, &temp_access);
DesiredAccess = static_cast<uint32_t>(temp_access);
uc_reg_read(uc, UC_X86_REG_R8, &TokenHandle);
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uint32_t temp_handle;
uc_mem_read(uc, esp_address, &temp_handle, sizeof(uint32_t));
ProcessHandle = temp_handle;
esp_address += 0x4;
uc_mem_read(uc, esp_address, &DesiredAccess, sizeof(uint32_t));
esp_address += 0x4;
uint32_t temp_token;
uc_mem_read(uc, esp_address, &temp_token, sizeof(uint32_t));
TokenHandle = temp_token;
}
// 创建一个假的token句柄使用一个非零值
uint64_t fake_token_handle = 0x1234;
// 将假的token句柄写入TokenHandle指向的内存
if (TokenHandle != 0) {
if (context->GetPeInfo()->isX64) {
uc_mem_write(uc, TokenHandle, &fake_token_handle, sizeof(uint64_t));
} else {
uint32_t token_handle_32 = static_cast<uint32_t>(fake_token_handle);
uc_mem_write(uc, TokenHandle, &token_handle_32, sizeof(uint32_t));
}
}
// 返回TRUE
uint64_t result = 1;
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
printf(
"[*] OpenProcessToken: ProcessHandle=0x%llx, DesiredAccess=0x%x, "
"TokenHandle=0x%llx\n",
ProcessHandle, DesiredAccess, fake_token_handle);
}
auto Api_GetTokenInformation(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t TokenHandle = 0;
uint32_t TokenInformationClass = 0;
uint64_t TokenInformation = 0;
uint32_t TokenInformationLength = 0;
uint64_t ReturnLength = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx, rdx, r8, r9, [rsp+0x28]
uc_reg_read(uc, UC_X86_REG_RCX, &TokenHandle);
uint64_t temp_class;
uc_reg_read(uc, UC_X86_REG_RDX, &temp_class);
TokenInformationClass = static_cast<uint32_t>(temp_class);
uc_reg_read(uc, UC_X86_REG_R8, &TokenInformation);
uint64_t temp_length;
uc_reg_read(uc, UC_X86_REG_R9, &temp_length);
TokenInformationLength = static_cast<uint32_t>(temp_length);
uint64_t rsp;
uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
uc_mem_read(uc, rsp + 0x28, &ReturnLength, sizeof(uint64_t));
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uint32_t temp_handle;
uc_mem_read(uc, esp_address, &temp_handle, sizeof(uint32_t));
TokenHandle = temp_handle;
esp_address += 0x4;
uc_mem_read(uc, esp_address, &TokenInformationClass, sizeof(uint32_t));
esp_address += 0x4;
uint32_t temp_info;
uc_mem_read(uc, esp_address, &temp_info, sizeof(uint32_t));
TokenInformation = temp_info;
esp_address += 0x4;
uc_mem_read(uc, esp_address, &TokenInformationLength, sizeof(uint32_t));
esp_address += 0x4;
uint32_t temp_return;
uc_mem_read(uc, esp_address, &temp_return, sizeof(uint32_t));
ReturnLength = temp_return;
}
// 如果是TokenElevation类20返回TRUE表示进程有管理员权限
if (TokenInformationClass == 20) { // TokenElevation
uint32_t is_elevated = 1; // 1表示有管理员权限
if (TokenInformation != 0 &&
TokenInformationLength >= sizeof(uint32_t)) {
uc_mem_write(uc, TokenInformation, &is_elevated, sizeof(uint32_t));
}
// 写入所需的缓冲区大小
uint32_t required_size = sizeof(uint32_t);
if (ReturnLength != 0) {
uc_mem_write(uc, ReturnLength, &required_size, sizeof(uint32_t));
}
}
// 返回TRUE
uint64_t result = 1;
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
printf(
"[*] GetTokenInformation: TokenHandle=0x%llx, Class=%d, Info=0x%llx, "
"Length=%u\n",
TokenHandle, TokenInformationClass, TokenInformation,
TokenInformationLength);
}

View File

@@ -1,6 +1,457 @@
#include "sandbox.h"
#include "sandbox_callbacks.h"
void Api_GetLastError(void* sandbox, uc_engine* uc, uint64_t address) {
auto context = static_cast<Sandbox*>(sandbox);
DWORD last_error = 0;
// 从TEB中获取LastError
if (context->GetPeInfo()->isX64) {
last_error = context->GetTeb64()->LastErrorValue;
} else {
last_error = context->GetTeb32()->LastErrorValue;
}
printf("[*] GetLastError: LastError=0x%x\n", last_error);
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&last_error);
}
auto Api_InitializeCriticalSectionAndSpinCount(void* sandbox, uc_engine* uc,
uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t lpCriticalSection = 0;
uint32_t dwSpinCount = 0;
BOOL success = TRUE; // 默认返回成功
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = lpCriticalSection, rdx = dwSpinCount
uc_reg_read(uc, UC_X86_REG_RCX, &lpCriticalSection);
uint64_t temp_spin_count = 0;
uc_reg_read(uc, UC_X86_REG_RDX, &temp_spin_count);
dwSpinCount = static_cast<uint32_t>(temp_spin_count);
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uint32_t temp_cs = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uc_mem_read(uc, esp_address, &temp_cs, sizeof(uint32_t));
lpCriticalSection = temp_cs;
esp_address += 0x4;
uc_mem_read(uc, esp_address, &dwSpinCount, sizeof(uint32_t));
}
if (lpCriticalSection != 0) {
// 初始化关键段结构
RTL_CRITICAL_SECTION cs = {0};
cs.LockCount = -1; // 初始未锁定状态
cs.RecursionCount = 0; // 初始递归计数为0
cs.SpinCount = dwSpinCount; // 设置自旋计数
cs.OwningThread = 0; // 初始无拥有线程
cs.LockSemaphore = 0; // 初始信号量为0
// 写入初始化后的结构到目标内存
uc_mem_write(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION));
} else {
success = FALSE;
// 设置LastError
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
}
printf(
"[*] InitializeCriticalSectionAndSpinCount: CS=0x%llx, SpinCount=0x%x, "
"Success=%d\n",
lpCriticalSection, dwSpinCount, success);
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&success);
}
auto Api_InitializeCriticalSectionEx(void* sandbox, uc_engine* uc,
uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t lpCriticalSection = 0;
uint32_t dwSpinCount = 0;
uint32_t dwFlags = 0;
BOOL success = TRUE; // 默认返回成功
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = lpCriticalSection, rdx = dwSpinCount, r8 = dwFlags
uc_reg_read(uc, UC_X86_REG_RCX, &lpCriticalSection);
uint64_t temp_spin_count = 0;
uc_reg_read(uc, UC_X86_REG_RDX, &temp_spin_count);
dwSpinCount = static_cast<uint32_t>(temp_spin_count);
uint64_t temp_flags = 0;
uc_reg_read(uc, UC_X86_REG_R8, &temp_flags);
dwFlags = static_cast<uint32_t>(temp_flags);
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uint32_t temp_cs = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uc_mem_read(uc, esp_address, &temp_cs, sizeof(uint32_t));
lpCriticalSection = temp_cs;
esp_address += 0x4;
uc_mem_read(uc, esp_address, &dwSpinCount, sizeof(uint32_t));
esp_address += 0x4;
uc_mem_read(uc, esp_address, &dwFlags, sizeof(uint32_t));
}
if (lpCriticalSection != 0) {
// 初始化关键段结构
RTL_CRITICAL_SECTION cs = {0};
cs.LockCount = -1; // 初始未锁定状态
cs.RecursionCount = 0; // 初始递归计数为0
cs.SpinCount = dwSpinCount; // 设置自旋计数
cs.OwningThread = 0; // 初始无拥有线程
cs.LockSemaphore = 0; // 初始信号量为0
// 处理特殊标志
// CRITICAL_SECTION_FLAG_NO_DEBUG_INFO = 0x01000000
// CRITICAL_SECTION_FLAG_DYNAMIC_SPIN = 0x02000000
// CRITICAL_SECTION_FLAG_STATIC_INIT = 0x04000000
// CRITICAL_SECTION_FLAG_RESOURCE_TYPE = 0x08000000
// CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO = 0x10000000
// 写入初始化后的结构到目标内存
uc_mem_write(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION));
} else {
success = FALSE;
// 设置LastError
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
}
printf(
"[*] InitializeCriticalSectionEx: CS=0x%llx, SpinCount=0x%x, "
"Flags=0x%x, "
"Success=%d\n",
lpCriticalSection, dwSpinCount, dwFlags, success);
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&success);
}
auto Api_TlsAlloc(void* sandbox, uc_engine* uc, uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
DWORD tls_index = TLS_OUT_OF_INDEXES; // 默认返回失败值
// 获取TEB结构
if (context->GetPeInfo()->isX64) {
auto teb = context->GetTeb64();
// 在TLS槽中查找第一个可用的位置
for (DWORD i = 0; i < 64; i++) { // TEB中TlsSlots数组大小为64
if (teb->TlsSlots[i] == (void*)0x1337ffffff) {
teb->TlsSlots[i] = (void*)0; // 标记为已使用
tls_index = i;
break;
}
}
} else {
auto teb = context->GetTeb32();
// 在TLS槽中查找第一个可用的位置
for (DWORD i = 0; i < 64; i++) { // TEB中TlsSlots数组大小为64
if (teb->TlsSlots[i] == 0x1337) {
teb->TlsSlots[i] = 0; // 标记为已使用
tls_index = i;
break;
}
}
}
if (tls_index == TLS_OUT_OF_INDEXES) {
// 设置LastError为没有可用的TLS索引
DWORD error = ERROR_NO_MORE_ITEMS;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
}
printf("[*] TlsAlloc: Allocated TLS Index=0x%x\n", tls_index);
// 返回分配的TLS索引
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&tls_index);
}
auto Api_TlsSetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint32_t dwTlsIndex = 0;
uint64_t lpTlsValue = 0;
BOOL success = FALSE;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = dwTlsIndex, rdx = lpTlsValue
uint64_t temp_index;
uc_reg_read(uc, UC_X86_REG_RCX, &temp_index);
dwTlsIndex = static_cast<uint32_t>(temp_index);
uc_reg_read(uc, UC_X86_REG_RDX, &lpTlsValue);
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uc_mem_read(uc, esp_address, &dwTlsIndex, sizeof(uint32_t));
esp_address += 0x4;
uint32_t temp_value;
uc_mem_read(uc, esp_address, &temp_value, sizeof(uint32_t));
lpTlsValue = temp_value;
}
// 检查索引是否有效小于64
if (dwTlsIndex < 64) {
if (context->GetPeInfo()->isX64) {
auto teb = context->GetTeb64();
// 检查槽是否已分配不为nullptr
if (teb->TlsSlots[dwTlsIndex] != (void*)0x1337ffffff) {
teb->TlsSlots[dwTlsIndex] = (void*)lpTlsValue;
success = TRUE;
}
} else {
auto teb = context->GetTeb32();
// 检查槽是否已分配不为0
if (teb->TlsSlots[dwTlsIndex] != 0x1337) {
teb->TlsSlots[dwTlsIndex] = static_cast<uint32_t>(lpTlsValue);
success = TRUE;
}
}
}
if (!success) {
// 设置LastError
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
}
printf("[*] TlsSetValue: Index=0x%x, Value=0x%llx, Success=%d\n",
dwTlsIndex, lpTlsValue, success);
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&success);
}
auto Api_DeleteCriticalSection(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t lpCriticalSection = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = lpCriticalSection
uc_reg_read(uc, UC_X86_REG_RCX, &lpCriticalSection);
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uint32_t temp_cs = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uc_mem_read(uc, esp_address, &temp_cs, sizeof(uint32_t));
lpCriticalSection = temp_cs;
}
if (lpCriticalSection != 0) {
// 读取现有的关键段结构
RTL_CRITICAL_SECTION cs;
uc_mem_read(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION));
// 检查是否有线程仍在等待
if (cs.LockCount >= 0) {
// 有线程正在等待,设置错误
DWORD error = ERROR_SEM_IS_SET;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
}
// 清零内存,表示删除
memset(&cs, 0, sizeof(RTL_CRITICAL_SECTION));
uc_mem_write(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION));
}
printf("[*] DeleteCriticalSection: CS=0x%llx\n", lpCriticalSection);
}
auto Api_IsProcessorFeaturePresent(void* sandbox, uc_engine* uc,
uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint32_t feature_number = 0;
BOOL is_supported = FALSE;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = FeatureNumber
uint64_t temp_feature;
uc_reg_read(uc, UC_X86_REG_RCX, &temp_feature);
feature_number = static_cast<uint32_t>(temp_feature);
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uc_mem_read(uc, esp_address, &feature_number, sizeof(uint32_t));
}
// 模拟一些常见的处理器特性
switch (feature_number) {
case PF_FLOATING_POINT_PRECISION_ERRATA: // 0
is_supported = FALSE;
break;
case PF_FLOATING_POINT_EMULATED: // 1
is_supported = FALSE;
break;
case PF_COMPARE_EXCHANGE_DOUBLE: // 2
is_supported = TRUE;
break;
case PF_MMX_INSTRUCTIONS_AVAILABLE: // 3
is_supported = TRUE;
break;
case PF_XMMI_INSTRUCTIONS_AVAILABLE: // 6
is_supported = TRUE;
break;
case PF_3DNOW_INSTRUCTIONS_AVAILABLE: // 7
is_supported = FALSE;
break;
case PF_RDTSC_INSTRUCTION_AVAILABLE: // 8
is_supported = TRUE;
break;
case PF_PAE_ENABLED: // 9
is_supported = TRUE;
break;
case PF_XMMI64_INSTRUCTIONS_AVAILABLE: // 10
is_supported = TRUE;
break;
case PF_SSE_DAZ_MODE_AVAILABLE: // 11
is_supported = TRUE;
break;
case PF_NX_ENABLED: // 12
is_supported = TRUE;
break;
case PF_SSE3_INSTRUCTIONS_AVAILABLE: // 13
is_supported = TRUE;
break;
case PF_COMPARE_EXCHANGE128: // 14
is_supported = TRUE;
break;
case PF_XSAVE_ENABLED: // 17
is_supported = TRUE;
break;
case PF_ARM_VFP_32_REGISTERS_AVAILABLE: // 18
is_supported = FALSE;
break;
default:
is_supported = FALSE;
break;
}
printf("[*] IsProcessorFeaturePresent: Feature=0x%x, Supported=%d\n",
feature_number, is_supported);
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&is_supported);
}
auto Api___set_app_type(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
int32_t appType = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = appType
uint64_t temp_type;
uc_reg_read(uc, UC_X86_REG_RCX, &temp_type);
appType = static_cast<int32_t>(temp_type);
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uc_mem_read(uc, esp_address, &appType, sizeof(int32_t));
}
// 简单地返回0表示成功
int32_t result = 0;
printf("[*] __set_app_type: AppType=%d\n", appType);
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
}
auto Api___p__fmode(void* sandbox, uc_engine* uc, uint64_t address) -> void {
auto sb = static_cast<Sandbox*>(sandbox);
// 检查是否已经创建了 _fmode 变量
static uint64_t fmode_address = 0;
static int32_t fmode_value = 0; // 默认为文本模式 (_O_TEXT)
if (fmode_address == 0) {
// 为 _fmode 变量分配内存
// 使用特定堆地址,与其他 API 一致
uint64_t heap_handle =
sb->GetPeInfo()->isX64 ? HEAP_ADDRESS_64 : HEAP_ADDRESS_32;
// 在堆上分配空间
HeapSegment* segment = nullptr;
auto it = sb->m_heapSegments.find(heap_handle);
if (it != sb->m_heapSegments.end()) {
segment = it->second;
} else {
// 创建新的堆段
segment = sb->CreateHeapSegment(heap_handle, 0x10000);
sb->m_heapSegments[heap_handle] = segment;
}
if (segment) {
fmode_address = sb->AllocateFromSegment(segment, sizeof(int32_t));
if (fmode_address) {
// 初始化 _fmode 为文本模式
uc_mem_write(uc, fmode_address, &fmode_value, sizeof(int32_t));
printf(
"[*] __p__fmode: Allocated _fmode at 0x%llx with value "
"%d\n",
fmode_address, fmode_value);
}
}
}
// 返回 _fmode 变量的地址
printf("[*] __p__fmode: Returning address 0x%llx\n", fmode_address);
// 设置返回值
if (sb->GetPeInfo()->isX64) {
uc_reg_write(uc, UC_X86_REG_RAX, &fmode_address);
} else {
uint32_t eax = static_cast<uint32_t>(fmode_address);
uc_reg_write(uc, UC_X86_REG_EAX, &eax);
}
}
// 实现 AreFileApisANSI API
auto Api_AreFileApisANSI(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
@@ -687,18 +1138,21 @@ auto Api_HeapAlloc(void* sandbox, uc_engine* uc, uint64_t address) -> void {
uc_mem_read(uc, esp_address, &temp_bytes, sizeof(uint32_t));
dwBytes = temp_bytes;
}
// 这里如果想检查有效,得先跑main,再跑其他的,浪费时间了,操
// 检查堆句柄是否有效
/*
uint64_t expected_handle =
context->GetPeInfo()->isX64 ? HEAP_ADDRESS_64 : HEAP_ADDRESS_32;
if (hHeap != expected_handle) {
uint64_t null_ptr = 0;
hHeap = expected_handle;
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&null_ptr);
return;
}
*/
// 获取或创建堆段
HeapSegment* segment = nullptr;
auto it = context->m_heapSegments.find(hHeap);
@@ -1512,4 +1966,162 @@ auto Sandbox::AllocateFromSegment(HeapSegment* segment, size_t size)
}
return 0; // 分配失败
}
}
auto Api_CloseHandle(void* sandbox, uc_engine* uc, uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t handle = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = handle
uc_reg_read(uc, UC_X86_REG_RCX, &handle);
} else {
// x86: 从栈上读取参数
uint32_t esp = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
esp += 0x4; // 跳过返回地址
uint32_t temp_handle;
uc_mem_read(uc, esp, &temp_handle, sizeof(uint32_t));
handle = temp_handle;
}
bool success = true;
// 如果是进程快照句柄 (0x1337),清理进程枚举状态
if (handle == 0x1337) {
auto it = context->process_enum_state.find(handle);
if (it != context->process_enum_state.end()) {
context->process_enum_state.erase(it);
}
}
// 其他类型的句柄也返回成功
// 实际应用中可能需要根据句柄类型进行不同的处理
printf("[*] CloseHandle: Handle=0x%llx, Success=%d\n", handle, success);
// 设置返回值
uint64_t result = success ? 1 : 0;
if (context->GetPeInfo()->isX64) {
uc_reg_write(uc, UC_X86_REG_RAX, &result);
} else {
uint32_t result32 = static_cast<uint32_t>(result);
uc_reg_write(uc, UC_X86_REG_EAX, &result32);
}
// 设置错误码
DWORD error = success ? 0 : ERROR_INVALID_HANDLE;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
}
// 添加RtlFormatCurrentUserKeyPath API实现
auto Api_RtlFormatCurrentUserKeyPath(void* sandbox, uc_engine* uc,
uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t keyPathBuffer = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = KeyPathBuffer
uc_reg_read(uc, UC_X86_REG_RCX, &keyPathBuffer);
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uint32_t temp_buffer;
uc_mem_read(uc, esp_address, &temp_buffer, sizeof(uint32_t));
keyPathBuffer = temp_buffer;
}
// 构造当前用户的注册表路径
// 同时在这里实现查询MCP服务器的功能
wchar_t userKeyPath[256] =
L"\\Registry\\User\\S-1-5-21-1234567890-1234567890-1234567890-1001";
// 模拟查询MCP服务器这里可以根据需要实现实际的服务器查询
// 例如可以修改userKeyPath或在日志中记录查询操作
printf("[*] RtlFormatCurrentUserKeyPath: 正在查询MCP服务器获取用户SID\n");
// 将路径写入到提供的缓冲区
if (keyPathBuffer != 0) {
uc_mem_write(uc, keyPathBuffer, userKeyPath,
(wcslen(userKeyPath) + 1) * sizeof(wchar_t));
}
// 返回NTSTATUS成功代码 (0x00000000 = STATUS_SUCCESS)
uint64_t status = 0;
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&status);
printf("[*] RtlFormatCurrentUserKeyPath: Buffer=0x%llx, Path=%ls\n",
keyPathBuffer, userKeyPath);
}
// 添加FlsSetValue API实现
auto Api_FlsSetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t dwFlsIndex = 0;
uint64_t lpFlsData = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = dwFlsIndex, rdx = lpFlsData
uc_reg_read(uc, UC_X86_REG_RCX, &dwFlsIndex);
uc_reg_read(uc, UC_X86_REG_RDX, &lpFlsData);
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uint32_t temp_index;
uint32_t temp_data;
uc_mem_read(uc, esp_address, &temp_index, sizeof(uint32_t));
uc_mem_read(uc, esp_address + 0x4, &temp_data, sizeof(uint32_t));
dwFlsIndex = temp_index;
lpFlsData = temp_data;
}
// 模拟FLS存储操作类似于TLS存储
bool success = false;
if (dwFlsIndex < 64) { // 使用与TLS相同的槽位大小
// 存储数据到模拟的FLS槽中复用TLS槽
if (context->GetPeInfo()->isX64) {
auto teb = context->GetTeb64();
if (teb->TlsSlots[dwFlsIndex] != (void*)0x1337ffffff) {
teb->TlsSlots[dwFlsIndex] = (void*)lpFlsData;
success = true;
}
} else {
auto teb = context->GetTeb32();
if (teb->TlsSlots[dwFlsIndex] != 0x1337) {
teb->TlsSlots[dwFlsIndex] = static_cast<uint32_t>(lpFlsData);
success = true;
}
}
}
printf("[*] FlsSetValue: Index=%llu, Data=0x%llx, Success=%d\n", dwFlsIndex,
lpFlsData, success);
// 设置返回值
uint64_t result = success ? 1 : 0;
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
// 如果失败,设置错误码
if (!success) {
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
}
}

View File

@@ -0,0 +1,220 @@
#include "sandbox.h"
#include "sandbox_callbacks.h"
#include <fwpmu.h>
// FwpmEngineOpen0 API模拟
auto Api_FwpmEngineOpen0(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t serverName = 0;
uint64_t authnService = 0;
uint64_t authIdentity = 0;
uint64_t session = 0;
uint64_t engineHandle = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
uc_reg_read(uc, UC_X86_REG_RCX, &serverName);
uc_reg_read(uc, UC_X86_REG_RDX, &authnService);
uc_reg_read(uc, UC_X86_REG_R8, &authIdentity);
uc_reg_read(uc, UC_X86_REG_R9, &session);
uint64_t rsp;
uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
uc_mem_read(uc, rsp + 0x28, &engineHandle, sizeof(engineHandle));
} else {
uint32_t esp;
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
esp += 4; // 跳过返回地址
uint32_t temp;
uc_mem_read(uc, esp, &temp, sizeof(temp));
serverName = temp;
esp += 4;
uc_mem_read(uc, esp, &temp, sizeof(temp));
authnService = temp;
esp += 4;
uc_mem_read(uc, esp, &temp, sizeof(temp));
authIdentity = temp;
esp += 4;
uc_mem_read(uc, esp, &temp, sizeof(temp));
session = temp;
esp += 4;
uc_mem_read(uc, esp, &temp, sizeof(temp));
engineHandle = temp;
}
// 创建新的WFP引擎实例
auto engine = new Sandbox::FakeWFPEngine();
engine->isOpen = true;
HANDLE handle = context->GetNextWfpEngineHandle();
context->GetWfpEngines()[handle] = engine;
// 写回引擎句柄
if (context->GetPeInfo()->isX64) {
uc_mem_write(uc, engineHandle, &handle, sizeof(handle));
} else {
uint32_t handle32 = (uint32_t)(uint64_t)handle;
uc_mem_write(uc, engineHandle, &handle32, sizeof(handle32));
}
// 返回成功
uint64_t result = ERROR_SUCCESS;
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
printf("[*] FwpmEngineOpen0: Handle=0x%llx\n", (uint64_t)handle);
}
// FwpmProviderAdd0 API模拟
auto Api_FwpmProviderAdd0(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t engineHandle = 0;
uint64_t provider = 0;
uint64_t sd = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
uc_reg_read(uc, UC_X86_REG_RCX, &engineHandle);
uc_reg_read(uc, UC_X86_REG_RDX, &provider);
uc_reg_read(uc, UC_X86_REG_R8, &sd);
} else {
uint32_t esp;
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
esp += 4;
uint32_t temp;
uc_mem_read(uc, esp, &temp, sizeof(temp));
engineHandle = temp;
esp += 4;
uc_mem_read(uc, esp, &temp, sizeof(temp));
provider = temp;
esp += 4;
uc_mem_read(uc, esp, &temp, sizeof(temp));
sd = temp;
}
// 检查引擎句柄是否有效
auto& engines = context->GetWfpEngines();
auto it = engines.find((HANDLE)engineHandle);
if (it == engines.end()) {
uint64_t result = ERROR_INVALID_HANDLE;
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
return;
}
// 添加提供者
FWPM_PROVIDER0 providerData;
uc_mem_read(uc, provider, &providerData, sizeof(FWPM_PROVIDER0));
it->second->providers.push_back(providerData);
// 返回成功
uint64_t result = ERROR_SUCCESS;
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
printf("[*] FwpmProviderAdd0: Handle=0x%llx\n", engineHandle);
}
// FwpmFilterAdd0 API模拟
auto Api_FwpmFilterAdd0(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t engineHandle = 0;
uint64_t filter = 0;
uint64_t sd = 0;
uint64_t id = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
uc_reg_read(uc, UC_X86_REG_RCX, &engineHandle);
uc_reg_read(uc, UC_X86_REG_RDX, &filter);
uc_reg_read(uc, UC_X86_REG_R8, &sd);
uc_reg_read(uc, UC_X86_REG_R9, &id);
} else {
uint32_t esp;
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
esp += 4;
uint32_t temp;
uc_mem_read(uc, esp, &temp, sizeof(temp));
engineHandle = temp;
esp += 4;
uc_mem_read(uc, esp, &temp, sizeof(temp));
filter = temp;
esp += 4;
uc_mem_read(uc, esp, &temp, sizeof(temp));
sd = temp;
esp += 4;
uc_mem_read(uc, esp, &temp, sizeof(temp));
id = temp;
}
// 检查引擎句柄是否有效
auto& engines = context->GetWfpEngines();
auto it = engines.find((HANDLE)engineHandle);
if (it == engines.end()) {
uint64_t result = ERROR_INVALID_HANDLE;
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
return;
}
// 添加过滤器
FWPM_FILTER0 filterData;
uc_mem_read(uc, filter, &filterData, sizeof(FWPM_FILTER0));
it->second->filters.push_back(filterData);
// 生成并写回过滤器ID
static uint64_t nextFilterId = 1;
uint64_t filterId = nextFilterId++;
if (id != 0) {
uc_mem_write(uc, id, &filterId, sizeof(filterId));
}
// 返回成功
uint64_t result = ERROR_SUCCESS;
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
printf("[*] FwpmFilterAdd0: Handle=0x%llx, FilterId=0x%llx\n", engineHandle,
filterId);
}
// FwpmEngineClose0 API模拟
auto Api_FwpmEngineClose0(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t engineHandle = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
uc_reg_read(uc, UC_X86_REG_RCX, &engineHandle);
} else {
uint32_t esp;
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
esp += 4;
uint32_t temp;
uc_mem_read(uc, esp, &temp, sizeof(temp));
engineHandle = temp;
}
// 检查并关闭引擎
auto& engines = context->GetWfpEngines();
auto it = engines.find((HANDLE)engineHandle);
if (it != engines.end()) {
delete it->second;
engines.erase(it);
}
// 返回成功
uint64_t result = ERROR_SUCCESS;
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
printf("[*] FwpmEngineClose0: Handle=0x%llx\n", engineHandle);
}

View File

@@ -0,0 +1,286 @@
#include "sandbox.h"
#include "sandbox_callbacks.h"
#include "sandbox_api_winhttp.h"
#include <tlhelp32.h>
// WLAN API 实现
auto Api_WlanOpenHandle(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t dwClientVersion = 0;
uint64_t pReserved = 0;
uint64_t pdwNegotiatedVersion = 0;
uint64_t phClientHandle = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
uc_reg_read(uc, UC_X86_REG_RCX, &dwClientVersion);
uc_reg_read(uc, UC_X86_REG_RDX, &pReserved);
uc_reg_read(uc, UC_X86_REG_R8, &pdwNegotiatedVersion);
uc_reg_read(uc, UC_X86_REG_R9, &phClientHandle);
} else {
uint32_t esp;
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
esp += 4;
uc_mem_read(uc, esp, &dwClientVersion, sizeof(uint32_t));
esp += 4;
uint32_t temp_reserved;
uc_mem_read(uc, esp, &temp_reserved, sizeof(uint32_t));
pReserved = temp_reserved;
esp += 4;
uint32_t temp_version;
uc_mem_read(uc, esp, &temp_version, sizeof(uint32_t));
pdwNegotiatedVersion = temp_version;
esp += 4;
uint32_t temp_handle;
uc_mem_read(uc, esp, &temp_handle, sizeof(uint32_t));
phClientHandle = temp_handle;
}
// 修改常量定义
uint32_t negotiatedVersion = 2; // 返回请求的版本
uint64_t clientHandle = 0x13370000; // 使用有效的十六进制常量
// 写入协商版本
if (pdwNegotiatedVersion != 0) {
uc_mem_write(uc, pdwNegotiatedVersion, &negotiatedVersion,
sizeof(uint32_t));
}
// 写入客户端句柄
if (phClientHandle != 0) {
if (context->GetPeInfo()->isX64) {
uc_mem_write(uc, phClientHandle, &clientHandle, sizeof(uint64_t));
} else {
uint32_t handle32 = static_cast<uint32_t>(clientHandle);
uc_mem_write(uc, phClientHandle, &handle32, sizeof(uint32_t));
}
}
// 返回成功0
uint64_t result = 0;
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
printf("[*] WlanOpenHandle: Version=%u, Handle=0x%llx\n", negotiatedVersion,
clientHandle);
}
auto Api_WlanEnumInterfaces(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t hClientHandle = 0;
uint64_t pReserved = 0;
uint64_t ppInterfaceList = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
uc_reg_read(uc, UC_X86_REG_RCX, &hClientHandle);
uc_reg_read(uc, UC_X86_REG_RDX, &pReserved);
uc_reg_read(uc, UC_X86_REG_R8, &ppInterfaceList);
} else {
uint32_t esp;
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
esp += 4;
uint32_t temp_handle;
uc_mem_read(uc, esp, &temp_handle, sizeof(uint32_t));
hClientHandle = temp_handle;
esp += 4;
uint32_t temp_reserved;
uc_mem_read(uc, esp, &temp_reserved, sizeof(uint32_t));
pReserved = temp_reserved;
esp += 4;
uint32_t temp_list;
uc_mem_read(uc, esp, &temp_list, sizeof(uint32_t));
ppInterfaceList = temp_list;
}
// 修改句柄检查
if (hClientHandle != 0x13370000) {
uint64_t result = 1; // ERROR_INVALID_HANDLE
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
return;
}
// 分配内存用于接口列表
uint64_t interfaceListAddr = context->AllocateMemory(1024); // 足够大的空间
// 创建一个模拟的WLAN接口列表
struct WLAN_INTERFACE_INFO {
GUID InterfaceGuid;
WCHAR strInterfaceDescription[256];
DWORD isState;
};
struct WLAN_INTERFACE_INFO_LIST {
DWORD dwNumberOfItems;
DWORD dwIndex;
WLAN_INTERFACE_INFO InterfaceInfo[1];
};
WLAN_INTERFACE_INFO_LIST interfaceList = {0};
interfaceList.dwNumberOfItems = 1;
interfaceList.dwIndex = 0;
// 创建一个假的GUID
GUID fakeGuid = {0x12345678,
0x1234,
0x1234,
{0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF}};
interfaceList.InterfaceInfo[0].InterfaceGuid = fakeGuid;
// 设置接口描述
const wchar_t* description = L"Simulated Wi-Fi Adapter";
wcscpy_s(interfaceList.InterfaceInfo[0].strInterfaceDescription,
description);
interfaceList.InterfaceInfo[0].isState = 1; // connected
// 写入接口列表
uc_mem_write(uc, interfaceListAddr, &interfaceList,
sizeof(WLAN_INTERFACE_INFO_LIST));
// 写入接口列表指针
if (context->GetPeInfo()->isX64) {
uc_mem_write(uc, ppInterfaceList, &interfaceListAddr, sizeof(uint64_t));
} else {
uint32_t addr32 = static_cast<uint32_t>(interfaceListAddr);
uc_mem_write(uc, ppInterfaceList, &addr32, sizeof(uint32_t));
}
// 返回成功0
uint64_t result = 0;
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
printf("[*] WlanEnumInterfaces: Handle=0x%llx, InterfaceList=0x%llx\n",
hClientHandle, interfaceListAddr);
}
auto Api_WlanGetProfileList(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t hClientHandle = 0;
uint64_t pInterfaceGuid = 0;
uint64_t pReserved = 0;
uint64_t ppProfileList = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
uc_reg_read(uc, UC_X86_REG_RCX, &hClientHandle);
uc_reg_read(uc, UC_X86_REG_RDX, &pInterfaceGuid);
uc_reg_read(uc, UC_X86_REG_R8, &pReserved);
uc_reg_read(uc, UC_X86_REG_R9, &ppProfileList);
} else {
uint32_t esp;
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
esp += 4;
uint32_t temp_values[4];
uc_mem_read(uc, esp, temp_values, sizeof(uint32_t) * 4);
hClientHandle = temp_values[0];
pInterfaceGuid = temp_values[1];
pReserved = temp_values[2];
ppProfileList = temp_values[3];
}
// 分配内存用于配置文件列表
uint64_t profileListAddr = context->AllocateMemory(1024);
// 创建模拟的配置文件列表
struct WLAN_PROFILE_INFO {
WCHAR strProfileName[256];
DWORD dwFlags;
};
struct WLAN_PROFILE_INFO_LIST {
DWORD dwNumberOfItems;
DWORD dwIndex;
WLAN_PROFILE_INFO ProfileInfo[1];
};
WLAN_PROFILE_INFO_LIST profileList = {0};
profileList.dwNumberOfItems = 1;
profileList.dwIndex = 0;
// 设置一个模拟的配置文件
const wchar_t* profileName = L"Home Network";
wcscpy_s(profileList.ProfileInfo[0].strProfileName, profileName);
profileList.ProfileInfo[0].dwFlags = 1;
// 写入配置文件列表
uc_mem_write(uc, profileListAddr, &profileList,
sizeof(WLAN_PROFILE_INFO_LIST));
// 写入配置文件列表指针
if (context->GetPeInfo()->isX64) {
uc_mem_write(uc, ppProfileList, &profileListAddr, sizeof(uint64_t));
} else {
uint32_t addr32 = static_cast<uint32_t>(profileListAddr);
uc_mem_write(uc, ppProfileList, &addr32, sizeof(uint32_t));
}
// 返回成功0
uint64_t result = 0;
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
printf("[*] WlanGetProfileList: Handle=0x%llx, ProfileList=0x%llx\n",
hClientHandle, profileListAddr);
}
auto Api_WlanFreeMemory(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t pMemory = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
uc_reg_read(uc, UC_X86_REG_RCX, &pMemory);
} else {
uint32_t esp;
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
esp += 4;
uint32_t temp_memory;
uc_mem_read(uc, esp, &temp_memory, sizeof(uint32_t));
pMemory = temp_memory;
}
// 实际上我们不需要释放内存,因为这是在模拟环境中
printf("[*] WlanFreeMemory: Memory=0x%llx\n", pMemory);
}
auto Api_WlanCloseHandle(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t hClientHandle = 0;
uint64_t pReserved = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
uc_reg_read(uc, UC_X86_REG_RCX, &hClientHandle);
uc_reg_read(uc, UC_X86_REG_RDX, &pReserved);
} else {
uint32_t esp;
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
esp += 4;
uint32_t temp_handle;
uc_mem_read(uc, esp, &temp_handle, sizeof(uint32_t));
hClientHandle = temp_handle;
esp += 4;
uint32_t temp_reserved;
uc_mem_read(uc, esp, &temp_reserved, sizeof(uint32_t));
pReserved = temp_reserved;
}
// 返回成功0
uint64_t result = 0;
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
printf("[*] WlanCloseHandle: Handle=0x%llx\n", hClientHandle);
}

View File

@@ -5,6 +5,7 @@ void handleCodeRun(uc_engine* uc, uint64_t address, uint32_t size,
uint64_t currentRip = 0;
uint64_t currentRsp = 0;
uint64_t currentRax = 0;
static uint64_t lastRip = 0;
auto* sandbox = static_cast<Sandbox*>(userData);
if (!sandbox) return;
@@ -61,12 +62,15 @@ void handleCodeRun(uc_engine* uc, uint64_t address, uint32_t size,
for (auto item : module->export_function) {
const auto vmAddress = module->base + item->function_address;
if (vmAddress == currentRip) {
printf("[%s] call function %s at file address: %llx\n",
module->name, item->name, address);
printf(
"[%s] call function %s at file address: %llx lastRip: "
"%llx\n",
module->name, item->name, address, lastRip);
sandbox->EmulateApi(uc, vmAddress, currentRip, item->name);
}
}
}
lastRip = currentRip;
if (LOG_LEVEL > 0) {
// 使用Capstone反汇编
cs_insn* instruction;

View File

@@ -0,0 +1,3 @@
#pragma once
#include "head.h"
#include <fwpmtypes.h>