调不了了 终极大招了

This commit is contained in:
Huoji's
2025-03-07 01:47:01 +08:00
parent 3f022ddd01
commit 8504a9c8f9
6 changed files with 748 additions and 25 deletions

View File

@@ -32,7 +32,7 @@ auto getPeInfo(std::string inputFilePath) -> std::shared_ptr<BasicPeInfo> {
return sampleInfo; return sampleInfo;
} }
int main() { int main() {
auto sampleInfo = getPeInfo("C:\\ConsoleApplication1.exe"); auto sampleInfo = getPeInfo("E:\\对战平台\\CrowAntiCheat\\CrowAntiCheat\\client\\Console_Test\\x64\\Release\\Console_Test.exe");
printf("input new file %s \n", sampleInfo->inputFilePath); printf("input new file %s \n", sampleInfo->inputFilePath);
printf("is x64: %d\n", sampleInfo->isX64); printf("is x64: %d\n", sampleInfo->isX64);
printf("is relocated: %d\n", sampleInfo->isRelocated); printf("is relocated: %d\n", sampleInfo->isRelocated);

View File

@@ -399,8 +399,8 @@ auto Sandbox::SetupVirtualMachine() -> void {
m_tebBase = TEB_BASE; // 进程TEB地址 m_tebBase = TEB_BASE; // 进程TEB地址
m_pebBase = PEB_BASE; // 进程PEB地址 m_pebBase = PEB_BASE; // 进程PEB地址
// stack // stack
m_stackBase = this->m_peInfo->isX64 ? STACK_BASE_64 : STACK_BASE_32; m_stackBase = AlignSize(this->m_peInfo->isX64 ? STACK_BASE_64 : STACK_BASE_32, 16);
m_stackSize = this->m_peInfo->isX64 ? STACK_SIZE_64 : STACK_SIZE_32; m_stackSize = AlignSize(this->m_peInfo->isX64 ? STACK_SIZE_64 : STACK_SIZE_32, 16);
m_stackEnd = m_stackBase + m_stackSize; m_stackEnd = m_stackBase + m_stackSize;
// heap // heap
@@ -525,7 +525,6 @@ auto Sandbox::InitEnv(std::shared_ptr<BasicPeInfo> peInfo) -> void {
printf("map file to vm size: %llx\n", m_peInfo->peSize); printf("map file to vm size: %llx\n", m_peInfo->peSize);
SetupVirtualMachine(); SetupVirtualMachine();
InitCommandLine(peInfo->inputFilePath); InitCommandLine(peInfo->inputFilePath);
} }
auto Sandbox::Run() -> void { auto Sandbox::Run() -> void {
@@ -544,12 +543,16 @@ auto Sandbox::Run() -> void {
} }
// 设置寄存器 // 设置寄存器
uint64_t rsp = m_stackEnd - 128; uint64_t rsp = m_stackEnd - 256;
err = uc_reg_write(m_ucEngine, err = uc_reg_write(m_ucEngine,
m_peInfo->isX64 ? UC_X86_REG_RSP : UC_X86_REG_ESP, &rsp); m_peInfo->isX64 ? UC_X86_REG_RSP : UC_X86_REG_ESP, &rsp);
if (err != UC_ERR_OK) { if (err != UC_ERR_OK) {
throw std::runtime_error("Failed to write stack pointer"); throw std::runtime_error("Failed to write stack pointer");
} }
uint64_t rbp =
rsp - (m_peInfo->isX64 ? sizeof(uint64_t) : sizeof(uint32_t));
uc_reg_write(m_ucEngine, m_peInfo->isX64 ? UC_X86_REG_RBP : UC_X86_REG_EBP,
&rbp);
// 设置入口点 // 设置入口点
uint64_t entryPoint = m_peInfo->RecImageBase + m_peInfo->entryPoint; uint64_t entryPoint = m_peInfo->RecImageBase + m_peInfo->entryPoint;
@@ -610,10 +613,9 @@ auto Sandbox::Run() -> void {
throw std::runtime_error("Failed to set entry point"); throw std::runtime_error("Failed to set entry point");
} }
// 开始执行 InitApiHooks();
std::cout << "Starting execution at " << std::hex << entryPoint std::cout << "Starting execution at " << std::hex << entryPoint
<< std::endl; << std::endl;
InitApiHooks();
err = uc_emu_start(m_ucEngine, entryPoint, m_peInfo->imageEnd, 0, 0); err = uc_emu_start(m_ucEngine, entryPoint, m_peInfo->imageEnd, 0, 0);
if (err != UC_ERR_OK) { if (err != UC_ERR_OK) {
std::cerr << "Emulation error: " << uc_strerror(err) << std::endl; std::cerr << "Emulation error: " << uc_strerror(err) << std::endl;

View File

@@ -10,10 +10,10 @@
#define SF_MASK (1 << 7) #define SF_MASK (1 << 7)
#define OF_MASK (1 << 11) #define OF_MASK (1 << 11)
#define ALL_MASK (OF_MASK | SF_MASK | ZF_MASK | PF_MASK | CF_MASK) #define ALL_MASK (OF_MASK | SF_MASK | ZF_MASK | PF_MASK | CF_MASK)
#define STACK_BASE_64 0x7ffffffde000 #define STACK_BASE_64 0x14A0000
#define STACK_BASE_32 0xfffdd000 #define STACK_BASE_32 0x14A0000
#define STACK_SIZE_64 0x40000 #define STACK_SIZE_64 0x40000
#define STACK_SIZE_32 0x21000 #define STACK_SIZE_32 0x40000
#define HEAP_ADDRESS_64 0x500000000 #define HEAP_ADDRESS_64 0x500000000
#define HEAP_SIZE_64 0x5000000 #define HEAP_SIZE_64 0x5000000
#define HEAP_ADDRESS_32 0x5000000 #define HEAP_ADDRESS_32 0x5000000

View File

@@ -1,4 +1,5 @@
#include "sandbox.h" #include "sandbox.h"
#include "sandbox_callbacks.h"
std::string getDllNameFromApiSetMap(const std::string& apiSet); std::string getDllNameFromApiSetMap(const std::string& apiSet);
auto Api_QueryPerformanceCounter(void* sandbox, uc_engine* uc, uint64_t address) auto Api_QueryPerformanceCounter(void* sandbox, uc_engine* uc, uint64_t address)
-> void { -> void {
@@ -1145,6 +1146,240 @@ auto Api_GetCPInfo(void* sandbox, uc_engine* uc, uint64_t address) -> void {
&success); &success);
} }
auto Api_MultiByteToWideChar(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint32_t CodePage = 0;
uint32_t dwFlags = 0;
uint64_t lpMultiByteStr = 0;
int32_t cbMultiByte = 0;
uint64_t lpWideCharStr = 0;
int32_t cchWideChar = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
uint64_t temp_codepage = 0;
uint64_t temp_flags = 0;
uint64_t temp_multibyte = 0;
uint64_t temp_cbmultibyte = 0;
// x64: rcx, rdx, r8, r9, [rsp+0x28], [rsp+0x30]
uc_reg_read(uc, UC_X86_REG_RCX, &temp_codepage);
uc_reg_read(uc, UC_X86_REG_RDX, &temp_flags);
uc_reg_read(uc, UC_X86_REG_R8, &temp_multibyte);
uc_reg_read(uc, UC_X86_REG_R9, &temp_cbmultibyte);
CodePage = static_cast<uint32_t>(temp_codepage);
dwFlags = static_cast<uint32_t>(temp_flags);
lpMultiByteStr = temp_multibyte;
cbMultiByte = static_cast<int32_t>(temp_cbmultibyte);
// 获取栈上的参数
uint64_t rsp = 0;
uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
// 为了确保安全访问,先验证栈地址的有效性
if (rsp < 0x8000000000000000 || rsp + 0x40 > 0x8000000000010000) {
// 无效的栈地址
DWORD error = ERROR_INVALID_PARAMETER;
context->GetTeb64()->LastErrorValue = error;
int result = 0;
uc_reg_write(uc, UC_X86_REG_RAX, &result);
return;
}
// 读取栈上的参数
uint64_t shadow_space = 0x20; // x64调用约定中的shadow space
uc_mem_read(uc, rsp + shadow_space + 0x8, &lpWideCharStr,
sizeof(uint64_t));
uc_mem_read(uc, rsp + shadow_space + 0x10, &cchWideChar,
sizeof(int32_t));
} 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, &CodePage, sizeof(uint32_t));
uc_mem_read(uc, esp_address + 0x4, &dwFlags, sizeof(uint32_t));
uc_mem_read(uc, esp_address + 0x8, &lpMultiByteStr, sizeof(uint32_t));
uc_mem_read(uc, esp_address + 0xC, &cbMultiByte, sizeof(int32_t));
uc_mem_read(uc, esp_address + 0x10, &lpWideCharStr, sizeof(uint32_t));
uc_mem_read(uc, esp_address + 0x14, &cchWideChar, sizeof(int32_t));
}
// 验证参数
if (lpMultiByteStr == 0 || (lpWideCharStr == 0 && cchWideChar != 0)) {
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
int result = 0;
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
return;
}
// 读取源字符串
std::vector<char> srcBuffer;
if (cbMultiByte == -1) {
// 如果长度为-1,则源字符串以null结尾
char ch = 0;
size_t len = 0;
do {
if (uc_mem_read(uc, lpMultiByteStr + len, &ch, 1) != UC_ERR_OK) {
break;
}
srcBuffer.push_back(ch);
len++;
} while (ch != 0 && len < MAX_PATH); // 添加长度限制防止无限循环
if (len >= MAX_PATH) {
// 设置错误码
DWORD error = ERROR_INSUFFICIENT_BUFFER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
int result = 0;
uc_reg_write(
uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
return;
}
cbMultiByte = static_cast<int32_t>(len);
} else if (cbMultiByte > 0) {
// 使用指定长度,但添加安全检查
if (cbMultiByte > MAX_PATH) {
DWORD error = ERROR_INSUFFICIENT_BUFFER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
int result = 0;
uc_reg_write(
uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
return;
}
srcBuffer.resize(cbMultiByte);
if (uc_mem_read(uc, lpMultiByteStr, srcBuffer.data(), cbMultiByte) !=
UC_ERR_OK) {
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
int result = 0;
uc_reg_write(
uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
return;
}
} else {
// 无效的输入长度
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
int result = 0;
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
return;
}
// 计算所需的宽字符缓冲区大小
int result = MultiByteToWideChar(CodePage, dwFlags, srcBuffer.data(),
cbMultiByte, nullptr, 0);
if (result == 0) {
// 转换失败,获取错误码
DWORD error = GetLastError();
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
return;
}
// 如果只是查询所需缓冲区大小
if (lpWideCharStr == 0 || cchWideChar == 0) {
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
return;
}
// 检查目标缓冲区大小是否足够
if (cchWideChar < result) {
DWORD error = ERROR_INSUFFICIENT_BUFFER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
result = 0;
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
return;
}
// 执行实际转换
std::vector<wchar_t> wideBuffer(result);
if (MultiByteToWideChar(CodePage, dwFlags, srcBuffer.data(), cbMultiByte,
wideBuffer.data(), result) > 0) {
// 写入转换后的字符串到目标内存
if (uc_mem_write(uc, lpWideCharStr, wideBuffer.data(),
result * sizeof(wchar_t)) != UC_ERR_OK) {
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
result = 0;
}
} else {
// 转换失败
DWORD error = GetLastError();
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
result = 0;
}
printf(
"[*] MultiByteToWideChar: CodePage=%u, Flags=0x%x, Input=%p, "
"InputLen=%d, Output=%p, OutputLen=%d, Result=%d\n",
CodePage, dwFlags, (void*)lpMultiByteStr, cbMultiByte,
(void*)lpWideCharStr, cchWideChar, result);
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
}
auto Sandbox::CreateHeapSegment(uint64_t base, size_t size) -> HeapSegment* { auto Sandbox::CreateHeapSegment(uint64_t base, size_t size) -> HeapSegment* {
auto segment = new HeapSegment(); auto segment = new HeapSegment();
segment->base = base; segment->base = base;
@@ -1279,6 +1514,383 @@ auto Sandbox::InitCommandLine(std::string commandLine) -> void {
(wCommandLine.length() + 1) * sizeof(wchar_t)); (wCommandLine.length() + 1) * sizeof(wchar_t));
} }
auto Api_GetModuleFileNameW(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t hModule = 0;
uint64_t lpFilename = 0;
uint32_t nSize = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = hModule, rdx = lpFilename, r8 = nSize
uc_reg_read(uc, UC_X86_REG_RCX, &hModule);
uc_reg_read(uc, UC_X86_REG_RDX, &lpFilename);
uint64_t temp_size;
uc_reg_read(uc, UC_X86_REG_R8, &temp_size);
nSize = static_cast<uint32_t>(temp_size);
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uint32_t temp_module = 0;
uint32_t temp_filename = 0;
uc_mem_read(uc, esp_address, &temp_module, sizeof(uint32_t));
uc_mem_read(uc, esp_address + 0x4, &temp_filename, sizeof(uint32_t));
uc_mem_read(uc, esp_address + 0x8, &nSize, sizeof(uint32_t));
hModule = temp_module;
lpFilename = temp_filename;
}
uint32_t result = 0;
// 验证参数
if (lpFilename == 0 || nSize == 0) {
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
return;
}
std::wstring modulePath;
if (hModule == 0) {
// 如果hModule为NULL,返回主模块(PE文件)的路径
modulePath = std::wstring(context->GetPeInfo()->inputFilePath.begin(),
context->GetPeInfo()->inputFilePath.end());
} else {
// 在模块列表中查找对应模块
bool found = false;
for (const auto& module : context->GetModuleList()) {
if (module->base == hModule) {
// 构建完整的模块路径
char windowsPath[MAX_PATH];
GetWindowsDirectoryA(windowsPath, sizeof(windowsPath));
// 根据PE架构选择正确的系统目录
const std::string systemDir = context->GetPeInfo()->isX64
? "\\System32\\"
: "\\SysWOW64\\";
std::string fullPath =
std::string(windowsPath) + systemDir + module->name;
modulePath = std::wstring(fullPath.begin(), fullPath.end());
found = true;
break;
}
}
if (!found) {
DWORD error = ERROR_MOD_NOT_FOUND;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
uc_reg_write(
uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
return;
}
}
// 检查缓冲区大小是否足够
if (nSize < modulePath.length() + 1) {
// 缓冲区太小,返回所需大小
result = static_cast<uint32_t>(modulePath.length() + 1);
DWORD error = ERROR_INSUFFICIENT_BUFFER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
} else {
// 写入路径到缓冲区
if (uc_mem_write(uc, lpFilename, modulePath.c_str(),
(modulePath.length() + 1) * sizeof(wchar_t)) ==
UC_ERR_OK) {
result = static_cast<uint32_t>(modulePath.length());
} else {
result = 0;
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
}
}
printf(
"[*] GetModuleFileNameW: Module=0x%llx, Buffer=0x%llx, Size=%u, "
"Result=%u, Path=%ls\n",
hModule, lpFilename, nSize, result, modulePath.c_str());
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
}
// 实现 AreFileApisANSI API
auto Api_AreFileApisANSI(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
// 默认返回TRUE表示使用ANSI字符集
BOOL isAnsi = TRUE;
printf("[*] AreFileApisANSI: IsAnsi=%d\n", isAnsi);
// 返回结果
uc_reg_write(uc,
static_cast<Sandbox*>(sandbox)->GetPeInfo()->isX64
? UC_X86_REG_RAX
: UC_X86_REG_EAX,
&isAnsi);
}
auto Api_WideCharToMultiByte(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint32_t CodePage = 0;
uint32_t dwFlags = 0;
uint64_t lpWideCharStr = 0;
int32_t cchWideChar = 0;
uint64_t lpMultiByteStr = 0;
int32_t cbMultiByte = 0;
uint64_t lpDefaultChar = 0;
uint64_t lpUsedDefaultChar = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx, rdx, r8, r9, [rsp+0x28], [rsp+0x30], [rsp+0x38], [rsp+0x40]
uint64_t temp_codepage = 0;
uint64_t temp_flags = 0;
uint64_t temp_widechar = 0;
uint64_t temp_cchwidechar = 0;
uc_reg_read(uc, UC_X86_REG_RCX, &temp_codepage);
uc_reg_read(uc, UC_X86_REG_RDX, &temp_flags);
uc_reg_read(uc, UC_X86_REG_R8, &temp_widechar);
uc_reg_read(uc, UC_X86_REG_R9, &temp_cchwidechar);
CodePage = static_cast<uint32_t>(temp_codepage);
dwFlags = static_cast<uint32_t>(temp_flags);
lpWideCharStr = temp_widechar;
cchWideChar = static_cast<int32_t>(temp_cchwidechar);
// 获取栈上的参数
uint64_t rsp = 0;
uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
uint64_t shadow_space = 0x20;
uc_mem_read(uc, rsp + shadow_space + 0x8, &lpMultiByteStr,
sizeof(uint64_t));
uc_mem_read(uc, rsp + shadow_space + 0x10, &cbMultiByte,
sizeof(int32_t));
uc_mem_read(uc, rsp + shadow_space + 0x18, &lpDefaultChar,
sizeof(uint64_t));
uc_mem_read(uc, rsp + shadow_space + 0x20, &lpUsedDefaultChar,
sizeof(uint64_t));
} 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, &CodePage, sizeof(uint32_t));
uc_mem_read(uc, esp_address + 0x4, &dwFlags, sizeof(uint32_t));
uc_mem_read(uc, esp_address + 0x8, &lpWideCharStr, sizeof(uint32_t));
uc_mem_read(uc, esp_address + 0xC, &cchWideChar, sizeof(int32_t));
uc_mem_read(uc, esp_address + 0x10, &lpMultiByteStr, sizeof(uint32_t));
uc_mem_read(uc, esp_address + 0x14, &cbMultiByte, sizeof(int32_t));
uc_mem_read(uc, esp_address + 0x18, &lpDefaultChar, sizeof(uint32_t));
uc_mem_read(uc, esp_address + 0x1C, &lpUsedDefaultChar,
sizeof(uint32_t));
}
// 基本参数验证
if (lpWideCharStr == 0 || cchWideChar == 0) {
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
int result = 0;
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
return;
}
// 读取源宽字符串
std::vector<wchar_t> srcBuffer;
size_t actualWideLength = 0;
if (cchWideChar == -1) {
// 如果长度为-1,则源字符串以null结尾
wchar_t ch = 0;
do {
if (uc_mem_read(uc, lpWideCharStr + (actualWideLength * 2), &ch,
2) != UC_ERR_OK) {
break;
}
srcBuffer.push_back(ch);
actualWideLength++;
} while (ch != 0 && actualWideLength < MAX_PATH);
if (actualWideLength >= MAX_PATH) {
DWORD error = ERROR_INSUFFICIENT_BUFFER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
int result = 0;
uc_reg_write(
uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
return;
}
} else {
// 使用指定长度
if (cchWideChar > 0 && cchWideChar <= MAX_PATH) {
srcBuffer.resize(cchWideChar);
if (uc_mem_read(uc, lpWideCharStr, srcBuffer.data(),
cchWideChar * 2) != UC_ERR_OK) {
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
int result = 0;
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX
: UC_X86_REG_EAX,
&result);
return;
}
actualWideLength = cchWideChar;
} else {
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
int result = 0;
uc_reg_write(
uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
return;
}
}
// 读取默认字符和使用默认字符标志
char defaultChar = '?';
BOOL usedDefaultChar = FALSE;
if (lpDefaultChar != 0) {
uc_mem_read(uc, lpDefaultChar, &defaultChar, 1);
}
// 计算所需的多字节缓冲区大小
int requiredSize = WideCharToMultiByte(
CodePage, dwFlags, srcBuffer.data(), static_cast<int>(actualWideLength),
nullptr, 0, lpDefaultChar ? &defaultChar : nullptr,
lpUsedDefaultChar ? &usedDefaultChar : nullptr);
if (requiredSize == 0) {
// 获取并设置错误码
DWORD error = GetLastError();
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
int result = 0;
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
return;
}
// 如果只是查询所需缓冲区大小
if (lpMultiByteStr == 0 || cbMultiByte == 0) {
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&requiredSize);
return;
}
// 检查目标缓冲区大小是否足够
if (cbMultiByte < requiredSize) {
DWORD error = ERROR_INSUFFICIENT_BUFFER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
int result = 0;
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
return;
}
// 执行实际转换
std::vector<char> multiByteBuffer(requiredSize);
int result = WideCharToMultiByte(
CodePage, dwFlags, srcBuffer.data(), static_cast<int>(actualWideLength),
multiByteBuffer.data(), requiredSize,
lpDefaultChar ? &defaultChar : nullptr,
lpUsedDefaultChar ? &usedDefaultChar : nullptr);
if (result > 0) {
// 写入转换后的字符串到目标内存
if (uc_mem_write(uc, lpMultiByteStr, multiByteBuffer.data(), result) !=
UC_ERR_OK) {
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
result = 0;
}
// 如果需要,写回使用默认字符标志
if (lpUsedDefaultChar != 0) {
uc_mem_write(uc, lpUsedDefaultChar, &usedDefaultChar, sizeof(BOOL));
}
} else {
// 获取并设置错误码
DWORD error = GetLastError();
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
}
printf(
"[*] WideCharToMultiByte: CodePage=%u, Flags=0x%x, WideStr=%p, "
"WideLen=%d, MultiStr=%p, MultiLen=%d, Result=%d\n",
CodePage, dwFlags, (void*)lpWideCharStr, cchWideChar,
(void*)lpMultiByteStr, cbMultiByte, result);
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
}
auto Sandbox::InitApiHooks() -> void { auto Sandbox::InitApiHooks() -> void {
auto FakeApi_GetSystemTimeAsFileTime = auto FakeApi_GetSystemTimeAsFileTime =
_fakeApi{.func = Api_GetSystemTimeAsFileTime, .paramCount = 1}; _fakeApi{.func = Api_GetSystemTimeAsFileTime, .paramCount = 1};
@@ -1329,6 +1941,14 @@ auto Sandbox::InitApiHooks() -> void {
_fakeApi{.func = Api_GetCommandLineW, .paramCount = 0}; _fakeApi{.func = Api_GetCommandLineW, .paramCount = 0};
auto FakeApi_GetACP = _fakeApi{.func = Api_GetACP, .paramCount = 0}; auto FakeApi_GetACP = _fakeApi{.func = Api_GetACP, .paramCount = 0};
auto FakeApi_GetCPInfo = _fakeApi{.func = Api_GetCPInfo, .paramCount = 2}; auto FakeApi_GetCPInfo = _fakeApi{.func = Api_GetCPInfo, .paramCount = 2};
auto FakeApi_MultiByteToWideChar =
_fakeApi{.func = Api_MultiByteToWideChar, .paramCount = 6};
auto FakeApi_GetModuleFileNameW =
_fakeApi{.func = Api_GetModuleFileNameW, .paramCount = 3};
auto FakeApi_AreFileApisANSI =
_fakeApi{.func = Api_AreFileApisANSI, .paramCount = 0};
auto FakeApi_WideCharToMultiByte =
_fakeApi{.func = Api_WideCharToMultiByte, .paramCount = 8};
api_map = { api_map = {
{"GetSystemTimeAsFileTime", {"GetSystemTimeAsFileTime",
@@ -1370,13 +1990,21 @@ auto Sandbox::InitApiHooks() -> void {
{"GetCommandLineW", {"GetCommandLineW",
std::make_shared<_fakeApi>(FakeApi_GetCommandLineW)}, std::make_shared<_fakeApi>(FakeApi_GetCommandLineW)},
{"GetACP", std::make_shared<_fakeApi>(FakeApi_GetACP)}, {"GetACP", std::make_shared<_fakeApi>(FakeApi_GetACP)},
{"GetCPInfo", std::make_shared<_fakeApi>(FakeApi_GetCPInfo)}}; {"GetCPInfo", std::make_shared<_fakeApi>(FakeApi_GetCPInfo)},
{"MultiByteToWideChar",
std::make_shared<_fakeApi>(FakeApi_MultiByteToWideChar)},
{"GetModuleFileNameW",
std::make_shared<_fakeApi>(FakeApi_GetModuleFileNameW)},
{"AreFileApisANSI",
std::make_shared<_fakeApi>(FakeApi_AreFileApisANSI)},
{"WideCharToMultiByte",
std::make_shared<_fakeApi>(FakeApi_WideCharToMultiByte)},
};
} }
auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip, auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip,
std::string ApiName) -> void { std::string ApiName) -> void {
auto it = api_map.find(ApiName); auto it = api_map.find(ApiName);
if (it != api_map.end()) { if (it != api_map.end()) {
// 调用API函数
it->second->func(this, uc, address); it->second->func(this, uc, address);
// 获取参数数量 // 获取参数数量

View File

@@ -1,5 +1,5 @@
#include "sandbox_callbacks.h" #include "sandbox_callbacks.h"
#define LOG_LEVEL 0 #define LOG_LEVEL 1
namespace sandboxCallbacks { namespace sandboxCallbacks {
void handleCodeRun(uc_engine* uc, uint64_t address, uint32_t size, void handleCodeRun(uc_engine* uc, uint64_t address, uint32_t size,
void* userData) { void* userData) {
@@ -46,6 +46,8 @@ void handleCodeRun(uc_engine* uc, uint64_t address, uint32_t size,
instruction[0].mnemonic, instruction[0].op_str); instruction[0].mnemonic, instruction[0].op_str);
} }
cs_free(instruction, instructionCount); cs_free(instruction, instructionCount);
dumpVmenv(uc, userData);
} }
} }
@@ -54,7 +56,10 @@ void handleMemoryRead(uc_engine* uc, uc_mem_type type, uint64_t address,
auto* sandbox = static_cast<Sandbox*>(userData); auto* sandbox = static_cast<Sandbox*>(userData);
if (!sandbox) return; if (!sandbox) return;
uint64_t regRax, regRip; uint64_t regRax, regRip, regRbp;
uc_reg_read(uc,
sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RBP : UC_X86_REG_EBP,
&regRbp);
uc_reg_read(uc, uc_reg_read(uc,
sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&regRax); &regRax);
@@ -68,8 +73,9 @@ void handleMemoryRead(uc_engine* uc, uc_mem_type type, uint64_t address,
if (LOG_LEVEL > 0) { if (LOG_LEVEL > 0) {
printf( printf(
"[handleMemoryRead] Address: %p Size: %p Rax: %p Rip: %p Error: %d " "[handleMemoryRead] Address: %p Size: %p Rax: %p Rip: %p Error: %d "
"ReadData: %p\n", "ReadData: %p Rbp: %p\n",
address, size, regRax, regRip, readError, readAddress); address, size, regRax, regRip, readError, readAddress, regRbp);
sandboxCallbacks::dumpVmenv(uc, sandbox);
} }
} }
void dumpVmenv(uc_engine* uc, void* userData) { void dumpVmenv(uc_engine* uc, void* userData) {
@@ -81,6 +87,8 @@ void dumpVmenv(uc_engine* uc, void* userData) {
uint64_t Rbp = 0; uint64_t Rbp = 0;
uint64_t Rcx = 0; uint64_t Rcx = 0;
uint64_t Rdx = 0; uint64_t Rdx = 0;
uint64_t Eax = 0;
uint64_t Ecx = 0;
uc_reg_read(uc, uc_reg_read(uc,
sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RIP : UC_X86_REG_EIP, sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RIP : UC_X86_REG_EIP,
&Rip); &Rip);
@@ -99,8 +107,94 @@ void dumpVmenv(uc_engine* uc, void* userData) {
uc_reg_read(uc, uc_reg_read(uc,
sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RDX : UC_X86_REG_EDX, sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RDX : UC_X86_REG_EDX,
&Rdx); &Rdx);
printf("[dumpVmenv] Rip: %p Rax: %p Rsp: %p Rbp: %p Rcx: %p Rdx: %p\n", Rip, uc_reg_read(uc,
Rax, Rsp, Rbp, Rcx, Rdx); sandbox->GetPeInfo()->isX64 ? UC_X86_REG_EAX : UC_X86_REG_EAX,
&Eax);
uc_reg_read(uc,
sandbox->GetPeInfo()->isX64 ? UC_X86_REG_ECX : UC_X86_REG_ECX,
&Ecx);
printf(
"[dumpVmenv] Rip: %p Rax: %p Rsp: %p Rbp: %p Rcx: %p Rdx: %p Eax: "
"%08x Ecx: %08x\n",
Rip, Rax, Rsp, Rbp, Rcx, Rdx, Eax, Ecx);
// 打印16层栈内存
printf("\n[Stack Memory Dump (16 levels)]\n");
const int STACK_LEVELS = 16;
const int POINTER_SIZE = sandbox->GetPeInfo()->isX64 ? 8 : 4;
for (int i = 0; i < STACK_LEVELS; i++) {
uint64_t currentAddress = Rsp + (i * POINTER_SIZE);
uint64_t memValue = 0;
if (uc_mem_read(uc, currentAddress, &memValue, POINTER_SIZE) ==
UC_ERR_OK) {
printf("RSP+%02X [%p]: ", i * POINTER_SIZE, currentAddress);
// 按4字节分组显示十六进制
for (int j = 0; j < POINTER_SIZE; j += 4) {
uint32_t chunk;
size_t chunkSize = min(4, POINTER_SIZE - j);
if (uc_mem_read(uc, currentAddress + j, &chunk, chunkSize) ==
UC_ERR_OK) {
printf("%08X ", chunk);
} else {
printf("???????? ");
}
}
// 显示ASCII字符
printf("| ");
for (int j = 0; j < POINTER_SIZE; j++) {
uint8_t byte;
if (uc_mem_read(uc, currentAddress + j, &byte, 1) ==
UC_ERR_OK) {
printf("%c", (byte >= 32 && byte <= 126) ? byte : '.');
} else {
printf("?");
}
}
printf("\n");
} else {
printf("RSP+%02X [%p]: Unable to read memory\n", i * POINTER_SIZE,
currentAddress);
}
}
printf("\n[Frame Pointer Stack (16 levels)]\n");
uint64_t currentBp = Rbp;
for (int i = 0; i < STACK_LEVELS && currentBp != 0; i++) {
uint64_t nextBp = 0;
if (uc_mem_read(uc, currentBp, &nextBp, POINTER_SIZE) == UC_ERR_OK) {
printf("Frame %02d [%p]: ", i, currentBp);
// 按4字节分组显示十六进制
for (int j = 0; j < POINTER_SIZE; j += 4) {
uint32_t chunk;
size_t chunkSize = min(4, POINTER_SIZE - j);
if (uc_mem_read(uc, currentBp + j, &chunk, chunkSize) ==
UC_ERR_OK) {
printf("%08X ", chunk);
} else {
printf("???????? ");
}
}
// 显示ASCII字符
printf("| ");
for (int j = 0; j < POINTER_SIZE; j++) {
uint8_t byte;
if (uc_mem_read(uc, currentBp + j, &byte, 1) == UC_ERR_OK) {
printf("%c", (byte >= 32 && byte <= 126) ? byte : '.');
} else {
printf("?");
}
}
printf("\n");
currentBp = nextBp;
} else {
printf("Frame %02d [%p]: Unable to read memory\n", i, currentBp);
break;
}
}
} }
void handleMemoryUnmapRead(uc_engine* uc, uc_mem_type type, uint64_t address, void handleMemoryUnmapRead(uc_engine* uc, uc_mem_type type, uint64_t address,
int size, int64_t value, void* userData) { int size, int64_t value, void* userData) {

View File

@@ -2,15 +2,14 @@
#include "sandbox.h" #include "sandbox.h"
namespace sandboxCallbacks { namespace sandboxCallbacks {
void handleCodeRun(uc_engine* uc, uint64_t address, uint32_t size, void handleCodeRun(uc_engine* uc, uint64_t address, uint32_t size,
void* userData); void* userData);
void handleMemoryRead(uc_engine* uc, uc_mem_type type, uint64_t address, void handleMemoryRead(uc_engine* uc, uc_mem_type type, uint64_t address,
int size, int64_t value, void* userData); int size, int64_t value, void* userData);
void handleMemoryUnmapRead(uc_engine* uc, uc_mem_type type, void handleMemoryUnmapRead(uc_engine* uc, uc_mem_type type, uint64_t address,
uint64_t address, int size, int64_t value, int size, int64_t value, void* userData);
void* userData);
void handleMemoryWrite(uc_engine* uc, uc_mem_type type, uint64_t address, void handleMemoryWrite(uc_engine* uc, uc_mem_type type, uint64_t address,
int size, int64_t value, void* userData); int size, int64_t value, void* userData);
void handleSyscall(uc_engine* uc, void* userData); void handleSyscall(uc_engine* uc, void* userData);
auto InitApiHooks() -> void; auto InitApiHooks() -> void;
void dumpVmenv(uc_engine* uc, void* userData);
}; // namespace sandboxCallbacks }; // namespace sandboxCallbacks