Files
awesome_anti_virus_engine/ai_anti_malware/sandbox_api_file.cpp
huoji 534b6a84a6 添加沙箱功能和API钩子支持
- 在沙箱中实现了新的功能,包括内存分配和API钩子初始化
- 更新了沙箱类,增加了对WFP引擎的支持
- 添加了多个API的实现,如GetLastError、InitializeCriticalSection等
- 修改了主函数以使用新的沙箱功能,替换了恶意软件扫描功能
- 更新了项目文件以包含新的源文件和API实现
- 改进了错误处理和日志记录功能
2025-03-18 20:49:18 +08:00

180 lines
6.9 KiB
C++

#include "sandbox.h"
#include "sandbox_callbacks.h"
#include "sandbox_api_winhttp.h"
#include <tlhelp32.h>
auto Api_ReadFile(void* sandbox, uc_engine* uc, uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t hFile = 0;
uint64_t lpBuffer = 0;
uint32_t nNumberOfBytesToRead = 0;
uint64_t lpNumberOfBytesRead = 0;
uint64_t lpOverlapped = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = hFile, rdx = lpBuffer, r8 = nNumberOfBytesToRead, r9 =
// lpNumberOfBytesRead
uc_reg_read(uc, UC_X86_REG_RCX, &hFile);
uc_reg_read(uc, UC_X86_REG_RDX, &lpBuffer);
uint64_t temp_bytes_to_read;
uc_reg_read(uc, UC_X86_REG_R8, &temp_bytes_to_read);
nNumberOfBytesToRead = static_cast<uint32_t>(temp_bytes_to_read);
uc_reg_read(uc, UC_X86_REG_R9, &lpNumberOfBytesRead);
// 从栈上读取lpOverlapped参数
uint64_t rsp;
uc_reg_read(uc, UC_X86_REG_RSP, &rsp);
uc_mem_read(uc, rsp + 0x28, &lpOverlapped, sizeof(uint64_t));
} else {
// x86: 从栈上读取参数
uint32_t esp;
uc_reg_read(uc, UC_X86_REG_ESP, &esp);
esp += 0x4; // 跳过返回地址
uint32_t temp_handle, temp_buffer, temp_bytes_read, temp_overlapped;
uc_mem_read(uc, esp, &temp_handle, sizeof(uint32_t));
uc_mem_read(uc, esp + 0x4, &temp_buffer, sizeof(uint32_t));
uc_mem_read(uc, esp + 0x8, &nNumberOfBytesToRead, sizeof(uint32_t));
uc_mem_read(uc, esp + 0xC, &temp_bytes_read, sizeof(uint32_t));
uc_mem_read(uc, esp + 0x10, &temp_overlapped, sizeof(uint32_t));
hFile = temp_handle;
lpBuffer = temp_buffer;
lpNumberOfBytesRead = temp_bytes_read;
lpOverlapped = temp_overlapped;
}
// 检查句柄是否为之前CreatePipe创建的读管道
bool success = false;
uint32_t bytesRead = 0;
// 检查是否为之前CreatePipe创建的读管道句柄 (0x1338)
if (hFile == 0x1338) {
// 模拟管道数据读取 - 这里我们可以根据之前的CreateProcessA来生成数据
// 生成一些模拟的ping命令输出数据
std::string pingOutput =
"Reply from 127.0.0.1: bytes=32 time<1ms TTL=45\r\n"
"Reply from 127.0.0.1: bytes=32 time<1ms TTL=45\r\n"
"Reply from 127.0.0.1: bytes=32 time<1ms TTL=45\r\n"
"Reply from 127.0.0.1: bytes=32 time<1ms TTL=45\r\n\r\n"
"Ping statistics for 127.0.0.1:\r\n"
" Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),\r\n"
"Approximate round trip times in milli-seconds:\r\n"
" Minimum = 0ms, Maximum = 0ms, Average = 0ms\r\n";
// 确保不超过缓冲区大小
bytesRead = min(static_cast<uint32_t>(pingOutput.length()),
nNumberOfBytesToRead);
// 写入数据到缓冲区
if (lpBuffer != 0 && bytesRead > 0) {
uc_mem_write(uc, lpBuffer, pingOutput.c_str(), bytesRead);
success = true;
}
}
// 写入实际读取的字节数
if (lpNumberOfBytesRead != 0) {
if (context->GetPeInfo()->isX64) {
uc_mem_write(uc, lpNumberOfBytesRead, &bytesRead, sizeof(uint32_t));
} else {
uc_mem_write(uc, lpNumberOfBytesRead, &bytesRead, sizeof(uint32_t));
}
}
printf(
"[*] ReadFile: Handle=0x%llx, Buffer=0x%llx, BytesToRead=%u, "
"BytesRead=%u, Success=%d\n",
hFile, lpBuffer, nNumberOfBytesToRead, bytesRead, success);
// 设置返回值
uint64_t result = success ? 1 : 0;
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
// 如果失败,设置错误码
if (!success) {
DWORD error = ERROR_INVALID_HANDLE;
if (context->GetPeInfo()->isX64) {
context->GetTeb64()->LastErrorValue = error;
} else {
context->GetTeb32()->LastErrorValue = error;
}
}
}
auto Api_CreatePipe(void* sandbox, uc_engine* uc, uint64_t address) -> void {
auto context = static_cast<Sandbox*>(sandbox);
uint64_t hReadPipe = 0;
uint64_t hWritePipe = 0;
uint64_t lpPipeAttributes = 0;
uint32_t nSize = 0;
// 获取参数
if (context->GetPeInfo()->isX64) {
// x64: rcx = hReadPipe, rdx = hWritePipe, r8 = lpPipeAttributes, r9 =
// nSize
uc_reg_read(uc, UC_X86_REG_RCX, &hReadPipe);
uc_reg_read(uc, UC_X86_REG_RDX, &hWritePipe);
uc_reg_read(uc, UC_X86_REG_R8, &lpPipeAttributes);
uint64_t temp_size;
uc_reg_read(uc, UC_X86_REG_R9, &temp_size);
nSize = static_cast<uint32_t>(temp_size);
} else {
// x86: 从栈上读取参数
uint32_t esp_address = 0;
uc_reg_read(uc, UC_X86_REG_ESP, &esp_address);
esp_address += 0x4; // 跳过返回地址
uint32_t temp_read_pipe;
uint32_t temp_write_pipe;
uint32_t temp_pipe_attributes;
uc_mem_read(uc, esp_address, &temp_read_pipe, sizeof(uint32_t));
uc_mem_read(uc, esp_address + 0x4, &temp_write_pipe, sizeof(uint32_t));
uc_mem_read(uc, esp_address + 0x8, &temp_pipe_attributes,
sizeof(uint32_t));
uc_mem_read(uc, esp_address + 0xC, &nSize, sizeof(uint32_t));
hReadPipe = temp_read_pipe;
hWritePipe = temp_write_pipe;
lpPipeAttributes = temp_pipe_attributes;
}
// 创建模拟的管道句柄
uint64_t read_handle = 0x1338; // 使用特殊值作为读取句柄
uint64_t write_handle = 0x1339; // 使用特殊值作为写入句柄
// 生成唯一的管道名称
char pipeName[MAX_PATH];
DWORD processId =
context->GetPeInfo()->isX64
? static_cast<DWORD>(context->GetTeb64()->ClientId.UniqueProcess)
: static_cast<DWORD>(context->GetTeb32()->ClientId.UniqueProcess);
snprintf(pipeName, sizeof(pipeName),
"\\\\.\\pipe\\sandbox_pipe_%lu_%llx_%llx", processId, read_handle,
write_handle);
// 写入句柄到输出参数
if (context->GetPeInfo()->isX64) {
uc_mem_write(uc, hReadPipe, &read_handle, sizeof(uint64_t));
uc_mem_write(uc, hWritePipe, &write_handle, sizeof(uint64_t));
} else {
uint32_t read_handle_32 = static_cast<uint32_t>(read_handle);
uint32_t write_handle_32 = static_cast<uint32_t>(write_handle);
uc_mem_write(uc, hReadPipe, &read_handle_32, sizeof(uint32_t));
uc_mem_write(uc, hWritePipe, &write_handle_32, sizeof(uint32_t));
}
// 设置返回值为TRUE
uint64_t result = 1;
uc_reg_write(uc,
context->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&result);
printf(
"[*] CreatePipe: Name=%s, ReadHandle=0x%llx, WriteHandle=0x%llx, "
"Size=%u\n",
pipeName, read_handle, write_handle, nSize);
}