fix up
This commit is contained in:
@@ -858,350 +858,6 @@ auto Api_AdjustTokenPrivileges(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
context->GetTeb32()->LastErrorValue = error;
|
||||
}
|
||||
}
|
||||
auto Api_CreateDirectoryW(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void {
|
||||
auto context = static_cast<Sandbox*>(sandbox);
|
||||
uint64_t lpPathName = 0;
|
||||
uint64_t lpSecurityAttributes = 0;
|
||||
|
||||
// 获取参数
|
||||
if (context->GetPeInfo()->isX64) {
|
||||
// x64: rcx = lpPathName, rdx = lpSecurityAttributes
|
||||
uc_reg_read(uc, UC_X86_REG_RCX, &lpPathName);
|
||||
uc_reg_read(uc, UC_X86_REG_RDX, &lpSecurityAttributes);
|
||||
} else {
|
||||
// x86: 从栈上读取参数
|
||||
uint32_t esp_address = 0;
|
||||
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
|
||||
esp_address += 0x4; // 跳过返回地址
|
||||
|
||||
uint32_t temp_path_name, temp_security_attr;
|
||||
uc_mem_read(uc, esp_address, &temp_path_name, sizeof(uint32_t));
|
||||
uc_mem_read(uc, esp_address + 0x4, &temp_security_attr,
|
||||
sizeof(uint32_t));
|
||||
|
||||
lpPathName = temp_path_name;
|
||||
lpSecurityAttributes = temp_security_attr;
|
||||
}
|
||||
|
||||
// 读取目录路径
|
||||
wchar_t pathBuffer[MAX_PATH] = {0};
|
||||
if (lpPathName != 0) {
|
||||
size_t i = 0;
|
||||
do {
|
||||
uint16_t wchar;
|
||||
uc_mem_read(uc, lpPathName + (i * 2), &wchar, 2);
|
||||
pathBuffer[i] = wchar;
|
||||
i++;
|
||||
} while (pathBuffer[i - 1] != 0 && i < MAX_PATH);
|
||||
}
|
||||
|
||||
// 将宽字符转换为常规字符串用于日志输出
|
||||
std::wstring widePath(pathBuffer);
|
||||
std::string path(widePath.begin(), widePath.end());
|
||||
|
||||
// 在实际的实现中,可能需要检查目录是否已存在
|
||||
// 这里简单地返回成功,不实际创建目录
|
||||
bool success = true;
|
||||
|
||||
// 输出日志
|
||||
printf("[*] CreateDirectoryW: Path=%s, Result=%s\n", path.c_str(),
|
||||
success ? "TRUE" : "FALSE");
|
||||
|
||||
// 设置返回值
|
||||
uint64_t result = success ? 1 : 0;
|
||||
uc_reg_write(uc,
|
||||
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||||
&result);
|
||||
|
||||
// 如果失败,可以设置LastError
|
||||
if (!success) {
|
||||
DWORD error = ERROR_PATH_NOT_FOUND; // 或其他适当的错误代码
|
||||
if (context->GetPeInfo()->isX64) {
|
||||
context->GetTeb64()->LastErrorValue = error;
|
||||
} else {
|
||||
context->GetTeb32()->LastErrorValue = error;
|
||||
}
|
||||
}
|
||||
}
|
||||
auto Api_GetStringTypeW(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void {
|
||||
auto context = static_cast<Sandbox*>(sandbox);
|
||||
uint64_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 =
|
||||
@@ -1320,7 +976,6 @@ auto Sandbox::InitApiHooks() -> void {
|
||||
_fakeApi{.func = Api_CreateProcessA, .paramCount = 10};
|
||||
auto FakeApi_CreateProcessW =
|
||||
_fakeApi{.func = Api_CreateProcessW, .paramCount = 10};
|
||||
auto FakeApi_ReadFile = _fakeApi{.func = Api_ReadFile, .paramCount = 5};
|
||||
auto FakeApi_WlanOpenHandle =
|
||||
_fakeApi{.func = Api_WlanOpenHandle, .paramCount = 4};
|
||||
auto FakeApi_WlanEnumInterfaces =
|
||||
@@ -1380,6 +1035,15 @@ auto Sandbox::InitApiHooks() -> void {
|
||||
_fakeApi{.func = Api_SysAllocString, .paramCount = 1};
|
||||
auto FakeApi_LoadLibraryW =
|
||||
_fakeApi{ .func = Api_LoadLibraryW, .paramCount = 1 };
|
||||
// *** 新增 LCMapStringEx ***
|
||||
auto FakeApi_LCMapStringEx =
|
||||
_fakeApi{.func = Api_LCMapStringEx, .paramCount = 9}; // LCMapStringEx 有 9 个参数
|
||||
|
||||
// 添加文件操作相关API
|
||||
auto FakeApi_CreateFileW = _fakeApi{.func = Api_CreateFileW, .paramCount = 7};
|
||||
auto FakeApi_ReadFileA = _fakeApi{.func = Api_ReadFileA, .paramCount = 5};
|
||||
auto FakeApi_ReadFileW = _fakeApi{.func = Api_ReadFileW, .paramCount = 5};
|
||||
auto FakeApi_CloseFile = _fakeApi{.func = Api_CloseFile, .paramCount = 1};
|
||||
|
||||
api_map = {
|
||||
{"GetSystemTimeAsFileTime",
|
||||
@@ -1477,7 +1141,6 @@ auto Sandbox::InitApiHooks() -> void {
|
||||
{"CreatePipe", std::make_shared<_fakeApi>(FakeApi_CreatePipe)},
|
||||
{"CreateProcessA", std::make_shared<_fakeApi>(FakeApi_CreateProcessA)},
|
||||
{"CreateProcessW", std::make_shared<_fakeApi>(FakeApi_CreateProcessW)},
|
||||
{"ReadFile", std::make_shared<_fakeApi>(FakeApi_ReadFile)},
|
||||
{"WlanOpenHandle", std::make_shared<_fakeApi>(FakeApi_WlanOpenHandle)},
|
||||
{"WlanEnumInterfaces",
|
||||
std::make_shared<_fakeApi>(FakeApi_WlanEnumInterfaces)},
|
||||
@@ -1524,6 +1187,13 @@ auto Sandbox::InitApiHooks() -> void {
|
||||
{"VariantClear", std::make_shared<_fakeApi>(FakeApi_VariantClear)},
|
||||
{"SysAllocString", std::make_shared<_fakeApi>(FakeApi_SysAllocString)},
|
||||
{"LoadLibraryW", std::make_shared<_fakeApi>(FakeApi_LoadLibraryW)},
|
||||
// *** 新增 LCMapStringEx 映射 ***
|
||||
{"LCMapStringEx", std::make_shared<_fakeApi>(FakeApi_LCMapStringEx)},
|
||||
// 添加文件操作相关API映射
|
||||
{"CreateFileW", std::make_shared<_fakeApi>(FakeApi_CreateFileW)},
|
||||
{"ReadFileA", std::make_shared<_fakeApi>(FakeApi_ReadFileA)},
|
||||
{"ReadFileW", std::make_shared<_fakeApi>(FakeApi_ReadFileW)},
|
||||
{"CloseFile", std::make_shared<_fakeApi>(FakeApi_CloseFile)},
|
||||
};
|
||||
}
|
||||
auto Sandbox::EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip,
|
||||
|
||||
Reference in New Issue
Block a user