修复沙箱功能和API实现
- 在沙箱中添加了对CreateProcessW的支持,整合了CreateProcessA和CreateProcessW的共同逻辑 - 实现了URLDownloadToFileW函数,增加了对可疑URL的检测 - 更新了API钩子以支持新的API功能 - 改进了错误处理和日志记录,确保更好的调试信息输出 - 调整了主函数中的恶意软件扫描和沙箱功能调用顺序,确保恶意软件扫描优先执行
This commit is contained in:
@@ -474,6 +474,211 @@ auto Api_Process32NextW(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
}
|
||||
}
|
||||
|
||||
// 内部函数,用于处理CreateProcessA和CreateProcessW的共同逻辑
|
||||
auto CreateProcessInternal(void* sandbox, uc_engine* uc,
|
||||
uint64_t lpApplicationName, uint64_t lpCommandLine,
|
||||
uint64_t lpProcessInformation,
|
||||
uint64_t lpStartupInfo, bool isWideChar) -> bool {
|
||||
auto* context = static_cast<Sandbox*>(sandbox);
|
||||
std::string applicationName;
|
||||
std::wstring wApplicationName;
|
||||
std::string commandLine;
|
||||
std::wstring wCommandLine;
|
||||
|
||||
// 读取应用程序名称
|
||||
if (lpApplicationName != 0) {
|
||||
if (isWideChar) {
|
||||
// 读取宽字符应用程序名称
|
||||
wchar_t buffer[MAX_PATH] = {0};
|
||||
size_t i = 0;
|
||||
bool success = true;
|
||||
|
||||
do {
|
||||
wchar_t ch;
|
||||
uc_err err =
|
||||
uc_mem_read(uc, lpApplicationName + (i * 2), &ch, 2);
|
||||
if (err != UC_ERR_OK) {
|
||||
printf(
|
||||
"[!] Error reading wide application name at address "
|
||||
"0x%llx: %u\n",
|
||||
lpApplicationName + (i * 2), err);
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
if (ch == 0) break;
|
||||
buffer[i] = ch;
|
||||
i++;
|
||||
} while (i < MAX_PATH - 1);
|
||||
|
||||
// 确保字符串以 NULL 结尾
|
||||
buffer[i] = 0;
|
||||
|
||||
if (success) {
|
||||
wApplicationName = std::wstring(buffer);
|
||||
// 转换为ANSI以便于日志记录
|
||||
std::string ansiAppName(wApplicationName.begin(),
|
||||
wApplicationName.end());
|
||||
printf("[*] Read Wide ApplicationName: %s (Length: %zu)\n",
|
||||
ansiAppName.c_str(), wApplicationName.length());
|
||||
}
|
||||
} else {
|
||||
// 读取ANSI应用程序名称
|
||||
char buffer[MAX_PATH] = {0};
|
||||
size_t i = 0;
|
||||
bool success = true;
|
||||
|
||||
do {
|
||||
uint8_t byte;
|
||||
uc_err err = uc_mem_read(uc, lpApplicationName + i, &byte, 1);
|
||||
if (err != UC_ERR_OK) {
|
||||
printf(
|
||||
"[!] Error reading application name at address 0x%llx: "
|
||||
"%u\n",
|
||||
lpApplicationName + i, err);
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
if (byte == 0) break;
|
||||
buffer[i] = byte;
|
||||
i++;
|
||||
} while (i < MAX_PATH - 1);
|
||||
|
||||
// 确保字符串以 NULL 结尾
|
||||
buffer[i] = 0;
|
||||
|
||||
if (success) {
|
||||
applicationName = std::string(buffer);
|
||||
printf("[*] Read ANSI ApplicationName: %s (Length: %zu)\n",
|
||||
buffer, applicationName.length());
|
||||
// 转换为宽字符
|
||||
wApplicationName = std::wstring(applicationName.begin(),
|
||||
applicationName.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 读取命令行
|
||||
if (lpCommandLine != 0) {
|
||||
if (isWideChar) {
|
||||
// 读取宽字符命令行
|
||||
wchar_t buffer[MAX_PATH] = {0};
|
||||
size_t i = 0;
|
||||
bool success = true;
|
||||
|
||||
do {
|
||||
wchar_t ch;
|
||||
uc_err err = uc_mem_read(uc, lpCommandLine + (i * 2), &ch, 2);
|
||||
if (err != UC_ERR_OK) {
|
||||
printf(
|
||||
"[!] Error reading wide command line at address "
|
||||
"0x%llx: %u\n",
|
||||
lpCommandLine + (i * 2), err);
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
if (ch == 0) break;
|
||||
buffer[i] = ch;
|
||||
i++;
|
||||
} while (i < MAX_PATH - 1);
|
||||
|
||||
// 确保字符串以 NULL 结尾
|
||||
buffer[i] = 0;
|
||||
|
||||
if (success) {
|
||||
wCommandLine = std::wstring(buffer);
|
||||
// 转换为ANSI以便于日志记录
|
||||
std::string ansiCmdLine(wCommandLine.begin(),
|
||||
wCommandLine.end());
|
||||
printf("[*] Read Wide CommandLine: %s (Length: %zu)\n",
|
||||
ansiCmdLine.c_str(), wCommandLine.length());
|
||||
}
|
||||
} else {
|
||||
// 读取ANSI命令行
|
||||
char buffer[MAX_PATH] = {0};
|
||||
size_t i = 0;
|
||||
bool success = true;
|
||||
|
||||
do {
|
||||
uint8_t byte;
|
||||
uc_err err = uc_mem_read(uc, lpCommandLine + i, &byte, 1);
|
||||
if (err != UC_ERR_OK) {
|
||||
printf(
|
||||
"[!] Error reading command line at address 0x%llx: "
|
||||
"%u\n",
|
||||
lpCommandLine + i, err);
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
if (byte == 0) break;
|
||||
buffer[i] = byte;
|
||||
i++;
|
||||
} while (i < MAX_PATH - 1);
|
||||
|
||||
// 确保字符串以 NULL 结尾
|
||||
buffer[i] = 0;
|
||||
|
||||
if (success) {
|
||||
commandLine = std::string(buffer);
|
||||
printf("[*] Read ANSI CommandLine: %s (Length: %zu)\n", buffer,
|
||||
commandLine.length());
|
||||
// 转换为宽字符
|
||||
wCommandLine =
|
||||
std::wstring(commandLine.begin(), commandLine.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 记录调用信息
|
||||
if (isWideChar) {
|
||||
std::string ansiAppName(wApplicationName.begin(),
|
||||
wApplicationName.end());
|
||||
std::string ansiCmdLine(wCommandLine.begin(), wCommandLine.end());
|
||||
printf("[*] CreateProcessW: ApplicationName=%s, CommandLine=%s\n",
|
||||
ansiAppName.empty() ? "(null)" : ansiAppName.c_str(),
|
||||
ansiCmdLine.empty() ? "(null)" : ansiCmdLine.c_str());
|
||||
} else {
|
||||
printf("[*] CreateProcessA: ApplicationName=%s, CommandLine=%s\n",
|
||||
applicationName.empty() ? "(null)" : applicationName.c_str(),
|
||||
commandLine.empty() ? "(null)" : commandLine.c_str());
|
||||
}
|
||||
|
||||
// 模拟创建进程,设置进程和线程ID
|
||||
DWORD processId = 0x1234;
|
||||
DWORD threadId = 0x5678;
|
||||
HANDLE hProcess = (HANDLE)0x1340;
|
||||
HANDLE hThread = (HANDLE)0x1341;
|
||||
|
||||
// 写入进程信息
|
||||
if (lpProcessInformation != 0) {
|
||||
if (context->GetPeInfo()->isX64) {
|
||||
struct PROCESS_INFORMATION64 {
|
||||
HANDLE hProcess;
|
||||
HANDLE hThread;
|
||||
DWORD dwProcessId;
|
||||
DWORD dwThreadId;
|
||||
} pi;
|
||||
pi.hProcess = (HANDLE)hProcess;
|
||||
pi.hThread = (HANDLE)hThread;
|
||||
pi.dwProcessId = processId;
|
||||
pi.dwThreadId = threadId;
|
||||
uc_mem_write(uc, lpProcessInformation, &pi, sizeof(pi));
|
||||
printf("[*] Wrote process info (x64) to 0x%llx\n",
|
||||
lpProcessInformation);
|
||||
} else {
|
||||
PROCESS_INFORMATION pi;
|
||||
pi.hProcess = hProcess;
|
||||
pi.hThread = hThread;
|
||||
pi.dwProcessId = processId;
|
||||
pi.dwThreadId = threadId;
|
||||
uc_mem_write(uc, lpProcessInformation, &pi, sizeof(pi));
|
||||
printf("[*] Wrote process info (x86) to 0x%llx\n",
|
||||
lpProcessInformation);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
auto Api_CreateProcessA(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void {
|
||||
auto context = static_cast<Sandbox*>(sandbox);
|
||||
@@ -521,109 +726,73 @@ auto Api_CreateProcessA(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
esp, temp_app_name, temp_cmd_line);
|
||||
}
|
||||
|
||||
// 读取应用程序名称
|
||||
std::string applicationName;
|
||||
if (lpApplicationName != 0) {
|
||||
// 增加大小检测以避免内存溢出
|
||||
char buffer[MAX_PATH] = {0};
|
||||
size_t i = 0;
|
||||
bool success = true;
|
||||
// 调用内部函数处理共同逻辑
|
||||
bool success =
|
||||
CreateProcessInternal(sandbox, uc, lpApplicationName, lpCommandLine,
|
||||
lpProcessInformation, lpStartupInfo, false);
|
||||
|
||||
do {
|
||||
uint8_t byte;
|
||||
uc_err err = uc_mem_read(uc, lpApplicationName + i, &byte, 1);
|
||||
if (err != UC_ERR_OK) {
|
||||
printf(
|
||||
"[!] Error reading application name at address 0x%llx: "
|
||||
"%u\n",
|
||||
lpApplicationName + i, err);
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
buffer[i] = byte;
|
||||
i++;
|
||||
} while (buffer[i - 1] != 0 && i < MAX_PATH - 1);
|
||||
// 返回结果
|
||||
uint64_t result = success ? 1 : 0;
|
||||
uc_reg_write(uc,
|
||||
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||||
&result);
|
||||
}
|
||||
|
||||
// 确保字符串以 NULL 结尾
|
||||
buffer[i] = 0;
|
||||
// CreateProcessW的实现
|
||||
auto Api_CreateProcessW(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void {
|
||||
auto context = static_cast<Sandbox*>(sandbox);
|
||||
uint64_t lpApplicationName = 0;
|
||||
uint64_t lpCommandLine = 0;
|
||||
uint64_t lpProcessInformation = 0;
|
||||
uint64_t lpStartupInfo = 0;
|
||||
|
||||
if (success) {
|
||||
applicationName = std::string(buffer);
|
||||
printf("[*] Read ApplicationName: %s (Length: %zu)\n", buffer,
|
||||
applicationName.length());
|
||||
}
|
||||
// 获取参数
|
||||
if (context->GetPeInfo()->isX64) {
|
||||
// x64: rcx = lpApplicationName, rdx = lpCommandLine
|
||||
uc_reg_read(uc, UC_X86_REG_RCX, &lpApplicationName);
|
||||
uc_reg_read(uc, UC_X86_REG_RDX, &lpCommandLine);
|
||||
// 从栈上获取 PROCESS_INFORMATION 和 STARTUPINFO
|
||||
uint64_t rsp;
|
||||
uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
|
||||
rsp += 0x28; // 跳过前4个参数的影子空间
|
||||
uc_mem_read(uc, rsp + 0x20, &lpProcessInformation, sizeof(uint64_t));
|
||||
uc_mem_read(uc, rsp + 0x18, &lpStartupInfo, sizeof(uint64_t));
|
||||
|
||||
printf(
|
||||
"[*] CreateProcessW Debug (x64): AppNameAddr=0x%llx, "
|
||||
"CmdLineAddr=0x%llx\n",
|
||||
lpApplicationName, lpCommandLine);
|
||||
} else {
|
||||
// x86: 从栈上读取参数
|
||||
uint32_t esp;
|
||||
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
|
||||
esp += 0x4; // 跳过返回地址
|
||||
uint32_t temp_app_name, temp_cmd_line, temp_proc_info,
|
||||
temp_startup_info;
|
||||
uc_mem_read(uc, esp, &temp_app_name, sizeof(uint32_t));
|
||||
uc_mem_read(uc, esp + 0x4, &temp_cmd_line, sizeof(uint32_t));
|
||||
// 修正x86下的参数读取偏移,使用实际结构的偏移量
|
||||
uc_mem_read(uc, esp + 0x24, &temp_proc_info, sizeof(uint32_t));
|
||||
uc_mem_read(uc, esp + 0x1C, &temp_startup_info, sizeof(uint32_t));
|
||||
lpApplicationName = temp_app_name;
|
||||
lpCommandLine = temp_cmd_line;
|
||||
lpProcessInformation = temp_proc_info;
|
||||
lpStartupInfo = temp_startup_info;
|
||||
|
||||
printf(
|
||||
"[*] CreateProcessW Debug (x86): ESP=0x%x, AppNameAddr=0x%x, "
|
||||
"CmdLineAddr=0x%x\n",
|
||||
esp, temp_app_name, temp_cmd_line);
|
||||
}
|
||||
|
||||
// 读取命令行
|
||||
std::string commandLine;
|
||||
if (lpCommandLine != 0) {
|
||||
char buffer[MAX_PATH] = {0};
|
||||
size_t i = 0;
|
||||
bool success = true;
|
||||
// 调用内部函数处理共同逻辑
|
||||
bool success =
|
||||
CreateProcessInternal(sandbox, uc, lpApplicationName, lpCommandLine,
|
||||
lpProcessInformation, lpStartupInfo, true);
|
||||
|
||||
do {
|
||||
uint8_t byte;
|
||||
uc_err err = uc_mem_read(uc, lpCommandLine + i, &byte, 1);
|
||||
if (err != UC_ERR_OK) {
|
||||
printf("[!] Error reading command line at address 0x%llx: %u\n",
|
||||
lpCommandLine + i, err);
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
buffer[i] = byte;
|
||||
i++;
|
||||
} while (buffer[i - 1] != 0 && i < MAX_PATH - 1);
|
||||
|
||||
// 确保字符串以 NULL 结尾
|
||||
buffer[i] = 0;
|
||||
|
||||
if (success) {
|
||||
commandLine = std::string(buffer);
|
||||
printf("[*] Read CommandLine: %s (Length: %zu)\n", buffer,
|
||||
commandLine.length());
|
||||
}
|
||||
}
|
||||
|
||||
printf("[*] CreateProcessA: ApplicationName=%s, CommandLine=%s\n",
|
||||
applicationName.empty() ? "(null)" : applicationName.c_str(),
|
||||
commandLine.empty() ? "(null)" : commandLine.c_str());
|
||||
|
||||
// 模拟创建进程,设置进程和线程ID
|
||||
DWORD processId = 0x1234;
|
||||
DWORD threadId = 0x5678;
|
||||
HANDLE hProcess = (HANDLE)0x1340;
|
||||
HANDLE hThread = (HANDLE)0x1341;
|
||||
|
||||
// 写入进程信息
|
||||
if (lpProcessInformation != 0) {
|
||||
if (context->GetPeInfo()->isX64) {
|
||||
struct PROCESS_INFORMATION64 {
|
||||
HANDLE hProcess;
|
||||
HANDLE hThread;
|
||||
DWORD dwProcessId;
|
||||
DWORD dwThreadId;
|
||||
} pi;
|
||||
pi.hProcess = (HANDLE)hProcess;
|
||||
pi.hThread = (HANDLE)hThread;
|
||||
pi.dwProcessId = processId;
|
||||
pi.dwThreadId = threadId;
|
||||
uc_mem_write(uc, lpProcessInformation, &pi, sizeof(pi));
|
||||
printf("[*] Wrote process info (x64) to 0x%llx\n",
|
||||
lpProcessInformation);
|
||||
} else {
|
||||
PROCESS_INFORMATION pi;
|
||||
pi.hProcess = hProcess;
|
||||
pi.hThread = hThread;
|
||||
pi.dwProcessId = processId;
|
||||
pi.dwThreadId = threadId;
|
||||
uc_mem_write(uc, lpProcessInformation, &pi, sizeof(pi));
|
||||
printf("[*] Wrote process info (x86) to 0x%llx\n",
|
||||
lpProcessInformation);
|
||||
}
|
||||
}
|
||||
|
||||
// 返回成功
|
||||
uint64_t result = 1;
|
||||
// 返回结果
|
||||
uint64_t result = success ? 1 : 0;
|
||||
uc_reg_write(uc,
|
||||
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
|
||||
&result);
|
||||
|
||||
Reference in New Issue
Block a user