初步增加32位支持(没加全)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user