初步增加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

@@ -1333,39 +1333,72 @@ auto Api_EnterCriticalSection(void* sandbox, uc_engine* uc, uint64_t address)
lpCriticalSection = temp_cs;
}
// 获取当前线程ID
HANDLE currentThreadHandle = nullptr;
if (context->GetPeInfo()->isX64) {
currentThreadHandle =
(HANDLE)(ULONG_PTR)context->GetTeb64()->ClientId.UniqueThread;
}
else {
currentThreadHandle =
(HANDLE)(ULONG_PTR)context->GetTeb32()->ClientId.UniqueThread;
}
if (lpCriticalSection != 0) {
RTL_CRITICAL_SECTION cs;
uc_mem_read(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION));
// 获取当前线程ID
HANDLE currentThreadHandle = nullptr;
if (context->GetPeInfo()->isX64) {
currentThreadHandle =
(HANDLE)(ULONG_PTR)context->GetTeb64()->ClientId.UniqueThread;
} else {
currentThreadHandle =
(HANDLE)(ULONG_PTR)context->GetTeb32()->ClientId.UniqueThread;
}
RTL_CRITICAL_SECTION cs;
uc_mem_read(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION));
// 如果当前线程已经拥有锁,增加递归计数
if (cs.OwningThread == currentThreadHandle) {
cs.RecursionCount++;
} else {
// 如果没有线程拥有锁,获取它
if (cs.LockCount == -1) {
cs.OwningThread = currentThreadHandle;
cs.RecursionCount = 1;
cs.LockCount = 0;
} else {
// 在实际情况下这里应该自旋等待,但在模拟环境中我们直接获取锁
cs.OwningThread = currentThreadHandle;
cs.RecursionCount = 1;
cs.LockCount++;
// 如果当前线程已经拥有锁,增加递归计数
if (cs.OwningThread == currentThreadHandle) {
cs.RecursionCount++;
}
else {
// 如果没有线程拥有锁,获取它
if (cs.LockCount == -1) {
cs.OwningThread = currentThreadHandle;
cs.RecursionCount = 1;
cs.LockCount = 0;
}
else {
// 在实际情况下这里应该自旋等待,但在模拟环境中我们直接获取锁
cs.OwningThread = currentThreadHandle;
cs.RecursionCount = 1;
cs.LockCount++;
}
}
}
// 写回更新后的关键段结构
uc_mem_write(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION));
// 写回更新后的关键段结构
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));
// 如果当前线程已经拥有锁,增加递归计数
if (cs.OwningThread == (DWORD)currentThreadHandle) {
cs.RecursionCount++;
}
else {
// 如果没有线程拥有锁,获取它
if (cs.LockCount == -1) {
cs.OwningThread = (DWORD)currentThreadHandle;
cs.RecursionCount = 1;
cs.LockCount = 0;
}
else {
// 在实际情况下这里应该自旋等待,但在模拟环境中我们直接获取锁
cs.OwningThread = (DWORD)currentThreadHandle;
cs.RecursionCount = 1;
cs.LockCount++;
}
}
// 写回更新后的关键段结构
uc_mem_write(uc, lpCriticalSection, &cs, sizeof(RTL_CRITICAL_SECTION32));
}
}
printf("[*] EnterCriticalSection: CS=0x%llx\n", lpCriticalSection);
@@ -1426,7 +1459,7 @@ auto Api_GetStartupInfoW(void* sandbox, uc_engine* uc, uint64_t address)
-> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t lpStartupInfo = 0;
printf("[*] GetStartupInfoW start dump vmenv\n");
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = lpStartupInfo
@@ -1442,28 +1475,49 @@ auto Api_GetStartupInfoW(void* sandbox, uc_engine* uc, uint64_t address)
}
if (lpStartupInfo != 0) {
// 创建一个默认的 STARTUPINFOW 结构
STARTUPINFOW si = {0};
si.cb = sizeof(STARTUPINFOW);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOWNORMAL;
si.lpDesktop = nullptr;
si.lpTitle = nullptr;
si.dwX = 0;
si.dwY = 0;
si.dwXSize = 0;
si.dwYSize = 0;
si.dwXCountChars = 0;
si.dwYCountChars = 0;
si.dwFillAttribute = 0;
si.cbReserved2 = 0;
si.lpReserved2 = nullptr;
si.hStdInput = nullptr;
si.hStdOutput = nullptr;
si.hStdError = nullptr;
// 写入结构到目标内存
uc_mem_write(uc, lpStartupInfo, &si, sizeof(STARTUPINFOW));
if (context->GetPeInfo()->isX64) {
STARTUPINFOW si = { 0 };
si.cb = sizeof(STARTUPINFOW);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOWNORMAL;
si.lpDesktop = nullptr;
si.lpTitle = nullptr;
si.dwX = 0;
si.dwY = 0;
si.dwXSize = 0;
si.dwYSize = 0;
si.dwXCountChars = 0;
si.dwYCountChars = 0;
si.dwFillAttribute = 0;
si.cbReserved2 = 0;
si.lpReserved2 = nullptr;
si.hStdInput = nullptr;
si.hStdOutput = nullptr;
si.hStdError = nullptr;
uc_mem_write(uc, lpStartupInfo, &si, sizeof(STARTUPINFOW));
}
else {
STARTUPINFOW32 si = { 0 };
si.cb = sizeof(STARTUPINFOW32);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOWNORMAL;
si.lpDesktop = 0;
si.lpTitle = 0;
si.dwX = 0;
si.dwY = 0;
si.dwXSize = 0;
si.dwYSize = 0;
si.dwXCountChars = 0;
si.dwYCountChars = 0;
si.dwFillAttribute = 0;
si.cbReserved2 = 0;
si.lpReserved2 = 0;
si.hStdInput = 0;
si.hStdOutput = 0;
si.hStdError = 0;
uc_mem_write(uc, lpStartupInfo, &si, sizeof(STARTUPINFOW32));
}
}
printf("[*] GetStartupInfoW: lpStartupInfo=0x%llx\n", lpStartupInfo);
@@ -2058,15 +2112,25 @@ auto Api_RtlFormatCurrentUserKeyPath(void* sandbox, uc_engine* uc,
if (stringBuffer != 0 && keyPathBuffer != 0) {
// 将路径字符串写入到分配的缓冲区
uc_mem_write(uc, stringBuffer, userKeyPath, bufferSize);
if (context->GetPeInfo()->isX64) {
// 创建UNICODE_STRING结构
UNICODE_STRING unicodeString;
unicodeString.Length = static_cast<USHORT>(pathLen * sizeof(wchar_t));
unicodeString.MaximumLength = static_cast<USHORT>(bufferSize);
unicodeString.Buffer = reinterpret_cast<PWSTR>(stringBuffer);
// 创建UNICODE_STRING结构
UNICODE_STRING unicodeString;
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 {
UNICODE_STRING32 unicodeString;
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_STRING));
// 将UNICODE_STRING结构写入到提供的缓冲区
uc_mem_write(uc, keyPathBuffer, &unicodeString, sizeof(UNICODE_STRING32));
}
}
// 返回NTSTATUS成功代码 (0x00000000 = STATUS_SUCCESS)
@@ -2143,3 +2207,189 @@ auto Api_FlsSetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void {
}
}
}
// 实现TlsFree API
auto Api_TlsFree(void* sandbox, uc_engine* uc, uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint32_t dwTlsIndex = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = dwTlsIndex
uint64_t temp_index;
uc_reg_read(uc, UC_X86_REG_RCX, &temp_index);
dwTlsIndex = static_cast<uint32_t>(temp_index);
} 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, &dwTlsIndex, sizeof(uint32_t));
}
// 检查索引是否有效小于64并释放对应的TLS槽
BOOL success = FALSE;
if (dwTlsIndex < 64) {
if (context->GetPeInfo()->isX64) {
auto teb = context->GetTeb64();
// 检查槽是否已分配不为0x1337ffffff
if (teb->TlsSlots[dwTlsIndex] != (void*)0x1337ffffff) {
// 将槽位标记为可用
teb->TlsSlots[dwTlsIndex] = (void*)0x1337ffffff;
success = TRUE;
}
} else {
auto teb = context->GetTeb32();
// 检查槽是否已分配不为0x1337
if (teb->TlsSlots[dwTlsIndex] != 0x1337) {
// 将槽位标记为可用
teb->TlsSlots[dwTlsIndex] = 0x1337;
success = TRUE;
}
}
}
if (!success) {
// 设置错误码
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
}
printf("[*] TlsFree: Index=0x%x, Success=%d\n", dwTlsIndex, success);
// 返回操作是否成功
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&success);
}
// 实现FlsAlloc API
auto Api_FlsAlloc(void* sandbox, uc_engine* uc, uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t lpCallback = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = lpCallback
uc_reg_read(uc, UC_X86_REG_RCX, &lpCallback);
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uint32_t temp_callback = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uc_mem_read(uc, esp_address, &temp_callback, sizeof(uint32_t));
lpCallback = temp_callback;
}
// 初始化返回值为失败状态
DWORD fls_index = FLS_OUT_OF_INDEXES;
// 获取TEB结构
if (context->GetPeInfo()->isX64) {
auto teb = context->GetTeb64();
// 在TLS槽中查找第一个可用的位置
for (DWORD i = 0; i < 64; i++) { // TEB中TlsSlots数组大小为64
if (teb->TlsSlots[i] == (void*)0x1337ffffff) {
teb->TlsSlots[i] = (void*)0; // 标记为已使用
fls_index = i;
break;
}
}
} else {
auto teb = context->GetTeb32();
// 在TLS槽中查找第一个可用的位置
for (DWORD i = 0; i < 64; i++) { // TEB中TlsSlots数组大小为64
if (teb->TlsSlots[i] == 0x1337) {
teb->TlsSlots[i] = 0; // 标记为已使用
fls_index = i;
break;
}
}
}
if (fls_index == FLS_OUT_OF_INDEXES) {
// 设置LastError为没有可用的FLS索引
DWORD error = ERROR_NO_MORE_ITEMS;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
}
printf("[*] FlsAlloc: Callback=0x%llx, Allocated FLS Index=0x%x\n",
lpCallback, fls_index);
// 返回分配的FLS索引
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&fls_index);
}
// 实现FlsGetValue API
auto Api_FlsGetValue(void* sandbox, uc_engine* uc, uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint32_t dwFlsIndex = 0;
uint64_t return_value = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = dwFlsIndex
uint64_t temp_index;
uc_reg_read(uc, UC_X86_REG_RCX, &temp_index);
dwFlsIndex = static_cast<uint32_t>(temp_index);
} 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, &dwFlsIndex, sizeof(uint32_t));
}
// 检查索引是否有效小于64
if (dwFlsIndex < 64) {
if (context->GetPeInfo()->isX64) {
auto teb = context->GetTeb64();
// 检查槽是否已分配不为nullptr
if (teb->TlsSlots[dwFlsIndex] != (void*)0x1337ffffff) {
return_value =
reinterpret_cast<uint64_t>(teb->TlsSlots[dwFlsIndex]);
} else {
// 槽未分配设置LastError
DWORD error = ERROR_INVALID_PARAMETER;
teb->LastErrorValue = error;
}
} else {
auto teb = context->GetTeb32();
// 检查槽是否已分配不为0
if (teb->TlsSlots[dwFlsIndex] != 0x1337) {
return_value = teb->TlsSlots[dwFlsIndex];
} else {
// 槽未分配设置LastError
DWORD error = ERROR_INVALID_PARAMETER;
teb->LastErrorValue = error;
}
}
} else {
// 索引无效设置LastError
DWORD error = ERROR_INVALID_PARAMETER;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
}
printf("[*] FlsGetValue: Index=0x%x, Value=0x%llx\n", dwFlsIndex,
return_value);
// 返回FLS槽中的值
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&return_value);
}