Files
awesome_anti_virus_engine/ai_anti_malware/sandbox_setupvm.cpp

277 lines
11 KiB
C++
Raw Normal View History

2025-04-23 03:48:16 +08:00
#include "sandbox.h"
auto Sandbox::BuildPebParameter() -> void {
//<2F><><EFBFBD><EFBFBD>peb->ProcessParameters
// <20><><EFBFBD>ý<EFBFBD><C3BD>̲<EFBFBD><CCB2><EFBFBD>
RTL_USER_PROCESS_PARAMETERS processParams = {};
// ӳ<><D3B3><EFBFBD><EFBFBD><EFBFBD>̲<EFBFBD><CCB2><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
size_t processParamsSize = AlignToSectionAlignment(sizeof(RTL_USER_PROCESS_PARAMETERS), PAGE_SIZE);
uc_err procErr = uc_mem_map(m_ucEngine, m_processParamsBase, processParamsSize,
UC_PROT_READ | UC_PROT_WRITE);
if (procErr != UC_ERR_OK) {
throw std::runtime_error("Failed to map process parameters block");
}
// <20><><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
processParams.MaximumLength = sizeof(RTL_USER_PROCESS_PARAMETERS);
processParams.Length = sizeof(RTL_USER_PROCESS_PARAMETERS);
// <20>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
uint64_t stringBufferBase = m_processParamsBase + processParamsSize;
uint64_t currentStringPos = stringBufferBase;
// ӳ<><D3B3><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
size_t stringBufferSize = AlignToSectionAlignment(4096, PAGE_SIZE); // <20><EFBFBD><E3B9BB><EFBFBD>Ŀռ<C4BF><D5BC><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
uc_mem_map(m_ucEngine, stringBufferBase, stringBufferSize, UC_PROT_READ | UC_PROT_WRITE);
// <20><><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3>·<EFBFBD><C2B7>
std::wstring imagePath = L"C:\\Path\\To\\EmulatedImage.exe";
UNICODE_STRING imagePathUnicode;
imagePathUnicode.Length = static_cast<USHORT>(imagePath.length() * sizeof(wchar_t));
imagePathUnicode.MaximumLength = imagePathUnicode.Length + sizeof(wchar_t); // <20><><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD><EFBFBD><EFBFBD>null<6C><6C>ֹ<EFBFBD><D6B9>
imagePathUnicode.Buffer = reinterpret_cast<PWSTR>(currentStringPos);
// д<><D0B4>ӳ<EFBFBD><D3B3>·<EFBFBD><C2B7><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
uc_mem_write(m_ucEngine, currentStringPos, imagePath.c_str(), imagePath.length() * sizeof(wchar_t) + sizeof(wchar_t));
currentStringPos += AlignToSectionAlignment(imagePathUnicode.MaximumLength, 8);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::wstring commandLine = L"EmulatedImage.exe argument1 argument2";
UNICODE_STRING commandLineUnicode;
commandLineUnicode.Length = static_cast<USHORT>(commandLine.length() * sizeof(wchar_t));
commandLineUnicode.MaximumLength = commandLineUnicode.Length + sizeof(wchar_t);
commandLineUnicode.Buffer = reinterpret_cast<PWSTR>(currentStringPos);
// д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
uc_mem_write(m_ucEngine, currentStringPos, commandLine.c_str(), commandLine.length() * sizeof(wchar_t) + sizeof(wchar_t));
currentStringPos += AlignToSectionAlignment(commandLineUnicode.MaximumLength, 8);
// <20><><EFBFBD>õ<EFBFBD>ǰĿ¼
std::wstring currentDir = L"C:\\Path\\To";
UNICODE_STRING currentDirUnicode;
currentDirUnicode.Length = static_cast<USHORT>(currentDir.length() * sizeof(wchar_t));
currentDirUnicode.MaximumLength = currentDirUnicode.Length + sizeof(wchar_t);
currentDirUnicode.Buffer = reinterpret_cast<PWSTR>(currentStringPos);
// д<>뵱ǰĿ¼<C4BF>ַ<EFBFBD><D6B7><EFBFBD>
uc_mem_write(m_ucEngine, currentStringPos, currentDir.c_str(), currentDir.length() * sizeof(wchar_t) + sizeof(wchar_t));
currentStringPos += AlignToSectionAlignment(currentDirUnicode.MaximumLength, 8);
// <20><><EFBFBD><EFBFBD>DLL·<4C><C2B7>
std::wstring dllPath = L"C:\\Windows\\System32";
UNICODE_STRING dllPathUnicode;
dllPathUnicode.Length = static_cast<USHORT>(dllPath.length() * sizeof(wchar_t));
dllPathUnicode.MaximumLength = dllPathUnicode.Length + sizeof(wchar_t);
dllPathUnicode.Buffer = reinterpret_cast<PWSTR>(currentStringPos);
// д<><D0B4>DLL·<4C><C2B7><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
uc_mem_write(m_ucEngine, currentStringPos, dllPath.c_str(), dllPath.length() * sizeof(wchar_t) + sizeof(wchar_t));
// <20><><EFBFBD>ý<EFBFBD><C3BD>̲<EFBFBD><CCB2><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><D0B5>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>ֶ<EFBFBD>
processParams.ImagePathName = imagePathUnicode;
processParams.CommandLine = commandLineUnicode;
processParams.CurrentDirectory.DosPath = currentDirUnicode;
processParams.DllPath = dllPathUnicode;
processParams.Environment = reinterpret_cast<WCHAR*>(m_envBlockBase);
// д<><D0B4><EFBFBD><EFBFBD><EFBFBD>̲<EFBFBD><CCB2><EFBFBD><EFBFBD>
uc_mem_write(m_ucEngine, m_processParamsBase, &processParams, sizeof(RTL_USER_PROCESS_PARAMETERS));
}
auto Sandbox::SetupVirtualMachine() -> void {
SegmentSelector cs = { 0 };
cs.fields.index = 1;
uc_reg_write(m_ucEngine, UC_X86_REG_CS, &cs.all);
SegmentSelector ds = { 0 };
ds.fields.index = 2;
uc_reg_write(m_ucEngine, UC_X86_REG_DS, &ds.all);
SegmentSelector ss = { 0 };
ss.fields.index = 2;
uc_reg_write(m_ucEngine, UC_X86_REG_SS, &ss.all);
SegmentSelector es = { 0 };
es.fields.index = 2;
uc_reg_write(m_ucEngine, UC_X86_REG_ES, &es.all);
SegmentSelector gs = { 0 };
gs.fields.index = 2;
uc_reg_write(m_ucEngine, UC_X86_REG_GS, &gs.all);
FlagRegister eflags = { 0 };
eflags.fields.id = 1;
eflags.fields.intf = 1;
eflags.fields.reserved1 = 1;
uc_reg_write(m_ucEngine, UC_X86_REG_EFLAGS, &eflags.all);
uint64_t cr8 = 0;
uc_reg_write(m_ucEngine, UC_X86_REG_CR8, &cr8);
/*
ӳ<EFBFBD><EFBFBD> m_KSharedUserDataBase
*/
m_KSharedUserDataBase = 0x7FFE0000;
uint64_t m_KSharedUserDataEnd = 0x7FFE0FFF; // 0x7FFE2000
m_KSharedUserDataSize = AlignToSectionAlignment(
m_KSharedUserDataEnd - m_KSharedUserDataBase, PAGE_SIZE);
uc_mem_map(m_ucEngine, m_KSharedUserDataBase, m_KSharedUserDataSize,
UC_PROT_READ);
uc_mem_write(m_ucEngine, m_KSharedUserDataBase,
(void*)m_KSharedUserDataBase, m_KSharedUserDataSize);
m_tebBase = TEB_BASE; // <20><><EFBFBD><EFBFBD>TEB<45><42>ַ
m_pebBase = PEB_BASE; // <20><><EFBFBD><EFBFBD>PEB<45><42>ַ
m_envBlockBase = ENV_BLOCK_BASE; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
m_processParamsBase = PROCESS_PARAMS_BASE; // <20><><EFBFBD>̲<EFBFBD><CCB2><EFBFBD><EFBFBD><EFBFBD>ַ
// stack
m_stackBase = AlignToSectionAlignment(
this->m_peInfo->isX64 ? STACK_BASE_64 : STACK_BASE_32, 16);
m_stackSize = AlignToSectionAlignment(
this->m_peInfo->isX64 ? STACK_SIZE_64 : STACK_SIZE_32, 16);
m_stackEnd = m_stackBase + m_stackSize;
// heap
m_heapBase = this->m_peInfo->isX64 ? HEAP_ADDRESS_64 : HEAP_ADDRESS_32;
m_heapSize = this->m_peInfo->isX64 ? HEAP_SIZE_64 : HEAP_SIZE_32;
m_heapEnd = m_heapBase + m_heapSize;
BuildPebParameter();
InitializeLdrData();
// <20><><EFBFBD><EFBFBD>PE<50>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>PEB<45><42>TEB
if (this->m_peInfo->isX64) {
// <20><><EFBFBD><EFBFBD>64λPEB
m_peb64.ImageBaseAddress = m_peInfo->RecImageBase;
m_pebEnd =
m_pebBase + AlignToSectionAlignment(sizeof(X64PEB), PAGE_SIZE);
m_tebEnd =
m_tebBase + AlignToSectionAlignment(sizeof(X64TEB), PAGE_SIZE);
// <20><><EFBFBD><EFBFBD>64λTEB
m_teb64.ClientId.UniqueProcess = GetCurrentProcessId();
m_teb64.ClientId.UniqueThread = GetCurrentThreadId();
m_teb64.ProcessEnvironmentBlock = reinterpret_cast<X64PEB*>(m_pebBase);
m_teb64.NtTib.StackBase = (DWORD64)m_stackBase;
m_teb64.NtTib.StackLimit = (DWORD64)m_stackSize;
m_peb64.ProcessParameters = m_processParamsBase;
// <20><><EFBFBD>ö<EFBFBD>
m_peb64.ProcessHeap = m_heapBase;
// <20><><EFBFBD><EFBFBD>GS<47><53>ַ<EFBFBD>
m_gsBaseStruct.teb = m_tebBase;
m_gsBaseStruct.peb = m_pebBase;
uint64_t gsAllocSize =
AlignToSectionAlignment(sizeof(struct_gs_base), PAGE_SIZE);
// ӳ<><D3B3>PEB<45><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
uc_mem_map(m_ucEngine, m_pebBase, m_pebEnd - m_pebBase,
UC_PROT_READ | UC_PROT_WRITE);
uc_mem_write(m_ucEngine, m_pebBase, &m_peb64, sizeof(X64PEB));
// ӳ<><D3B3>TEB<45><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
uc_mem_map(m_ucEngine, m_tebBase, m_tebEnd - m_tebBase,
UC_PROT_READ | UC_PROT_WRITE);
uc_mem_write(m_ucEngine, m_tebBase, &m_teb64, sizeof(X64TEB));
// ӳ<><D3B3>GS<47><53>ַ<EFBFBD><EFBFBD><E1B9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
uc_mem_map(m_ucEngine, m_gsBase, gsAllocSize, UC_PROT_READ);
uc_mem_write(m_ucEngine, m_gsBase, &m_gsBaseStruct,
sizeof(struct_gs_base));
// <20><><EFBFBD><EFBFBD>GS<47><53>ַMSR
uc_x86_msr msr;
msr.rid = static_cast<uint32_t>(Msr::kIa32GsBase);
msr.value = m_gsBase;
uc_reg_write(m_ucEngine, UC_X86_REG_MSR, &msr);
}
else {
// <20><><EFBFBD><EFBFBD>32λPEB
m_peb32.ImageBaseAddress = static_cast<ULONG>(m_peInfo->RecImageBase);
m_pebEnd =
m_pebBase + AlignToSectionAlignment(sizeof(X32PEB), PAGE_SIZE);
m_tebEnd =
m_tebBase + AlignToSectionAlignment(sizeof(X32TEB), PAGE_SIZE);
// <20><><EFBFBD><EFBFBD>32λTEB
m_teb32.ClientId.UniqueProcess = GetCurrentProcessId();
m_teb32.ClientId.UniqueThread = GetCurrentThreadId();
m_teb32.ProcessEnvironmentBlock = static_cast<ULONG>(m_pebBase);
m_teb32.NtTib.StackBase = static_cast<ULONG>(m_stackBase);
m_teb32.NtTib.StackLimit = static_cast<ULONG>(m_stackSize);
// <20><>ʼ<EFBFBD><CABC>NT_TIB<49><EFBFBD><E1B9B9><EFBFBD><EFBFBD><EFBFBD>ಿ<EFBFBD><E0B2BF>
m_teb32.NtTib.Self =
static_cast<ULONG>(m_tebBase); // <20>ؼ<EFBFBD><D8BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Selfָ<66><D6B8>ָ<EFBFBD><D6B8>TEB<45><42><EFBFBD><EFBFBD>
m_teb32.NtTib.ExceptionList = 0xFFFFFFFF; // <20><>ʼ<EFBFBD><EFBFBD><ECB3A3><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
m_teb32.NtTib.Version = 0;
m_teb32.NtTib.FiberData = 0;
m_teb32.NtTib.ArbitraryUserPointer = 0;
m_peb32.ProcessParameters = m_processParamsBase;
// <20><><EFBFBD>ö<EFBFBD>
m_peb32.ProcessHeap = static_cast<ULONG>(m_heapBase);
// ӳ<><D3B3>PEB<45><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
uc_mem_map(m_ucEngine, m_pebBase, m_pebEnd - m_pebBase,
UC_PROT_READ | UC_PROT_WRITE);
uc_mem_write(m_ucEngine, m_pebBase, &m_peb32, sizeof(X32PEB));
// ӳ<><D3B3>TEB<45><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
uc_mem_map(m_ucEngine, m_tebBase, m_tebEnd - m_tebBase,
UC_PROT_READ | UC_PROT_WRITE);
uc_mem_write(m_ucEngine, m_tebBase, &m_teb32, sizeof(X32TEB));
// <20><><EFBFBD><EFBFBD>32λ<32><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>FS<46>μĴ<CEBC><C4B4><EFBFBD>ָ<EFBFBD><D6B8>TEB
SegmentSelector fs = { 0 };
fs.fields.index = 3;
// <20><><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>present<6E><74>dpl<70><6C><EFBFBD><EFBFBD>ΪSegmentSelector<6F><EFBFBD><E1B9B9><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD>Щ<EFBFBD>ֶ<EFBFBD>
uc_reg_write(m_ucEngine, UC_X86_REG_FS, &fs.all);
// <20><><EFBFBD><EFBFBD>FS<46><53>ַMSR
uc_x86_msr msr;
msr.rid = static_cast<uint32_t>(Msr::kIa32FsBase);
msr.value = m_tebBase;
uc_reg_write(m_ucEngine, UC_X86_REG_MSR, &msr);
// ȷ<><C8B7>TEB<45>йؼ<D0B9><D8BC>ֶα<D6B6><CEB1><EFBFBD>ȷ<EFBFBD><C8B7>ʼ<EFBFBD><CABC>
// <20>ر<EFBFBD><D8B1><EFBFBD>FS:18h (0x18)<29><>Ӧ<EFBFBD><D3A6>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>Native_Struct.h<><68>X32TEB<45><42><EFBFBD>壬ƫ<E5A3AC><C6AB>0x18<31><38><EFBFBD><EFBFBD>SelfTeb
uint32_t self_teb_ptr = static_cast<uint32_t>(m_tebBase);
// <20><>NT_TIB<49><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SelfTeb (offset 0x18)
uc_mem_write(m_ucEngine, m_tebBase + 0x18, &self_teb_ptr,
sizeof(uint32_t));
// ȷ<><C8B7>TEB<45>е<EFBFBD>ProcessEnvironmentBlock<63>ֶ<EFBFBD>ָ<EFBFBD><D6B8>PEB
uint32_t peb_ptr = static_cast<uint32_t>(m_pebBase);
// ƫ<><C6AB>0x30<33><30><EFBFBD><EFBFBD>ProcessEnvironmentBlock
uc_mem_write(m_ucEngine, m_tebBase + 0x30, &peb_ptr, sizeof(uint32_t));
}
// ӳ<><D3B3><EFBFBD>µ<EFBFBD><C2B5>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD>
size_t envSize =
AlignToSectionAlignment(this->GetEnvStringsSize(), PAGE_SIZE);
printf("env block size: %llx\n", envSize); // <20><><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
uc_err envErr = uc_mem_map(m_ucEngine, m_envBlockBase, envSize,
UC_PROT_READ | UC_PROT_WRITE);
if (envErr != UC_ERR_OK) {
throw std::runtime_error("Failed to map environment block");
}
auto envData = this->GetEnvString();
envErr = uc_mem_write(m_ucEngine, m_envBlockBase, envData.data(),
envData.size() * sizeof(wchar_t));
if (envErr != UC_ERR_OK) {
throw std::runtime_error("Failed to write environment block");
}
for (DWORD i = 0; i < 64; i++) {
GetTeb64()->TlsSlots[i] = (void*)0x1337ffffff;
}
for (DWORD i = 0; i < 64; i++) {
GetTeb32()->TlsSlots[i] = 0x1337;
}
}