This commit is contained in:
huoji
2025-04-25 16:08:22 +08:00
parent db31cd90b5
commit e160fd0d57
8 changed files with 937 additions and 349 deletions

View File

@@ -2531,3 +2531,591 @@ auto Api_getenv(void* sandbox, uc_engine* uc, uint64_t address) -> void {
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&return_value);
}
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);
}
// 实现 LCMapStringEx API
auto Api_LCMapStringEx(void* sandbox, uc_engine* uc, uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t lpLocaleName = 0;
uint64_t dwMapFlags = 0;
uint64_t lpSrcStr = 0;
uint64_t cchSrc = 0;
uint64_t lpDestStr = 0;
uint64_t cchDest = 0;
uint64_t lpVersionInformation = 0; // 通常为 NULL
uint64_t lpReserved = 0; // 必须为 NULL
uint64_t sortHandle = 0; // 必须为 0
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = lpLocaleName, rdx = dwMapFlags, r8 = lpSrcStr, r9 = cchSrc
uc_reg_read(uc, UC_X86_REG_RCX, &lpLocaleName);
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);
// 从栈上读取剩余参数 (参数 5 到 9)
uint64_t rsp;
uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
// 参数从 rsp + 0x28 开始 (跳过4个寄存器参数的shadow space + 返回地址)
uc_mem_read(uc, rsp + 0x28, &lpDestStr, sizeof(uint64_t));
uc_mem_read(uc, rsp + 0x30, &cchDest, sizeof(int32_t));
// 注意:参数在栈上的偏移量可能需要根据调用约定微调
uc_mem_read(uc, rsp + 0x38, &lpVersionInformation, sizeof(uint64_t));
uc_mem_read(uc, rsp + 0x40, &lpReserved, sizeof(uint64_t));
uc_mem_read(uc, rsp + 0x48, &sortHandle, 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_locale_name, temp_src_str, temp_dest_str, temp_version_info, temp_reserved, temp_sort_handle;
uc_mem_read(uc, esp_address, &temp_locale_name, sizeof(uint32_t)); lpLocaleName = temp_locale_name; esp_address += 0x4;
uc_mem_read(uc, esp_address, &dwMapFlags, sizeof(uint32_t)); esp_address += 0x4;
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;
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)); esp_address += 0x4;
uc_mem_read(uc, esp_address, &temp_version_info, sizeof(uint32_t)); lpVersionInformation = temp_version_info; esp_address += 0x4;
uc_mem_read(uc, esp_address, &temp_reserved, sizeof(uint32_t)); lpReserved = temp_reserved; esp_address += 0x4;
uc_mem_read(uc, esp_address, &temp_sort_handle, sizeof(uint32_t)); sortHandle = temp_sort_handle; esp_address += 0x4;
}
// 读取区域设置名称(可选,模拟中可能忽略)
std::wstring localeNameStr;
if (lpLocaleName != 0) {
wchar_t buffer[LOCALE_NAME_MAX_LENGTH] = { 0 };
size_t i = 0;
do {
uint16_t wchar;
if (uc_mem_read(uc, lpLocaleName + (i * 2), &wchar, 2) != UC_ERR_OK) break;
buffer[i] = wchar;
i++;
} while (buffer[i - 1] != 0 && i < LOCALE_NAME_MAX_LENGTH);
localeNameStr = buffer;
}
// 验证参数 (与 LCMapStringW 类似)
if (lpSrcStr == 0 || lpReserved != 0 || sortHandle != 0) { // 添加了对 lpReserved 和 sortHandle 的检查
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;
}
printf("[*] LCMapStringEx: Invalid parameter (lpSrcStr=0x%llx, lpReserved=0x%llx, sortHandle=0x%llx)\\n", lpSrcStr, lpReserved, sortHandle);
return;
}
// 如果cchSrc为负数计算源字符串长度 (与 LCMapStringW 相同)
if (cchSrc < 0) {
cchSrc = 0;
wchar_t temp_char;
do {
if (uc_mem_read(uc, lpSrcStr + (cchSrc * 2), &temp_char, sizeof(wchar_t)) != UC_ERR_OK) {
// 内存读取错误处理
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;
printf("[*] LCMapStringEx: Error reading source string length at 0x%llx\\n", lpSrcStr + (cchSrc * 2));
return;
}
cchSrc++;
} while (temp_char != 0 && cchSrc < 4096); // 增加合理上限防止死循环
if (cchSrc >= 4096) {
// 字符串过长或未找到终止符
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;
printf("[*] LCMapStringEx: Source string too long or unterminated at 0x%llx\\n", lpSrcStr);
return;
}
cchSrc--; // 不包括null终止符
}
// 读取源字符串 (与 LCMapStringW 相同)
std::vector<wchar_t> srcStr(cchSrc + 1, 0); // 分配足够空间并初始化为0
if (cchSrc > 0) {
if (uc_mem_read(uc, lpSrcStr, srcStr.data(), cchSrc * sizeof(wchar_t)) != UC_ERR_OK) {
// 内存读取错误处理
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;
printf("[*] LCMapStringEx: Error reading source string data from 0x%llx\\n", lpSrcStr);
return;
}
}
uint32_t required_size = cchSrc; // 默认需要的大小与源长度相同
bool needs_null_terminator = false; // 是否需要在目标缓冲区添加空终止符
// 根据 dwMapFlags 确定是否需要空终止符以及调整所需大小
if (!(dwMapFlags & LCMAP_BYTEREV) && !(dwMapFlags & LCMAP_SORTKEY)) {
required_size++; // 需要为 null 终止符增加空间
needs_null_terminator = true;
}
if (dwMapFlags & LCMAP_SORTKEY) {
required_size = cchSrc * 2 + 1; // 排序键通常需要更多空间,包含终止符
needs_null_terminator = true; // Sortkey is null-terminated byte array
}
// 如果cchDest为0返回所需缓冲区大小 (与 LCMapStringW 类似,但考虑了 null 终止符)
if (cchDest == 0) {
uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &required_size);
printf("[*] LCMapStringEx: Querying buffer size. Required: %u\\n", required_size);
return;
}
// 检查目标缓冲区大小是否足够
if (cchDest < required_size) {
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;
}
printf("[*] LCMapStringEx: Insufficient buffer. Provided: %d, Required: %u\\n", cchDest, required_size);
return;
}
// 处理字符串映射 (与 LCMapStringW 类似)
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; // 默认保持不变
}
// TODO: 处理其他 dwMapFlags如 LCMAP_HALFWIDTH, LCMAP_FULLWIDTH, LCMAP_HIRAGANA, LCMAP_KATAKANA, LCMAP_LINGUISTIC_CASING 等
// 这些需要更复杂的实现,可能需要 NLS 功能库或 ICU
}
// 写入结果
uint32_t written_size = 0;
uc_err write_err = UC_ERR_OK;
if (dwMapFlags & LCMAP_SORTKEY) {
// 生成简单的排序键(这里只是一个基本实现) (与 LCMapStringW 相同)
std::vector<BYTE> sortKey(required_size); // 使用 required_size
for (int i = 0; i < cchSrc; i++) {
// 简单地将 wchar_t 分解为两个字节
sortKey[i * 2] = static_cast<BYTE>(destStr[i] & 0xFF);
sortKey[i * 2 + 1] = static_cast<BYTE>((destStr[i] >> 8) & 0xFF);
}
sortKey[cchSrc * 2] = 0; // 终止符
write_err = uc_mem_write(uc, lpDestStr, sortKey.data(), required_size);
written_size = required_size;
}
else {
// 写入映射后的字符串
write_err = uc_mem_write(uc, lpDestStr, destStr.data(), cchSrc * sizeof(wchar_t));
if (write_err == UC_ERR_OK && needs_null_terminator) {
// 写入 null 终止符
wchar_t null_term = 0;
write_err = uc_mem_write(uc, lpDestStr + (cchSrc * sizeof(wchar_t)), &null_term, sizeof(wchar_t));
}
written_size = needs_null_terminator ? (cchSrc + 1) : cchSrc;
}
if (write_err != UC_ERR_OK) {
// 写入错误处理
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;
printf("[*] LCMapStringEx: Error writing to destination buffer at 0x%llx. Error: %u\\n", lpDestStr, write_err);
return;
}
// 设置返回值 (写入的字符数或字节数,取决于 flags)
uc_reg_write(uc, context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX, &written_size);
printf("[*] LCMapStringEx: Locale=%ls, MapFlags=0x%x, SrcLen=%d, DestLen=%d, Result=%u\\n",
localeNameStr.empty() ? L"(null)" : localeNameStr.c_str(), dwMapFlags, cchSrc, cchDest, written_size);
}