update & fix logic bug
This commit is contained in:
@@ -574,7 +574,7 @@ auto Api_WideCharToMultiByte(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
}
|
||||
} else {
|
||||
// 使用指定长度
|
||||
if (cchWideChar > 0 && cchWideChar <= MAX_PATH) {
|
||||
if (cchWideChar > 0 && cchWideChar <= 4 * 1024) {
|
||||
srcBuffer.resize(cchWideChar);
|
||||
if (uc_mem_read(uc, lpWideCharStr, srcBuffer.data(),
|
||||
cchWideChar * 2) != UC_ERR_OK) {
|
||||
@@ -699,7 +699,7 @@ auto Api_WideCharToMultiByte(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
"WideLen=%d, MultiStr=%p, MultiLen=%d, Result=%d\n",
|
||||
CodePage, dwFlags, (void*)lpWideCharStr, cchWideChar,
|
||||
(void*)lpMultiByteStr, cbMultiByte, result);
|
||||
|
||||
printf("[*] WideCharToMultiByte: pre=%s\n", multiByteBuffer.data());
|
||||
uc_reg_write(uc,
|
||||
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||||
&result);
|
||||
@@ -1338,8 +1338,7 @@ auto Api_EnterCriticalSection(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
if (context->GetPeInfo()->isX64) {
|
||||
currentThreadHandle =
|
||||
(HANDLE)(ULONG_PTR)context->GetTeb64()->ClientId.UniqueThread;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
currentThreadHandle =
|
||||
(HANDLE)(ULONG_PTR)context->GetTeb32()->ClientId.UniqueThread;
|
||||
}
|
||||
@@ -1347,21 +1346,19 @@ auto Api_EnterCriticalSection(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
if (lpCriticalSection != 0) {
|
||||
if (context->GetPeInfo()->isX64) {
|
||||
RTL_CRITICAL_SECTION cs;
|
||||
uc_mem_read(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION));
|
||||
|
||||
uc_mem_read(uc, lpCriticalSection, &cs,
|
||||
sizeof(RTL_CRITICAL_SECTION));
|
||||
|
||||
// 如果当前线程已经拥有锁,增加递归计数
|
||||
if (cs.OwningThread == currentThreadHandle) {
|
||||
cs.RecursionCount++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// 如果没有线程拥有锁,获取它
|
||||
if (cs.LockCount == -1) {
|
||||
cs.OwningThread = currentThreadHandle;
|
||||
cs.RecursionCount = 1;
|
||||
cs.LockCount = 0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// 在实际情况下这里应该自旋等待,但在模拟环境中我们直接获取锁
|
||||
cs.OwningThread = currentThreadHandle;
|
||||
cs.RecursionCount = 1;
|
||||
@@ -1370,25 +1367,23 @@ auto Api_EnterCriticalSection(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
}
|
||||
|
||||
// 写回更新后的关键段结构
|
||||
uc_mem_write(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION));
|
||||
}
|
||||
else {
|
||||
uc_mem_write(uc, lpCriticalSection, &cs,
|
||||
sizeof(RTL_CRITICAL_SECTION));
|
||||
} else {
|
||||
RTL_CRITICAL_SECTION32 cs;
|
||||
uc_mem_read(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION32));
|
||||
|
||||
uc_mem_read(uc, lpCriticalSection, &cs,
|
||||
sizeof(RTL_CRITICAL_SECTION32));
|
||||
|
||||
// 如果当前线程已经拥有锁,增加递归计数
|
||||
if (cs.OwningThread == (DWORD)currentThreadHandle) {
|
||||
cs.RecursionCount++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// 如果没有线程拥有锁,获取它
|
||||
if (cs.LockCount == -1) {
|
||||
cs.OwningThread = (DWORD)currentThreadHandle;
|
||||
cs.RecursionCount = 1;
|
||||
cs.LockCount = 0;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// 在实际情况下这里应该自旋等待,但在模拟环境中我们直接获取锁
|
||||
cs.OwningThread = (DWORD)currentThreadHandle;
|
||||
cs.RecursionCount = 1;
|
||||
@@ -1397,7 +1392,8 @@ auto Api_EnterCriticalSection(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
}
|
||||
|
||||
// 写回更新后的关键段结构
|
||||
uc_mem_write(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION32));
|
||||
uc_mem_write(uc, lpCriticalSection, &cs,
|
||||
sizeof(RTL_CRITICAL_SECTION32));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1475,9 +1471,8 @@ auto Api_GetStartupInfoW(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
}
|
||||
|
||||
if (lpStartupInfo != 0) {
|
||||
|
||||
if (context->GetPeInfo()->isX64) {
|
||||
STARTUPINFOW si = { 0 };
|
||||
STARTUPINFOW si = {0};
|
||||
si.cb = sizeof(STARTUPINFOW);
|
||||
si.dwFlags = STARTF_USESHOWWINDOW;
|
||||
si.wShowWindow = SW_SHOWNORMAL;
|
||||
@@ -1496,9 +1491,8 @@ auto Api_GetStartupInfoW(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
si.hStdOutput = nullptr;
|
||||
si.hStdError = nullptr;
|
||||
uc_mem_write(uc, lpStartupInfo, &si, sizeof(STARTUPINFOW));
|
||||
}
|
||||
else {
|
||||
STARTUPINFOW32 si = { 0 };
|
||||
} else {
|
||||
STARTUPINFOW32 si = {0};
|
||||
si.cb = sizeof(STARTUPINFOW32);
|
||||
si.dwFlags = STARTF_USESHOWWINDOW;
|
||||
si.wShowWindow = SW_SHOWNORMAL;
|
||||
@@ -2111,21 +2105,24 @@ auto Api_RtlFormatCurrentUserKeyPath(void* sandbox, uc_engine* uc,
|
||||
if (context->GetPeInfo()->isX64) {
|
||||
// 创建UNICODE_STRING结构
|
||||
UNICODE_STRING unicodeString;
|
||||
unicodeString.Length = static_cast<USHORT>(pathLen * sizeof(wchar_t));
|
||||
unicodeString.Length =
|
||||
static_cast<USHORT>(pathLen * sizeof(wchar_t));
|
||||
unicodeString.MaximumLength = static_cast<USHORT>(bufferSize);
|
||||
unicodeString.Buffer = reinterpret_cast<PWSTR>(stringBuffer);
|
||||
|
||||
// 将UNICODE_STRING结构写入到提供的缓冲区
|
||||
uc_mem_write(uc, keyPathBuffer, &unicodeString, sizeof(UNICODE_STRING));
|
||||
}
|
||||
else {
|
||||
uc_mem_write(uc, keyPathBuffer, &unicodeString,
|
||||
sizeof(UNICODE_STRING));
|
||||
} else {
|
||||
UNICODE_STRING32 unicodeString;
|
||||
unicodeString.Length = static_cast<USHORT>(pathLen * sizeof(wchar_t));
|
||||
unicodeString.Length =
|
||||
static_cast<USHORT>(pathLen * sizeof(wchar_t));
|
||||
unicodeString.MaximumLength = static_cast<USHORT>(bufferSize);
|
||||
unicodeString.Buffer = (DWORD)(stringBuffer);
|
||||
|
||||
// 将UNICODE_STRING结构写入到提供的缓冲区
|
||||
uc_mem_write(uc, keyPathBuffer, &unicodeString, sizeof(UNICODE_STRING32));
|
||||
uc_mem_write(uc, keyPathBuffer, &unicodeString,
|
||||
sizeof(UNICODE_STRING32));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2389,3 +2386,148 @@ auto Api_FlsGetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void {
|
||||
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||||
&return_value);
|
||||
}
|
||||
|
||||
auto Api__initterm_e(void* sandbox, uc_engine* uc, uint64_t address) -> void {
|
||||
auto context = static_cast<Sandbox*>(sandbox);
|
||||
uint64_t table_start = 0;
|
||||
uint64_t table_end = 0;
|
||||
|
||||
// 获取参数:函数表的起始地址和结束地址
|
||||
if (context->GetPeInfo()->isX64) {
|
||||
// x64: 参数在RCX和RDX中
|
||||
uc_reg_read(uc, UC_X86_REG_RCX, &table_start);
|
||||
uc_reg_read(uc, UC_X86_REG_RDX, &table_end);
|
||||
} else {
|
||||
// x86: 从栈上读取参数
|
||||
uint32_t esp = 0;
|
||||
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
|
||||
esp += 0x4; // 跳过返回地址
|
||||
|
||||
uint32_t temp_start;
|
||||
uc_mem_read(uc, esp, &temp_start, sizeof(uint32_t));
|
||||
table_start = temp_start;
|
||||
|
||||
esp += 0x4;
|
||||
uint32_t temp_end;
|
||||
uc_mem_read(uc, esp, &temp_end, sizeof(uint32_t));
|
||||
table_end = temp_end;
|
||||
}
|
||||
|
||||
// 返回值,默认为0(成功)
|
||||
int32_t return_value = 0;
|
||||
|
||||
// 遍历函数表并调用每个初始化函数
|
||||
// 在表的每一项都是函数指针
|
||||
printf("[*] _initterm_e: Start=0x%llx, End=0x%llx\n", table_start,
|
||||
table_end);
|
||||
|
||||
// 只有当表的起始地址和结束地址有效时才进行处理
|
||||
if (table_start < table_end) {
|
||||
uint64_t current = table_start;
|
||||
uint64_t ptr_size = context->GetPeInfo()->isX64 ? 8 : 4;
|
||||
|
||||
// 遍历函数表
|
||||
while (current < table_end) {
|
||||
uint64_t function_ptr = 0;
|
||||
|
||||
// 读取当前表项中的函数指针
|
||||
uc_mem_read(uc, current, &function_ptr, ptr_size);
|
||||
|
||||
// 非空函数指针才调用
|
||||
if (function_ptr != 0) {
|
||||
printf("[*] _initterm_e: Calling function at 0x%llx\n",
|
||||
function_ptr);
|
||||
|
||||
// 在实际环境中,这里会调用该函数并检查返回值
|
||||
// 但在沙箱中,我们模拟这个调用并返回成功
|
||||
// 如果需要执行真实函数,可以使用uc_emu_start
|
||||
|
||||
// 如果有错误发生,设置返回值并退出
|
||||
// 这里简化处理,始终假设初始化成功
|
||||
// 实际实现可能需要更复杂的逻辑
|
||||
}
|
||||
|
||||
// 移动到下一个表项
|
||||
current += ptr_size;
|
||||
}
|
||||
}
|
||||
|
||||
// 设置返回值
|
||||
uc_reg_write(uc,
|
||||
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||||
&return_value);
|
||||
}
|
||||
|
||||
// 实现getenv API
|
||||
auto Api_getenv(void* sandbox, uc_engine* uc, uint64_t address) -> void {
|
||||
auto context = static_cast<Sandbox*>(sandbox);
|
||||
uint64_t name_ptr = 0;
|
||||
char name[256] = {0};
|
||||
uint64_t return_value = 0; // 默认返回NULL
|
||||
|
||||
// 获取参数 - 环境变量名称
|
||||
if (context->GetPeInfo()->isX64) {
|
||||
// x64: rcx = name
|
||||
uc_reg_read(uc, UC_X86_REG_RCX, &name_ptr);
|
||||
} else {
|
||||
// x86: 从栈上读取参数
|
||||
uint32_t esp_address = 0;
|
||||
uint32_t temp_name_ptr = 0;
|
||||
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
|
||||
esp_address += 0x4; // 跳过返回地址
|
||||
uc_mem_read(uc, esp_address, &temp_name_ptr, sizeof(uint32_t));
|
||||
name_ptr = temp_name_ptr;
|
||||
}
|
||||
|
||||
// 读取环境变量名
|
||||
if (name_ptr != 0) {
|
||||
size_t i = 0;
|
||||
uint8_t byte = 1;
|
||||
while (byte != 0 && i < sizeof(name) - 1) {
|
||||
uc_mem_read(uc, name_ptr + i, &byte, 1);
|
||||
name[i++] = static_cast<char>(byte);
|
||||
}
|
||||
name[i] = '\0';
|
||||
}
|
||||
|
||||
printf("[*] getenv: Looking for env var '%s'\n", name);
|
||||
|
||||
// 获取环境变量值
|
||||
bool found = false;
|
||||
std::string value;
|
||||
std::vector<std::wstring> envStrings = context->GetEnvStrings();
|
||||
|
||||
for (const auto& var : envStrings) {
|
||||
std::string varA(var.begin(), var.end());
|
||||
size_t pos = varA.find('=');
|
||||
if (pos != std::string::npos) {
|
||||
std::string varName = varA.substr(0, pos);
|
||||
if (_stricmp(varName.c_str(), name) == 0) {
|
||||
value = varA.substr(pos + 1);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
// 分配内存存储环境变量值
|
||||
uint64_t valueSize = value.size() + 1; // 包括结束符
|
||||
uint64_t valuePtr = context->AllocateMemory(valueSize);
|
||||
|
||||
if (valuePtr) {
|
||||
// 复制字符串到内存
|
||||
uc_mem_write(uc, valuePtr, value.c_str(), valueSize);
|
||||
return_value = valuePtr;
|
||||
printf("[*] getenv: Found '%s'='%s' at 0x%llx\n", name,
|
||||
value.c_str(), valuePtr);
|
||||
}
|
||||
} else {
|
||||
printf("[*] getenv: Env var '%s' not found\n", name);
|
||||
}
|
||||
|
||||
// 设置返回值
|
||||
uc_reg_write(uc,
|
||||
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||||
&return_value);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user