初步增加32位支持(没加全)

This commit is contained in:
huoji
2025-03-19 20:47:26 +08:00
parent 9b970ce8a2
commit 232a7abcba
9 changed files with 819 additions and 137 deletions

View File

@@ -2,6 +2,7 @@
#include "sandbox_callbacks.h"
#include "sandbox_api_winhttp.h"
#include <tlhelp32.h>
auto Api_QueryPerformanceCounter(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
@@ -602,7 +603,16 @@ auto Api_VirtualProtect(void* sandbox, uc_engine* uc, uint64_t address)
// 检查地址范围是否已映射
uint32_t unicornProtect = WindowsToUnicornProtect(flNewProtect);
uc_err err = uc_mem_protect(uc, lpAddress, dwSize, unicornProtect);
// 对齐地址和大小到页面边界
uint64_t aligned_address =
lpAddress & ~(PAGE_SIZE - 1); // 向下对齐到页面边界
uint64_t end_address = (lpAddress + dwSize + PAGE_SIZE - 1) &
~(PAGE_SIZE - 1); // 向上对齐到页面边界
uint64_t aligned_size = end_address - aligned_address;
uc_err err =
uc_mem_protect(uc, aligned_address, aligned_size, unicornProtect);
if (err != UC_ERR_OK) {
uint64_t result = 0; // FALSE
uc_reg_write(
@@ -909,6 +919,285 @@ auto Api_CreateDirectoryW(void* sandbox, uc_engine* uc, uint64_t address)
}
}
}
auto Api_GetStringTypeW(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint32_t dwInfoType = 0;
uint64_t lpSrcStr = 0;
int32_t cchSrc = 0;
uint64_t lpCharType = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = dwInfoType, rdx = lpSrcStr, r8 = cchSrc, r9 = lpCharType
uc_reg_read(uc, UC_X86_REG_RCX, &dwInfoType);
uc_reg_read(uc, UC_X86_REG_RDX, &lpSrcStr);
uint64_t temp_size;
uc_reg_read(uc, UC_X86_REG_R8, &temp_size);
cchSrc = static_cast<int32_t>(temp_size);
uc_reg_read(uc, UC_X86_REG_R9, &lpCharType);
} 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, &dwInfoType, sizeof(uint32_t));
esp_address += 0x4;
uint32_t temp_src_str;
uc_mem_read(uc, esp_address, &temp_src_str, sizeof(uint32_t));
lpSrcStr = temp_src_str;
esp_address += 0x4;
uc_mem_read(uc, esp_address, &cchSrc, sizeof(int32_t));
esp_address += 0x4;
uint32_t temp_char_type;
uc_mem_read(uc, esp_address, &temp_char_type, sizeof(uint32_t));
lpCharType = temp_char_type;
}
// 验证参数
if (lpSrcStr == 0 || lpCharType == 0) {
uint64_t result = 0; // FALSE
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
return;
}
// 如果cchSrc为负数计算字符串长度
if (cchSrc < 0) {
cchSrc = 0;
wchar_t temp_char;
do {
uc_mem_read(uc, lpSrcStr + (cchSrc * 2), &temp_char,
sizeof(wchar_t));
cchSrc++;
} while (temp_char != 0 && cchSrc < 1024); // 设置一个合理的上限
cchSrc--; // 不包括null终止符
}
// 读取源字符串
std::vector<wchar_t> srcStr(cchSrc);
uc_mem_read(uc, lpSrcStr, srcStr.data(), cchSrc * sizeof(wchar_t));
// 处理每个字符
std::vector<WORD> charTypes(cchSrc);
for (int i = 0; i < cchSrc; i++) {
WORD type = 0;
wchar_t ch = srcStr[i];
switch (dwInfoType) {
case CT_CTYPE1: {
// 基本字符类型检查
if (iswupper(ch)) type |= C1_UPPER;
if (iswlower(ch)) type |= C1_LOWER;
if (iswdigit(ch)) type |= C1_DIGIT;
if (iswspace(ch)) type |= C1_SPACE;
if (iswpunct(ch)) type |= C1_PUNCT;
if (iswcntrl(ch)) type |= C1_CNTRL;
if (ch == L' ' || ch == L'\t') type |= C1_BLANK;
if ((ch >= L'0' && ch <= L'9') || (ch >= L'A' && ch <= L'F') ||
(ch >= L'a' && ch <= L'f'))
type |= C1_XDIGIT;
if (iswalpha(ch)) type |= C1_ALPHA;
if (type == 0) type |= C1_DEFINED;
break;
}
case CT_CTYPE2: {
// 简单的双向文本支持
if ((ch >= L'A' && ch <= L'Z') || (ch >= L'a' && ch <= L'z') ||
(ch >= L'0' && ch <= L'9')) {
type = C2_LEFTTORIGHT;
} else if (iswspace(ch)) {
type = C2_WHITESPACE;
} else {
type = C2_NOTAPPLICABLE;
}
break;
}
case CT_CTYPE3: {
// 基本文本处理信息
if (iswalpha(ch)) type |= C3_ALPHA;
// 这里可以添加更多的C3类型检查
break;
}
}
charTypes[i] = type;
}
// 写入结果
uc_mem_write(uc, lpCharType, charTypes.data(), cchSrc * sizeof(WORD));
printf("[*] GetStringTypeW: InfoType=0x%x, StrLen=%d\n", dwInfoType,
cchSrc);
// 返回成功
uint64_t result = 1; // TRUE
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
}
auto Api_LCMapStringW(void* sandbox, uc_engine* uc, uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint32_t Locale = 0;
uint32_t dwMapFlags = 0;
uint64_t lpSrcStr = 0;
int32_t cchSrc = 0;
uint64_t lpDestStr = 0;
int32_t cchDest = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = Locale, rdx = dwMapFlags, r8 = lpSrcStr, r9 = cchSrc
uc_reg_read(uc, UC_X86_REG_RCX, &Locale);
uc_reg_read(uc, UC_X86_REG_RDX, &dwMapFlags);
uc_reg_read(uc, UC_X86_REG_R8, &lpSrcStr);
uint64_t temp_src_size;
uc_reg_read(uc, UC_X86_REG_R9, &temp_src_size);
cchSrc = static_cast<int32_t>(temp_src_size);
// 从栈上读取剩余参数
uint64_t rsp;
uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
uc_mem_read(uc, rsp + 0x28, &lpDestStr, sizeof(uint64_t));
uc_mem_read(uc, rsp + 0x30, &cchDest, 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, &Locale, sizeof(uint32_t));
esp_address += 0x4;
uc_mem_read(uc, esp_address, &dwMapFlags, sizeof(uint32_t));
esp_address += 0x4;
uint32_t temp_src_str;
uc_mem_read(uc, esp_address, &temp_src_str, sizeof(uint32_t));
lpSrcStr = temp_src_str;
esp_address += 0x4;
uc_mem_read(uc, esp_address, &cchSrc, sizeof(int32_t));
esp_address += 0x4;
uint32_t temp_dest_str;
uc_mem_read(uc, esp_address, &temp_dest_str, sizeof(uint32_t));
lpDestStr = temp_dest_str;
esp_address += 0x4;
uc_mem_read(uc, esp_address, &cchDest, sizeof(int32_t));
}
// 验证参数
if (lpSrcStr == 0) {
uint32_t result = 0;
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
return;
}
// 如果cchSrc为负数计算源字符串长度
if (cchSrc < 0) {
cchSrc = 0;
wchar_t temp_char;
do {
uc_mem_read(uc, lpSrcStr + (cchSrc * 2), &temp_char,
sizeof(wchar_t));
cchSrc++;
} while (temp_char != 0 && cchSrc < 1024); // 设置一个合理的上限
cchSrc--; // 不包括null终止符
}
// 读取源字符串
std::vector<wchar_t> srcStr(cchSrc);
uc_mem_read(uc, lpSrcStr, srcStr.data(), cchSrc * sizeof(wchar_t));
// 如果cchDest为0返回所需缓冲区大小
if (cchDest == 0) {
uint32_t required_size = cchSrc;
if (dwMapFlags & LCMAP_SORTKEY) {
required_size = cchSrc * 2 + 1; // 排序键通常需要更多空间
}
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&required_size);
return;
}
// 检查目标缓冲区大小是否足够
if (cchDest < cchSrc) {
uint32_t result = 0;
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
DWORD error = ERROR_INSUFFICIENT_BUFFER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
return;
}
// 处理字符串映射
std::vector<wchar_t> destStr(cchSrc);
for (int i = 0; i < cchSrc; i++) {
wchar_t ch = srcStr[i];
if (dwMapFlags & LCMAP_UPPERCASE) {
destStr[i] = towupper(ch);
} else if (dwMapFlags & LCMAP_LOWERCASE) {
destStr[i] = towlower(ch);
} else {
destStr[i] = ch; // 默认保持不变
}
}
// 写入结果
if (dwMapFlags & LCMAP_SORTKEY) {
// 生成简单的排序键(这里只是一个基本实现)
std::vector<BYTE> sortKey(cchSrc * 2 + 1);
for (int i = 0; i < cchSrc; i++) {
sortKey[i * 2] = static_cast<BYTE>(destStr[i] & 0xFF);
sortKey[i * 2 + 1] = static_cast<BYTE>((destStr[i] >> 8) & 0xFF);
}
sortKey[cchSrc * 2] = 0; // 终止符
uc_mem_write(uc, lpDestStr, sortKey.data(), sortKey.size());
uint32_t result = static_cast<uint32_t>(sortKey.size());
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
} else {
// 写入映射后的字符串
uc_mem_write(uc, lpDestStr, destStr.data(), cchSrc * sizeof(wchar_t));
uint32_t result = cchSrc;
uc_reg_write(
uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
}
printf(
"[*] LCMapStringW: Locale=0x%x, MapFlags=0x%x, SrcLen=%d, DestLen=%d\n",
Locale, dwMapFlags, cchSrc, cchDest);
}
auto Sandbox::InitApiHooks() -> void {
auto FakeApi_GetSystemTimeAsFileTime =
_fakeApi{.func = Api_GetSystemTimeAsFileTime, .paramCount = 1};
@@ -1062,6 +1351,15 @@ auto Sandbox::InitApiHooks() -> void {
_fakeApi{.func = Api_CreateDirectoryW, .paramCount = 2};
auto FakeApi_URLDownloadToFileW =
_fakeApi{.func = Api_URLDownloadToFileW, .paramCount = 5};
auto FakeApi_TlsFree = _fakeApi{.func = Api_TlsFree, .paramCount = 1};
auto FakeApi_FlsAlloc = _fakeApi{.func = Api_FlsAlloc, .paramCount = 1};
auto FakeApi_FlsGetValue =
_fakeApi{.func = Api_FlsGetValue, .paramCount = 1};
auto FakeApi_GetStringTypeW =
_fakeApi{.func = Api_GetStringTypeW, .paramCount = 4};
auto FakeApi_LCMapStringW =
_fakeApi{.func = Api_LCMapStringW, .paramCount = 6};
api_map = {
{"GetSystemTimeAsFileTime",
std::make_shared<_fakeApi>(FakeApi_GetSystemTimeAsFileTime)},
@@ -1187,14 +1485,15 @@ auto Sandbox::InitApiHooks() -> void {
std::make_shared<_fakeApi>(FakeApi_LookupPrivilegeValueA)},
{"AdjustTokenPrivileges",
std::make_shared<_fakeApi>(FakeApi_AdjustTokenPrivileges)},
{"LookupPrivilegeValueA",
std::make_shared<_fakeApi>(FakeApi_LookupPrivilegeValueA)},
{"AdjustTokenPrivileges",
std::make_shared<_fakeApi>(FakeApi_AdjustTokenPrivileges)},
{"CreateDirectoryW",
std::make_shared<_fakeApi>(FakeApi_CreateDirectoryW)},
{"URLDownloadToFileW",
std::make_shared<_fakeApi>(FakeApi_URLDownloadToFileW)},
{"TlsFree", std::make_shared<_fakeApi>(FakeApi_TlsFree)},
{"FlsAlloc", std::make_shared<_fakeApi>(FakeApi_FlsAlloc)},
{"FlsGetValue", std::make_shared<_fakeApi>(FakeApi_FlsGetValue)},
{"GetStringTypeW", std::make_shared<_fakeApi>(FakeApi_GetStringTypeW)},
{"LCMapStringW", std::make_shared<_fakeApi>(FakeApi_LCMapStringW)},
};
}
auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip,
@@ -1202,8 +1501,8 @@ auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip,
auto it = api_map.find(ApiName);
if (it != api_map.end()) {
it->second->func(this, uc, address);
this->ApiCallList.push_back(ApiName);
this->ApiCallList.push_back(ApiName);
// 获取参数数量
int paramCount = it->second->paramCount;
uint32_t esp;
@@ -1236,7 +1535,8 @@ auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip,
// x86下所有参数都通过栈传递
// 调整栈指针每个参数4字节 + 返回地址4字节
esp += (paramCount * 4) + 4;
// 设置EIP为返回地址
// esp += 4;
// 设置EIP为返回地址
uc_reg_write(uc, UC_X86_REG_EIP, &return_address_32);
}
if (this->GetPeInfo()->isX64) {