按照样本优化了一下
This commit is contained in:
@@ -276,7 +276,7 @@ DetectEngineType DetectEngine::DetectMalware(std::string filePath) {
|
||||
if (peAnalyzer.AnalyzePe(peInfo)) {
|
||||
return DetectEngineType::kPeStruct;
|
||||
}
|
||||
|
||||
/*
|
||||
// 先机器学习引擎
|
||||
MachineLearning ml;
|
||||
double score = 1 - ml.PredictMalwareFromFile(filePath);
|
||||
@@ -286,11 +286,12 @@ DetectEngineType DetectEngine::DetectMalware(std::string filePath) {
|
||||
return DetectEngineType::kMachineLearning;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
// 再沙盒引擎
|
||||
Sandbox se;
|
||||
se.InitEnv(peInfo);
|
||||
se.Run();
|
||||
se.TestLdrListTraversal();
|
||||
se.Run(0x22A0);
|
||||
if (se.GetMalwareAnalysisType() == MalwareAnalysisType::kSuspicious ||
|
||||
se.GetMalwareAnalysisType() == MalwareAnalysisType::kMalware) {
|
||||
return DetectEngineType::kSandbox;
|
||||
@@ -375,7 +376,7 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
std::string filePath = argv[1];
|
||||
*/
|
||||
std::string filePath = "Z:\\malware";
|
||||
std::string filePath = "Z:\\123";
|
||||
DetectMalwareInDirectory(filePath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -191,6 +191,7 @@
|
||||
<ClCompile Include="sandbox_dump_pe.cpp" />
|
||||
<ClCompile Include="sandbox_ldr.cpp" />
|
||||
<ClCompile Include="sandbox_malware_check.cpp" />
|
||||
<ClCompile Include="sandbox_setupvm.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="head.h" />
|
||||
|
||||
@@ -168,6 +168,9 @@
|
||||
<ClCompile Include="sandbox_api_setmap.cpp">
|
||||
<Filter>源文件\sandbox</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sandbox_setupvm.cpp">
|
||||
<Filter>源文件\sandbox</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="head.h">
|
||||
|
||||
@@ -221,11 +221,27 @@ typedef struct _LDR_DATA_TABLE_ENTRY {
|
||||
};
|
||||
};
|
||||
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
|
||||
//0x18 bytes (sizeof)
|
||||
struct _CURDIR
|
||||
{
|
||||
struct _UNICODE_STRING DosPath; //0x0
|
||||
VOID* Handle; //0x10
|
||||
};
|
||||
typedef struct _RTL_USER_PROCESS_PARAMETERS {
|
||||
BYTE Reserved1[16];
|
||||
PVOID Reserved2[10];
|
||||
UNICODE_STRING ImagePathName;
|
||||
UNICODE_STRING CommandLine;
|
||||
ULONG MaximumLength; //0x0
|
||||
ULONG Length; //0x4
|
||||
ULONG Flags; //0x8
|
||||
ULONG DebugFlags; //0xc
|
||||
VOID* ConsoleHandle; //0x10
|
||||
ULONG ConsoleFlags; //0x18
|
||||
VOID* StandardInput; //0x20
|
||||
VOID* StandardOutput; //0x28
|
||||
VOID* StandardError; //0x30
|
||||
struct _CURDIR CurrentDirectory; //0x38
|
||||
struct _UNICODE_STRING DllPath; //0x50
|
||||
struct _UNICODE_STRING ImagePathName; //0x60
|
||||
struct _UNICODE_STRING CommandLine; //0x70
|
||||
VOID* Environment; //0x80
|
||||
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
|
||||
|
||||
typedef struct _BASE_RELOCATION_ENTRY {
|
||||
@@ -1019,7 +1035,7 @@ struct struct_handle_table {
|
||||
char name[MAX_PATH]; // 名称
|
||||
};
|
||||
struct struct_moudle {
|
||||
char name[MAX_PATH];
|
||||
std::string name;
|
||||
uint64_t entry;
|
||||
uint64_t base;
|
||||
uint64_t size;
|
||||
|
||||
@@ -111,7 +111,8 @@ public:
|
||||
// 遍历所有已加载的模块
|
||||
for (const auto& module : m_sandbox->m_moduleList) {
|
||||
// 检查模块名是否匹配
|
||||
if (_stricmp(module->name, lib_name) == 0) {
|
||||
|
||||
if (module->name == std::string(lib_name) == 0) {
|
||||
// 遍历该模块的导出函数
|
||||
for (const auto& exp : module->export_function) {
|
||||
// 检查函数名是否匹配
|
||||
@@ -144,7 +145,7 @@ public:
|
||||
}
|
||||
//序号导出,非常癌症的修复.
|
||||
|
||||
if (strcmp(module->name, lib_name) == 0) {
|
||||
if (std::string(lib_name) == module->name) {
|
||||
int ordinalNum = std::atoi(func_name);
|
||||
if (exp->ordinal == ordinalNum) {
|
||||
auto newBase = reinterpret_cast<FARPROC>(
|
||||
@@ -263,7 +264,7 @@ auto Sandbox::PushModuleToVM(const char* dllName, uint64_t moduleBase, uint64_t
|
||||
}
|
||||
}
|
||||
|
||||
auto Sandbox::CreateModuleInfo(const char* dllName, uint64_t moduleBase,
|
||||
auto Sandbox::CreateModuleInfo(std::string dllName, uint64_t moduleBase,
|
||||
uint64_t realModuleBase, uint64_t bufferAddress)
|
||||
-> std::shared_ptr<struct_moudle> {
|
||||
// 解析PE头
|
||||
@@ -283,9 +284,8 @@ auto Sandbox::CreateModuleInfo(const char* dllName, uint64_t moduleBase,
|
||||
reinterpret_cast<PUCHAR>(ntHeaders) + sizeof(ntHeaders->Signature) +
|
||||
sizeof(ntHeaders->FileHeader) +
|
||||
ntHeaders->FileHeader.SizeOfOptionalHeader);
|
||||
|
||||
struct_moudle newModule{};
|
||||
strncpy(newModule.name, dllName, strlen(dllName));
|
||||
newModule.name = dllName.c_str();
|
||||
newModule.base = moduleBase;
|
||||
newModule.real_base = realModuleBase;
|
||||
newModule.entry = ntHeaders->OptionalHeader.AddressOfEntryPoint;
|
||||
@@ -396,8 +396,16 @@ auto Sandbox::ResolveImportExports() -> void {
|
||||
}
|
||||
}
|
||||
auto Sandbox::mapSystemModuleToVmByName(std::string systemName) -> void {
|
||||
std::string tempMatchName = systemName;
|
||||
std::transform(tempMatchName.begin(), tempMatchName.end(), tempMatchName.begin(),
|
||||
[](unsigned char c) { return std::toupper(c); });
|
||||
|
||||
for (auto module : m_moduleList) {
|
||||
if (strcmp(module->name, systemName.c_str()) == 0) {
|
||||
std::string listModuleName = module->name;
|
||||
std::transform(listModuleName.begin(), listModuleName.end(), listModuleName.begin(),
|
||||
[](unsigned char c) { return std::toupper(c); });
|
||||
|
||||
if (tempMatchName == listModuleName) {
|
||||
if (LOG_LEVEL > 0) {
|
||||
printf("skip module name: %s (already loaded)\n", module->name);
|
||||
}
|
||||
@@ -428,8 +436,11 @@ auto Sandbox::mapSystemModuleToVmByName(std::string systemName) -> void {
|
||||
PushModuleToVM(systemName.c_str(), moduleBase, mappedPeSize);
|
||||
}
|
||||
auto Sandbox::processImportModule(const moudle_import* importModule) -> void {
|
||||
std::string impModule = importModule->dll_name;
|
||||
std::transform(impModule.begin(), impModule.end(), impModule.begin(),
|
||||
[](unsigned char c) { return std::toupper(c); });
|
||||
|
||||
mapSystemModuleToVmByName(importModule->dll_name);
|
||||
mapSystemModuleToVmByName(impModule);
|
||||
}
|
||||
auto Sandbox::ResoveImport() -> void {
|
||||
// 处理延迟导入
|
||||
@@ -453,194 +464,7 @@ auto Sandbox::ResoveImport() -> void {
|
||||
mapSystemModuleToVmByName(importModule->dll_name);
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
/*
|
||||
映射 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; // 进程TEB地址
|
||||
m_pebBase = PEB_BASE; // 进程PEB地址
|
||||
m_envBlockBase = ENV_BLOCK_BASE; // 环境变量块地址
|
||||
// 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;
|
||||
|
||||
// 根据PE文件类型设置PEB和TEB
|
||||
if (this->m_peInfo->isX64) {
|
||||
// 设置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);
|
||||
|
||||
// 设置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.ProcessHeap = m_heapBase;
|
||||
|
||||
// 设置GS基址结构
|
||||
m_gsBaseStruct.teb = m_tebBase;
|
||||
m_gsBaseStruct.peb = m_pebBase;
|
||||
uint64_t gsAllocSize =
|
||||
AlignToSectionAlignment(sizeof(struct_gs_base), PAGE_SIZE);
|
||||
|
||||
// 映射PEB到虚拟内存
|
||||
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));
|
||||
|
||||
// 映射TEB到虚拟内存
|
||||
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));
|
||||
|
||||
// 映射GS基址结构到虚拟内存
|
||||
uc_mem_map(m_ucEngine, m_gsBase, gsAllocSize, UC_PROT_READ);
|
||||
uc_mem_write(m_ucEngine, m_gsBase, &m_gsBaseStruct,
|
||||
sizeof(struct_gs_base));
|
||||
|
||||
// 设置GS基址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 {
|
||||
// 设置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);
|
||||
|
||||
// 设置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);
|
||||
// 初始化NT_TIB结构的其余部分
|
||||
m_teb32.NtTib.Self =
|
||||
static_cast<ULONG>(m_tebBase); // 关键:设置Self指针指向TEB本身
|
||||
m_teb32.NtTib.ExceptionList = 0xFFFFFFFF; // 初始异常链表指向特殊值
|
||||
m_teb32.NtTib.Version = 0;
|
||||
m_teb32.NtTib.FiberData = 0;
|
||||
m_teb32.NtTib.ArbitraryUserPointer = 0;
|
||||
|
||||
// 设置堆
|
||||
m_peb32.ProcessHeap = static_cast<ULONG>(m_heapBase);
|
||||
|
||||
// 映射PEB到虚拟内存
|
||||
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));
|
||||
|
||||
// 映射TEB到虚拟内存
|
||||
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));
|
||||
|
||||
// 对于32位,我们需要设置FS段寄存器指向TEB
|
||||
SegmentSelector fs = {0};
|
||||
fs.fields.index = 3;
|
||||
// 不需要设置present和dpl,因为SegmentSelector结构体中没有这些字段
|
||||
uc_reg_write(m_ucEngine, UC_X86_REG_FS, &fs.all);
|
||||
|
||||
// 设置FS基址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);
|
||||
|
||||
// 确保TEB中关键字段被正确初始化
|
||||
// 特别是FS:18h (0x18)处应该指向自身
|
||||
// 根据Native_Struct.h中X32TEB定义,偏移0x18处是SelfTeb
|
||||
uint32_t self_teb_ptr = static_cast<uint32_t>(m_tebBase);
|
||||
// 在NT_TIB中设置SelfTeb (offset 0x18)
|
||||
uc_mem_write(m_ucEngine, m_tebBase + 0x18, &self_teb_ptr,
|
||||
sizeof(uint32_t));
|
||||
|
||||
// 确保TEB中的ProcessEnvironmentBlock字段指向PEB
|
||||
uint32_t peb_ptr = static_cast<uint32_t>(m_pebBase);
|
||||
// 偏移0x30处是ProcessEnvironmentBlock
|
||||
uc_mem_write(m_ucEngine, m_tebBase + 0x30, &peb_ptr, sizeof(uint32_t));
|
||||
}
|
||||
// 映射新的内存区域
|
||||
size_t envSize =
|
||||
AlignToSectionAlignment(this->GetEnvStringsSize(), PAGE_SIZE);
|
||||
printf("env block size: %llx\n", envSize); // 添加调试输出
|
||||
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;
|
||||
}
|
||||
}
|
||||
/*
|
||||
// 在InitEnv函数之前添加这个函数
|
||||
void Sandbox::RegisterComApis() {
|
||||
@@ -672,10 +496,13 @@ auto Sandbox::InitEnv(std::shared_ptr<BasicPeInfo> peInfo) -> void {
|
||||
cs_close(&m_csHandle); // 清理已分配的capstone资源
|
||||
throw std::runtime_error("Failed to initialize Unicorn");
|
||||
}
|
||||
SetupVirtualMachine();
|
||||
|
||||
// 一定要确保他是第一个.
|
||||
auto newModule = CreateModuleInfo(
|
||||
"huoji.exe", m_peInfo->RecImageBase, m_peInfo->RecImageBase,
|
||||
reinterpret_cast<uint64_t>(m_peInfo->peBuffer));
|
||||
|
||||
_ASSERTE(m_moduleList.size() == 0);
|
||||
m_moduleList.push_back(newModule);
|
||||
|
||||
@@ -692,7 +519,35 @@ auto Sandbox::InitEnv(std::shared_ptr<BasicPeInfo> peInfo) -> void {
|
||||
if (!peconv::load_imports(m_peInfo->peBuffer, &importFixer)) {
|
||||
throw std::runtime_error("Failed to fix imports");
|
||||
}
|
||||
//检查有没有ntdll
|
||||
bool isFoundNtdll = false;
|
||||
bool isFoundKernelBase = false;
|
||||
|
||||
for (const auto& module : this->GetModuleList()) {
|
||||
//我tm也不知道为什么 有些病毒这玩意找小写....然后kernel32.dll找大写.wtf is that?
|
||||
if (module->name == "ntdll.dll") {
|
||||
isFoundNtdll = true;
|
||||
}
|
||||
//真的很懒了,这个是按TAB一键出来的
|
||||
if (module->name == "KERNELBASE.dll") {
|
||||
isFoundKernelBase = true;
|
||||
}
|
||||
if (isFoundKernelBase && isFoundNtdll) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isFoundNtdll == false) {
|
||||
if (LOG_LEVEL > 4) {
|
||||
printf("Not ntdll.dll Found, manual map it \n");
|
||||
}
|
||||
mapSystemModuleToVmByName("ntdll.dll");
|
||||
}
|
||||
if (isFoundKernelBase == false) {
|
||||
if (LOG_LEVEL > 4) {
|
||||
printf("Not kernelbase.dll Found, manual map it \n");
|
||||
}
|
||||
mapSystemModuleToVmByName("kernelbase.dll");
|
||||
}
|
||||
// 给所有导入表加c3
|
||||
for (const auto& module : this->GetModuleList()) {
|
||||
// 遍历导出函数查找对应名称
|
||||
@@ -710,7 +565,6 @@ auto Sandbox::InitEnv(std::shared_ptr<BasicPeInfo> peInfo) -> void {
|
||||
m_peInfo->peSize);
|
||||
printf("map file to vm file: %llx\n", m_peInfo->RecImageBase);
|
||||
printf("map file to vm size: %llx\n", m_peInfo->peSize);
|
||||
SetupVirtualMachine();
|
||||
InitCommandLine(peInfo->inputFilePath);
|
||||
}
|
||||
|
||||
@@ -811,7 +665,8 @@ auto Sandbox::Run(uint64_t address) -> void {
|
||||
|
||||
std::cout << "Starting execution at " << std::hex << entryPoint
|
||||
<< std::endl;
|
||||
uint64_t timeout = 2 * 60 * 1000 * 1000;
|
||||
//uint64_t timeout = 2 * 60 * 1000 * 1000;
|
||||
uint64_t timeout = 0;
|
||||
// 1.入口点是必须跑的
|
||||
if (m_peInfo->isDll) {
|
||||
// 给rcx和rdx设置dll应该设置的
|
||||
@@ -853,7 +708,7 @@ auto Sandbox::Run(uint64_t address) -> void {
|
||||
std::cerr << "Entry Point Emulation error: " << uc_strerror(err)
|
||||
<< std::endl;
|
||||
if (address != 0) {
|
||||
err = uc_emu_start(m_ucEngine, address, m_peInfo->imageEnd, timeout, 0);
|
||||
err = uc_emu_start(m_ucEngine, address + MAIN_MODULE_BASE, m_peInfo->imageEnd, timeout, 0);
|
||||
std::cerr << "Custom Emulation error: " << uc_strerror(err)
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define TEB_BASE 0x90000
|
||||
#define CMDLINE_ADDRESS 0x100000 // 命令行字符串的固定地址
|
||||
#define CMDLINEW_ADDRESS 0x110000 // 宽字符命令行字符串的固定地址
|
||||
#define PROCESS_PARAMS_BASE 0x120000 // 进程参数结构的基址
|
||||
|
||||
#define X86_GDT_ADDR 0x30000
|
||||
#define X86_GDT_LIMIT 0x1000
|
||||
@@ -244,6 +245,7 @@ class Sandbox {
|
||||
-> void {
|
||||
m_lastImpRead = {address, imp};
|
||||
}
|
||||
auto TestLdrListTraversal() -> bool;
|
||||
|
||||
// 注册COM相关API
|
||||
void RegisterComApis();
|
||||
@@ -266,6 +268,7 @@ class Sandbox {
|
||||
uint64_t m_heapEnd;
|
||||
uint64_t m_fakeBase;
|
||||
uint64_t m_envBlockBase;
|
||||
uint64_t m_processParamsBase;
|
||||
struct_gs_base m_gsBaseStruct = {0};
|
||||
X64TEB m_teb64 = {0};
|
||||
X64PEB m_peb64 = {0};
|
||||
@@ -307,8 +310,9 @@ class Sandbox {
|
||||
L"USERPROFILE=C:\\Users\\huoji",
|
||||
L"windir=C:\\Windows"};
|
||||
auto ResoveImport() -> void;
|
||||
auto BuildPebParameter() -> void;
|
||||
auto ResolveImportExports() -> void;
|
||||
auto CreateModuleInfo(const char* dllName, uint64_t moduleBase,
|
||||
auto CreateModuleInfo(std::string dllName, uint64_t moduleBase,
|
||||
uint64_t realModuleBase, uint64_t bufferAddress)
|
||||
-> std::shared_ptr<struct_moudle>;
|
||||
auto ResolveExport(uint64_t moduleBase)
|
||||
@@ -333,6 +337,9 @@ class Sandbox {
|
||||
// 将模块添加到LDR链表中
|
||||
auto AddModuleToLdr(const std::shared_ptr<struct_moudle>& module) -> void;
|
||||
|
||||
|
||||
auto DumpLdrList(const char* listName, uint64_t ldrDataBase, size_t listOffset, size_t entryLinkOffset) -> void;
|
||||
|
||||
// 创建LDR_DATA_TABLE_ENTRY结构
|
||||
auto CreateLdrEntry(const std::shared_ptr<struct_moudle>& module,
|
||||
uint64_t entryAddress, uint64_t fullNameAddress,
|
||||
|
||||
@@ -113,7 +113,7 @@ auto Api_LoadLibraryA(void* sandbox, uc_engine* uc, uint64_t address) -> void {
|
||||
|
||||
// 从模块列表中查找对应模块
|
||||
for (const auto& module : context->GetModuleList()) {
|
||||
if (_stricmp((*module).name, module_name.c_str()) == 0) {
|
||||
if ((*module).name == module_name.c_str()) {
|
||||
return_address = (*module).base;
|
||||
break;
|
||||
}
|
||||
@@ -183,7 +183,7 @@ auto Api_LoadLibraryExW(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
|
||||
// 从模块列表中查找对应模块
|
||||
for (const auto& module : context->GetModuleList()) {
|
||||
if (_stricmp((*module).name, ansi_name.c_str()) == 0) {
|
||||
if ((*module).name == ansi_name.c_str()) {
|
||||
return_address = (*module).base;
|
||||
break;
|
||||
}
|
||||
@@ -240,19 +240,21 @@ auto Api_GetProcAddress(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
functionName[i] = byte;
|
||||
i++;
|
||||
} while (functionName[i - 1] != 0 && i < sizeof(functionName));
|
||||
context->CheckMalwareActive_GetProcAddress(functionName);
|
||||
std::string fnName = functionName;
|
||||
|
||||
context->CheckMalwareActive_GetProcAddress(fnName);
|
||||
if (fnName == "FlsGetValue2") {
|
||||
fnName = "FlsGetValue";
|
||||
}
|
||||
// 在模块列表中查找对应模块
|
||||
for (const auto& module : context->GetModuleList()) {
|
||||
if (module->base == moduleHandle) {
|
||||
// 遍历导出函数查找对应名称
|
||||
for (const auto& exp : module->export_function) {
|
||||
// 使用 _stricmp 进行大小写不敏感的比较
|
||||
if (_stricmp(exp->name, functionName) == 0) {
|
||||
return_address = module->base + exp->function_address;
|
||||
break;
|
||||
}
|
||||
// 遍历导出函数查找对应名称
|
||||
for (const auto& exp : module->export_function) {
|
||||
// 使用 _stricmp 进行大小写不敏感的比较
|
||||
if (_stricmp(exp->name, fnName.c_str()) == 0) {
|
||||
return_address = module->base + exp->function_address;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -923,7 +925,7 @@ auto Api_CreateDirectoryW(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
auto Api_GetStringTypeW(void* sandbox, uc_engine* uc, uint64_t address)
|
||||
-> void {
|
||||
auto context = static_cast<Sandbox*>(sandbox);
|
||||
uint32_t dwInfoType = 0;
|
||||
uint64_t dwInfoType = 0;
|
||||
uint64_t lpSrcStr = 0;
|
||||
int32_t cchSrc = 0;
|
||||
uint64_t lpCharType = 0;
|
||||
|
||||
@@ -51,7 +51,17 @@ void handleCodeRun(uc_engine* uc, uint64_t address, uint32_t size,
|
||||
// 记录跨区段执行地址
|
||||
sandbox->SetCrossSectionExecution(address);
|
||||
}
|
||||
|
||||
if (address == 0xff1160) {
|
||||
uint64_t rcx = 0;
|
||||
uc_reg_read(uc, UC_X86_REG_RCX, &rcx);
|
||||
printf("malware try find hash: %llx \n", rcx);
|
||||
}
|
||||
/*
|
||||
if (address == 0xff12B7) {
|
||||
sandboxCallbacks::dumpVmenv(uc, userData);
|
||||
__debugbreak();
|
||||
}
|
||||
*/
|
||||
// 更新上次执行的区段
|
||||
if (currentSectionIndex >= 0) {
|
||||
sandbox->SetLastExecuteSectionIndex(currentSectionIndex);
|
||||
@@ -120,8 +130,8 @@ void handleMemoryRead(uc_engine* uc, uc_mem_type type, uint64_t address,
|
||||
address < (ldrAddress + sizeof(X64_PEB_LDR_DATA))) {
|
||||
printf(
|
||||
"[WARNING] Suspicious direct LDR access detected at RIP: "
|
||||
"0x%llx, accessing address: 0x%llx\n",
|
||||
regRip, address);
|
||||
"0x%llx, accessing address: 0x%llx accessing offset: 0x%llx\n",
|
||||
regRip, address, address - ldrAddress);
|
||||
sandbox->SetMalwareAnalysisType(MalwareAnalysisType::kSuspicious);
|
||||
}
|
||||
} else {
|
||||
@@ -170,6 +180,8 @@ void dumpVmenv(uc_engine* uc, void* userData) {
|
||||
uint64_t Rdx = 0;
|
||||
uint64_t Eax = 0;
|
||||
uint64_t Ecx = 0;
|
||||
uint64_t R15 = 0;
|
||||
|
||||
uc_reg_read(uc,
|
||||
sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RIP : UC_X86_REG_EIP,
|
||||
&Rip);
|
||||
@@ -188,16 +200,15 @@ void dumpVmenv(uc_engine* uc, void* userData) {
|
||||
uc_reg_read(uc,
|
||||
sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RDX : UC_X86_REG_EDX,
|
||||
&Rdx);
|
||||
uc_reg_read(uc,
|
||||
sandbox->GetPeInfo()->isX64 ? UC_X86_REG_EAX : UC_X86_REG_EAX,
|
||||
&Eax);
|
||||
uc_reg_read(uc, UC_X86_REG_EAX, &Eax);
|
||||
uc_reg_read(uc,
|
||||
sandbox->GetPeInfo()->isX64 ? UC_X86_REG_ECX : UC_X86_REG_ECX,
|
||||
&Ecx);
|
||||
uc_reg_read(uc, UC_X86_REG_R15D, &R15);
|
||||
printf(
|
||||
"[dumpVmenv] Rip: %p lastRip: %p Rax: %p Rsp: %p Rbp: %p Rcx: %p Rdx: %p Eax: "
|
||||
"%08x Ecx: %08x\n",
|
||||
Rip, Rax, Rsp, Rbp, Rcx, Rdx, Eax, Ecx);
|
||||
"[dumpVmenv] Rip: %p Rax: %p Rsp: %p Rbp: %p Rcx: %p Rdx: %p Eax: "
|
||||
"%08x Ecx: %llx R15D: %llx\n",
|
||||
Rip, Rax, Rsp, Rbp, Rcx, Rdx, Eax, Ecx, R15);
|
||||
|
||||
// 打印32层栈内存
|
||||
printf("\n[Stack Memory Dump (32 levels)]\n");
|
||||
|
||||
@@ -4,7 +4,7 @@ auto Sandbox::DumpPE() -> std::pair<std::unique_ptr<BYTE[]>, size_t> {
|
||||
// <20><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF>ģ<EFBFBD><C4A3> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>(ͨ<><CDA8><EFBFBD>DZ<EFBFBD><C7B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD>ִ<EFBFBD><D6B4><EFBFBD>ļ<EFBFBD>)
|
||||
std::shared_ptr<struct_moudle> targetModule = nullptr;
|
||||
for (const auto& module : m_moduleList) {
|
||||
if (strcmp(module->name, "huoji.exe") == 0) {
|
||||
if ((*module).name == "HUOJI.EXE") {
|
||||
targetModule = module;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
|
||||
auto Sandbox::InitializeLdrData() -> void {
|
||||
if (m_peInfo->isX64 && m_peb64.Ldr == 0) {
|
||||
if (m_peInfo->isX64) {
|
||||
// ΪLDR_DATA<54><41><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
|
||||
uint64_t ldrDataAddress = m_pebBase + sizeof(X64PEB);
|
||||
m_pebEnd = ldrDataAddress + sizeof(X64_PEB_LDR_DATA);
|
||||
@@ -17,148 +17,393 @@ auto Sandbox::InitializeLdrData() -> void {
|
||||
ldrData.Length = sizeof(X64_PEB_LDR_DATA);
|
||||
ldrData.Initialized = 1;
|
||||
|
||||
// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ - ʹ<EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD>
|
||||
LIST_ENTRY inLoadOrderList = {
|
||||
reinterpret_cast<LIST_ENTRY*>(
|
||||
ldrDataAddress +
|
||||
offsetof(X64_PEB_LDR_DATA, InLoadOrderModuleList)),
|
||||
reinterpret_cast<LIST_ENTRY*>(
|
||||
ldrDataAddress +
|
||||
offsetof(X64_PEB_LDR_DATA, InLoadOrderModuleList)) };
|
||||
ldrData.InLoadOrderModuleList = inLoadOrderList;
|
||||
// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ - ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD>(<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||||
uint64_t inLoadOrderListHead = ldrDataAddress + offsetof(X64_PEB_LDR_DATA, InLoadOrderModuleList);
|
||||
uint64_t inMemoryOrderListHead = ldrDataAddress + offsetof(X64_PEB_LDR_DATA, InMemoryOrderModuleList);
|
||||
uint64_t inInitOrderListHead = ldrDataAddress + offsetof(X64_PEB_LDR_DATA, InInitializationOrderModuleList);
|
||||
|
||||
LIST_ENTRY inMemoryOrderList = {
|
||||
reinterpret_cast<LIST_ENTRY*>(
|
||||
ldrDataAddress +
|
||||
offsetof(X64_PEB_LDR_DATA, InMemoryOrderModuleList)),
|
||||
reinterpret_cast<LIST_ENTRY*>(
|
||||
ldrDataAddress +
|
||||
offsetof(X64_PEB_LDR_DATA, InMemoryOrderModuleList)) };
|
||||
ldrData.InMemoryOrderModuleList = inMemoryOrderList;
|
||||
// <20><><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>Flink<6E><6B>Blink<6E><6B>ָ<EFBFBD><D6B8><EFBFBD>Լ<EFBFBD>
|
||||
ldrData.InLoadOrderModuleList.Flink = (LIST_ENTRY*)inLoadOrderListHead;
|
||||
ldrData.InLoadOrderModuleList.Blink = (LIST_ENTRY*)inLoadOrderListHead;
|
||||
|
||||
LIST_ENTRY inInitOrderList = {
|
||||
reinterpret_cast<LIST_ENTRY*>(
|
||||
ldrDataAddress +
|
||||
offsetof(X64_PEB_LDR_DATA, InInitializationOrderModuleList)),
|
||||
reinterpret_cast<LIST_ENTRY*>(
|
||||
ldrDataAddress +
|
||||
offsetof(X64_PEB_LDR_DATA, InInitializationOrderModuleList)) };
|
||||
ldrData.InInitializationOrderModuleList = inInitOrderList;
|
||||
ldrData.InMemoryOrderModuleList.Flink = (LIST_ENTRY*)inMemoryOrderListHead;
|
||||
ldrData.InMemoryOrderModuleList.Blink = (LIST_ENTRY*)inMemoryOrderListHead;
|
||||
|
||||
uc_mem_write(m_ucEngine, ldrDataAddress, &ldrData,
|
||||
sizeof(X64_PEB_LDR_DATA));
|
||||
ldrData.InInitializationOrderModuleList.Flink = (LIST_ENTRY*)inInitOrderListHead;
|
||||
ldrData.InInitializationOrderModuleList.Blink = (LIST_ENTRY*)inInitOrderListHead;
|
||||
|
||||
// д<><D0B4>LDR_DATA<54>ṹ<EFBFBD><E1B9B9><EFBFBD>ڴ<EFBFBD>
|
||||
uc_mem_write(m_ucEngine, ldrDataAddress, &ldrData, sizeof(X64_PEB_LDR_DATA));
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>PEB<45>е<EFBFBD>Ldrָ<72><D6B8>
|
||||
uc_mem_write(m_ucEngine, m_pebBase, &m_peb64, sizeof(X64PEB));
|
||||
}
|
||||
}
|
||||
|
||||
auto Sandbox::CreateLdrEntry(const std::shared_ptr<struct_moudle>& module,
|
||||
uint64_t entryAddress, uint64_t fullNameAddress,
|
||||
uint64_t baseNameAddress) -> LDR_DATA_TABLE_ENTRY {
|
||||
LDR_DATA_TABLE_ENTRY entry = { 0 };
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ṹ<EFBFBD><E1B9B9><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD><D6B6><EFBFBD>ȷ<EFBFBD><C8B7>ʼ<EFBFBD><CABC>
|
||||
LDR_DATA_TABLE_ENTRY entry = {};
|
||||
if (LOG_LEVEL > 4) {
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD>ַ - <20><><EFBFBD><EFBFBD>nullָ<6C><D6B8>
|
||||
if (module->base == 0) {
|
||||
printf("<EFBFBD><EFBFBD><EFBFBD>棺ģ<EFBFBD><EFBFBD>'%s'<27>Ļ<EFBFBD>ַΪ0<CEAA><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܵ<EFBFBD><DCB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n", module->name);
|
||||
}
|
||||
}
|
||||
|
||||
entry.DllBase = reinterpret_cast<PVOID>(module->base);
|
||||
entry.EntryPoint = reinterpret_cast<PVOID>(module->base + module->entry);
|
||||
entry.SizeOfImages = static_cast<ULONG>(module->size);
|
||||
|
||||
// <><D7BC>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>Unicode<64>ַ<EFBFBD><D6B7><EFBFBD>
|
||||
wchar_t nameBuffer[MAX_PATH] = { 0 };
|
||||
std::mbstowcs(nameBuffer, module->name, strlen(module->name));
|
||||
size_t convertedChars = 0;
|
||||
std::string fakeFullName = "c:\\windows\\system32\\" + std::string(module->name);
|
||||
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ·<EFBFBD><EFBFBD>
|
||||
entry.FullDllName.Length =
|
||||
static_cast<USHORT>(wcslen(nameBuffer) * sizeof(wchar_t));
|
||||
// ʹ<EFBFBD>ø<EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><EFBFBD>mbstowcs_s<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
mbstowcs_s(&convertedChars, nameBuffer, MAX_PATH, fakeFullName.c_str(), fakeFullName.size());
|
||||
|
||||
// <20><>֤ת<D6A4><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
size_t nameLen = wcslen(nameBuffer);
|
||||
if (LOG_LEVEL > 4) {
|
||||
|
||||
if (nameLen == 0 || nameLen >= MAX_PATH) {
|
||||
printf("<EFBFBD><EFBFBD><EFBFBD>棺ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>'%s'ת<><D7AA><EFBFBD><EFBFBD><EFBFBD>⣬<EFBFBD><E2A3AC><EFBFBD><EFBFBD>=%zu\n", module->name, nameLen);
|
||||
}
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
|
||||
entry.FullDllName.Length = static_cast<USHORT>(nameLen * sizeof(wchar_t));
|
||||
entry.FullDllName.MaximumLength = MAX_PATH * sizeof(wchar_t);
|
||||
entry.FullDllName.Buffer = reinterpret_cast<PWSTR>(fullNameAddress);
|
||||
|
||||
// <20><><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
entry.BaseDllName.Length =
|
||||
static_cast<USHORT>(wcslen(nameBuffer) * sizeof(wchar_t));
|
||||
entry.BaseDllName.Length = static_cast<USHORT>(nameLen * sizeof(wchar_t));
|
||||
entry.BaseDllName.MaximumLength = MAX_PATH * sizeof(wchar_t);
|
||||
entry.BaseDllName.Buffer = reinterpret_cast<PWSTR>(baseNameAddress);
|
||||
if (LOG_LEVEL > 4) {
|
||||
// д<><D0B4><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
printf("DEBUG: д<><D0B4>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD> '%s' <20><><EFBFBD><EFBFBD>ַ 0x%llx <20><> 0x%llx\n",
|
||||
module->name, fullNameAddress, baseNameAddress);
|
||||
}
|
||||
uc_mem_write(m_ucEngine, fullNameAddress, nameBuffer, (nameLen + 1) * sizeof(wchar_t));
|
||||
uc_mem_write(m_ucEngine, baseNameAddress, nameBuffer, (nameLen + 1) * sizeof(wchar_t));
|
||||
|
||||
// д<EFBFBD><EFBFBD>Unicode<EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD>
|
||||
uc_mem_write(m_ucEngine, fullNameAddress, nameBuffer,
|
||||
(wcslen(nameBuffer) + 1) * sizeof(wchar_t));
|
||||
uc_mem_write(m_ucEngine, baseNameAddress, nameBuffer,
|
||||
(wcslen(nameBuffer) + 1) * sizeof(wchar_t));
|
||||
// <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>ΪNULL<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>UpdateLdrLinks<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>
|
||||
entry.InLoadOrderLinks.Flink = nullptr;
|
||||
entry.InLoadOrderLinks.Blink = nullptr;
|
||||
entry.InMemoryOrderLinks.Flink = nullptr;
|
||||
entry.InMemoryOrderLinks.Blink = nullptr;
|
||||
entry.InInitializationOrderLinks.Flink = nullptr;
|
||||
entry.InInitializationOrderLinks.Blink = nullptr;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
auto Sandbox::UpdateLdrLinks(const LDR_DATA_TABLE_ENTRY& entry,
|
||||
uint64_t entryAddress, X64_PEB_LDR_DATA& ldrData)
|
||||
-> void {
|
||||
// <20><><EFBFBD><EFBFBD>LDR_DATA<54>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>ͷ
|
||||
ldrData.InLoadOrderModuleList.Flink = reinterpret_cast<LIST_ENTRY*>(
|
||||
entryAddress + offsetof(LDR_DATA_TABLE_ENTRY, InLoadOrderLinks));
|
||||
ldrData.InMemoryOrderModuleList.Flink = reinterpret_cast<LIST_ENTRY*>(
|
||||
entryAddress + offsetof(LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks));
|
||||
ldrData.InInitializationOrderModuleList.Flink =
|
||||
reinterpret_cast<LIST_ENTRY*>(
|
||||
entryAddress +
|
||||
offsetof(LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks));
|
||||
uint64_t entryAddress, X64_PEB_LDR_DATA& ldrData) -> void {
|
||||
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>ַ
|
||||
uint64_t inLoadOrderListHead = m_peb64.Ldr + offsetof(X64_PEB_LDR_DATA, InLoadOrderModuleList);
|
||||
uint64_t inMemoryOrderListHead = m_peb64.Ldr + offsetof(X64_PEB_LDR_DATA, InMemoryOrderModuleList);
|
||||
uint64_t inInitOrderListHead = m_peb64.Ldr + offsetof(X64_PEB_LDR_DATA, InInitializationOrderModuleList);
|
||||
|
||||
// д<EFBFBD>ظ<EFBFBD><EFBFBD>º<EFBFBD><EFBFBD><EFBFBD>LDR_DATA
|
||||
uc_mem_write(m_ucEngine, m_peb64.Ldr, &ldrData, sizeof(X64_PEB_LDR_DATA));
|
||||
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>еĵ<EFBFBD>ַ
|
||||
uint64_t entryInLoadOrder = entryAddress + offsetof(LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
|
||||
uint64_t entryInMemoryOrder = entryAddress + offsetof(LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
|
||||
uint64_t entryInInitOrder = entryAddress + offsetof(LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
|
||||
|
||||
LIST_ENTRY listHead;
|
||||
LIST_ENTRY entryLinks;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>InLoadOrderModuleList
|
||||
uc_mem_read(m_ucEngine, inLoadOrderListHead, &listHead, sizeof(LIST_ENTRY));
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD>뵽<EFBFBD><EBB5BD><EFBFBD><EFBFBD>ͷ֮<CDB7><D6AE>)
|
||||
entryLinks.Flink = listHead.Flink; // <20><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF>Flink = ԭ<><D4AD>ͷ<EFBFBD><CDB7>Flink
|
||||
entryLinks.Blink = (LIST_ENTRY*)inLoadOrderListHead; // <20><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF>Blink = ͷ
|
||||
uc_mem_write(m_ucEngine, entryInLoadOrder, &entryLinks, sizeof(LIST_ENTRY));
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>Flinkָ<6B><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||
listHead.Flink = (LIST_ENTRY*)entryInLoadOrder;
|
||||
uc_mem_write(m_ucEngine, inLoadOrderListHead, &listHead, sizeof(LIST_ENTRY));
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><C7BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>Blink
|
||||
if (entryLinks.Flink != (LIST_ENTRY*)inLoadOrderListHead) {
|
||||
LIST_ENTRY nextEntry;
|
||||
uc_mem_read(m_ucEngine, (uint64_t)entryLinks.Flink, &nextEntry, sizeof(LIST_ENTRY));
|
||||
nextEntry.Blink = (LIST_ENTRY*)entryInLoadOrder;
|
||||
uc_mem_write(m_ucEngine, (uint64_t)entryLinks.Flink, &nextEntry, sizeof(LIST_ENTRY));
|
||||
}
|
||||
|
||||
// ͬ<><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>InMemoryOrderModuleList
|
||||
uc_mem_read(m_ucEngine, inMemoryOrderListHead, &listHead, sizeof(LIST_ENTRY));
|
||||
entryLinks.Flink = listHead.Flink;
|
||||
entryLinks.Blink = (LIST_ENTRY*)inMemoryOrderListHead;
|
||||
uc_mem_write(m_ucEngine, entryInMemoryOrder, &entryLinks, sizeof(LIST_ENTRY));
|
||||
listHead.Flink = (LIST_ENTRY*)entryInMemoryOrder;
|
||||
uc_mem_write(m_ucEngine, inMemoryOrderListHead, &listHead, sizeof(LIST_ENTRY));
|
||||
if (entryLinks.Flink != (LIST_ENTRY*)inMemoryOrderListHead) {
|
||||
LIST_ENTRY nextEntry;
|
||||
uc_mem_read(m_ucEngine, (uint64_t)entryLinks.Flink, &nextEntry, sizeof(LIST_ENTRY));
|
||||
nextEntry.Blink = (LIST_ENTRY*)entryInMemoryOrder;
|
||||
uc_mem_write(m_ucEngine, (uint64_t)entryLinks.Flink, &nextEntry, sizeof(LIST_ENTRY));
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>InInitializationOrderModuleList
|
||||
uc_mem_read(m_ucEngine, inInitOrderListHead, &listHead, sizeof(LIST_ENTRY));
|
||||
entryLinks.Flink = listHead.Flink;
|
||||
entryLinks.Blink = (LIST_ENTRY*)inInitOrderListHead;
|
||||
uc_mem_write(m_ucEngine, entryInInitOrder, &entryLinks, sizeof(LIST_ENTRY));
|
||||
listHead.Flink = (LIST_ENTRY*)entryInInitOrder;
|
||||
uc_mem_write(m_ucEngine, inInitOrderListHead, &listHead, sizeof(LIST_ENTRY));
|
||||
if (entryLinks.Flink != (LIST_ENTRY*)inInitOrderListHead) {
|
||||
LIST_ENTRY nextEntry;
|
||||
uc_mem_read(m_ucEngine, (uint64_t)entryLinks.Flink, &nextEntry, sizeof(LIST_ENTRY));
|
||||
nextEntry.Blink = (LIST_ENTRY*)entryInInitOrder;
|
||||
uc_mem_write(m_ucEngine, (uint64_t)entryLinks.Flink, &nextEntry, sizeof(LIST_ENTRY));
|
||||
}
|
||||
}
|
||||
|
||||
auto Sandbox::AddModuleToLdr(const std::shared_ptr<struct_moudle>& module)
|
||||
-> void {
|
||||
auto Sandbox::AddModuleToLdr(const std::shared_ptr<struct_moudle>& module) -> void {
|
||||
if (!m_peInfo->isX64) {
|
||||
return; // <20><>ʱֻ<CAB1><D6BB><EFBFBD><EFBFBD>64λ
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_peb64.Ldr == 0) {
|
||||
InitializeLdrData();
|
||||
if (LOG_LEVEL > 4) {
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
printf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD>: '%s', <20><>ַ: 0x%llx, <20><><EFBFBD>ڵ<EFBFBD>: 0x%llx, <20><>С: 0x%llx\n",
|
||||
module->name, module->base, module->entry, module->size);
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
|
||||
const size_t stringSectionSize = MAX_PATH * sizeof(wchar_t) * 2;
|
||||
uint64_t entrySize = sizeof(LDR_DATA_TABLE_ENTRY) + stringSectionSize;
|
||||
|
||||
// Ϊģ<EFBFBD>鴴<EFBFBD><EFBFBD>LDR_DATA_TABLE_ENTRY
|
||||
uint64_t entrySize = sizeof(LDR_DATA_TABLE_ENTRY) +
|
||||
MAX_PATH * 2; // <20><><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD><EFBFBD><EFBFBD>Unicode<64>ַ<EFBFBD><D6B7><EFBFBD>
|
||||
uint64_t entryAddress = m_pebEnd;
|
||||
m_pebEnd += entrySize;
|
||||
|
||||
// ȷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD>뵽8<EFBFBD>ֽڱ߽磨<EFBFBD><EFBFBD><EFBFBD><EFBFBD>64λ<EFBFBD>ṹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD>
|
||||
uint64_t entryAddress = (m_pebEnd + 7) & ~7ULL;
|
||||
if (LOG_LEVEL > 4) {
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
printf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>LDR<EFBFBD><EFBFBD>Ŀ: <20><>ַ=0x%llx, <20><>С=0x%llx\n", entryAddress, entrySize);
|
||||
}
|
||||
// ӳ<><D3B3><EFBFBD>ڴ<EFBFBD>
|
||||
uc_mem_map(m_ucEngine, entryAddress, entrySize, UC_PROT_ALL);
|
||||
const size_t pageSize = 4096;
|
||||
size_t alignedSize = (entrySize + pageSize - 1) & ~(pageSize - 1);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>Unicode<64>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>ַ
|
||||
uint64_t fullNameAddress = entryAddress + sizeof(LDR_DATA_TABLE_ENTRY);
|
||||
uint64_t baseNameAddress = fullNameAddress + MAX_PATH;
|
||||
uc_err err = uc_mem_map(m_ucEngine, entryAddress, alignedSize, UC_PROT_ALL);
|
||||
if (err != UC_ERR_OK) {
|
||||
if (LOG_LEVEL > 4) {
|
||||
printf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20><EFBFBD>ӳ<EFBFBD><D3B3>LDR<44><52>Ŀ<EFBFBD>ڴ<EFBFBD> @ 0x%llx (<28><><EFBFBD><EFBFBD>=%d)\n", entryAddress, err);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>LDR_DATA_TABLE_ENTRY
|
||||
auto entry =
|
||||
CreateLdrEntry(module, entryAddress, fullNameAddress, baseNameAddress);
|
||||
// <20><><EFBFBD><EFBFBD>Unicode<EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD>ȷ<EFBFBD><EFBFBD>8<EFBFBD>ֽڶ<EFBFBD><EFBFBD><EFBFBD>
|
||||
uint64_t fullNameAddress = (entryAddress + sizeof(LDR_DATA_TABLE_ENTRY) + 7) & ~7ULL;
|
||||
uint64_t baseNameAddress = (fullNameAddress + (MAX_PATH * sizeof(wchar_t)) + 7) & ~7ULL;
|
||||
if (LOG_LEVEL > 4) {
|
||||
// <20><>֤<EFBFBD><D6A4>ַ<EFBFBD><D6B7>Χ
|
||||
printf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>ַ - FullName=0x%llx, BaseName=0x%llx\n",
|
||||
fullNameAddress, baseNameAddress);
|
||||
}
|
||||
// ȷ<><C8B7><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ淶Χ
|
||||
if (baseNameAddress + (MAX_PATH * sizeof(wchar_t)) > entryAddress + alignedSize) {
|
||||
if (LOG_LEVEL > 4) {
|
||||
printf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ淶Χ!\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>LDR<44><52>Ŀ
|
||||
auto entry = CreateLdrEntry(module, entryAddress, fullNameAddress, baseNameAddress);
|
||||
if (LOG_LEVEL > 4) {
|
||||
|
||||
// <20><>֤DllBase<73><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ
|
||||
if ((uint64_t)entry.DllBase != module->base) {
|
||||
printf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>: DllBase<73><65>ƥ<EFBFBD><C6A5> (<28><><EFBFBD><EFBFBD>=%llx, <20><><EFBFBD><EFBFBD>=%llx)\n",
|
||||
(uint64_t)entry.DllBase, module->base);
|
||||
}
|
||||
}
|
||||
// <20><>PEB<45><42>ȡ<EFBFBD><C8A1>ǰLDR_DATA<54>ṹ
|
||||
X64_PEB_LDR_DATA ldrData;
|
||||
uc_mem_read(m_ucEngine, m_peb64.Ldr, &ldrData, sizeof(X64_PEB_LDR_DATA));
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
||||
entry.InLoadOrderLinks.Flink = reinterpret_cast<LIST_ENTRY*>(
|
||||
reinterpret_cast<uintptr_t>(ldrData.InLoadOrderModuleList.Flink));
|
||||
entry.InLoadOrderLinks.Blink = reinterpret_cast<LIST_ENTRY*>(
|
||||
m_peb64.Ldr + offsetof(X64_PEB_LDR_DATA, InLoadOrderModuleList));
|
||||
|
||||
entry.InMemoryOrderLinks.Flink = reinterpret_cast<LIST_ENTRY*>(
|
||||
reinterpret_cast<uintptr_t>(ldrData.InMemoryOrderModuleList.Flink));
|
||||
entry.InMemoryOrderLinks.Blink = reinterpret_cast<LIST_ENTRY*>(
|
||||
m_peb64.Ldr + offsetof(X64_PEB_LDR_DATA, InMemoryOrderModuleList));
|
||||
|
||||
entry.InInitializationOrderLinks.Flink =
|
||||
reinterpret_cast<LIST_ENTRY*>(reinterpret_cast<uintptr_t>(
|
||||
ldrData.InInitializationOrderModuleList.Flink));
|
||||
entry.InInitializationOrderLinks.Blink = reinterpret_cast<LIST_ENTRY*>(
|
||||
m_peb64.Ldr +
|
||||
offsetof(X64_PEB_LDR_DATA, InInitializationOrderModuleList));
|
||||
|
||||
// д<><D0B4>LDR_DATA_TABLE_ENTRY<52>ṹ
|
||||
uc_mem_write(m_ucEngine, entryAddress, &entry,
|
||||
sizeof(LDR_DATA_TABLE_ENTRY));
|
||||
uc_mem_write(m_ucEngine, entryAddress, &entry, sizeof(LDR_DATA_TABLE_ENTRY));
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
UpdateLdrLinks(entry, entryAddress, ldrData);
|
||||
|
||||
printf("Added module '%s' to LDR data tables at 0x%llx\n", module->name,
|
||||
entryAddress);
|
||||
// <20><><EFBFBD><EFBFBD>PEBβ<42><CEB2>λ<EFBFBD><CEBB>
|
||||
m_pebEnd = entryAddress + alignedSize;
|
||||
if (LOG_LEVEL > 4) {
|
||||
|
||||
printf("<EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD> '%s' <20><>LDR<44><52><EFBFBD>ݱ<EFBFBD> @ 0x%llx\n", module->name, entryAddress);
|
||||
}
|
||||
}
|
||||
auto Sandbox::TestLdrListTraversal() -> bool {
|
||||
if (LOG_LEVEL > 4) {
|
||||
|
||||
printf("\n============ LDR<44><52><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ============\n");
|
||||
|
||||
// 1. <20><>ȡPEB<45><42>ַ
|
||||
uint64_t pebAddress = m_pebBase; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>PEB<45><42>ַ
|
||||
X64PEB peb;
|
||||
if (uc_mem_read(m_ucEngine, pebAddress, &peb, sizeof(X64PEB)) != UC_ERR_OK) {
|
||||
printf("ERROR: <20><EFBFBD><DEB7><EFBFBD>ȡPEB<45>ṹ<EFBFBD><E1B9B9>\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
printf("PEBλ<EFBFBD><EFBFBD>: 0x%llx\n", pebAddress);
|
||||
printf("PEB.Ldrָ<72><D6B8>: 0x%llx\n", peb.Ldr);
|
||||
|
||||
// 2. <20><>ȡLDR_DATA<54>ṹ
|
||||
if (peb.Ldr == 0) {
|
||||
printf("ERROR: PEB.LdrΪNULL<4C><4C>LDRδ<52><CEB4>ʼ<EFBFBD><CABC>\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
X64_PEB_LDR_DATA ldrData;
|
||||
if (uc_mem_read(m_ucEngine, peb.Ldr, &ldrData, sizeof(X64_PEB_LDR_DATA)) != UC_ERR_OK) {
|
||||
printf("ERROR: <20><EFBFBD><DEB7><EFBFBD>ȡLDR_DATA<54>ṹ<EFBFBD><E1B9B9>\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
printf("LDR_DATA.Length: %u\n", ldrData.Length);
|
||||
printf("LDR_DATA.Initialized: %u\n", ldrData.Initialized);
|
||||
|
||||
// 3. <20><><EFBFBD>鲢<EFBFBD><E9B2A2>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
DumpLdrList("InLoadOrderModuleList", peb.Ldr,
|
||||
offsetof(X64_PEB_LDR_DATA, InLoadOrderModuleList),
|
||||
offsetof(LDR_DATA_TABLE_ENTRY, InLoadOrderLinks));
|
||||
|
||||
DumpLdrList("InMemoryOrderModuleList", peb.Ldr,
|
||||
offsetof(X64_PEB_LDR_DATA, InMemoryOrderModuleList),
|
||||
offsetof(LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks));
|
||||
|
||||
DumpLdrList("InInitializationOrderModuleList", peb.Ldr,
|
||||
offsetof(X64_PEB_LDR_DATA, InInitializationOrderModuleList),
|
||||
offsetof(LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks));
|
||||
|
||||
printf("========================================\n");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡָ<D3A1><D6B8><EFBFBD><EFBFBD>LDR<44><52><EFBFBD><EFBFBD>
|
||||
auto Sandbox::DumpLdrList(const char* listName, uint64_t ldrDataBase, size_t listOffset, size_t entryLinkOffset) -> void {
|
||||
if (LOG_LEVEL > 4) {
|
||||
|
||||
printf("\n--- %s <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ---\n", listName);
|
||||
|
||||
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>ַ
|
||||
uint64_t listHeadAddr = ldrDataBase + listOffset;
|
||||
LIST_ENTRY listHead;
|
||||
if (uc_mem_read(m_ucEngine, listHeadAddr, &listHead, sizeof(LIST_ENTRY)) != UC_ERR_OK) {
|
||||
printf("ERROR: <20><EFBFBD><DEB7><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ͷ @ 0x%llx\n", listHeadAddr);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("<EFBFBD>б<EFBFBD>ͷ @ 0x%llx: Flink=0x%llx, Blink=0x%llx\n",
|
||||
listHeadAddr, (uint64_t)listHead.Flink, (uint64_t)listHead.Blink);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>Ϊ<EFBFBD><CEAA>
|
||||
if (listHead.Flink == (LIST_ENTRY*)listHeadAddr) {
|
||||
printf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD> (Flinkָ<6B><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
uint64_t currentLink = (uint64_t)listHead.Flink;
|
||||
int entryCount = 0;
|
||||
|
||||
while (currentLink != listHeadAddr && entryCount < 100) { // <20><>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD>
|
||||
entryCount++;
|
||||
|
||||
// <20><><EFBFBD>㵱ǰLDR_DATA_TABLE_ENTRY<52>ĵ<EFBFBD>ַ
|
||||
uint64_t entryAddr = currentLink - entryLinkOffset;
|
||||
|
||||
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||
LDR_DATA_TABLE_ENTRY entry;
|
||||
if (uc_mem_read(m_ucEngine, entryAddr, &entry, sizeof(LDR_DATA_TABLE_ENTRY)) != UC_ERR_OK) {
|
||||
printf("ERROR: <20><EFBFBD><DEB7><EFBFBD>ȡ<EFBFBD><C8A1>Ŀ @ 0x%llx\n", entryAddr);
|
||||
break;
|
||||
}
|
||||
|
||||
printf("\n<EFBFBD><EFBFBD>Ŀ #%d @ 0x%llx:\n", entryCount, entryAddr);
|
||||
printf(" DllBase: 0x%llx\n", (uint64_t)entry.DllBase);
|
||||
printf(" EntryPoint: 0x%llx\n", (uint64_t)entry.EntryPoint);
|
||||
printf(" SizeOfImage: 0x%x\n", entry.SizeOfImages);
|
||||
|
||||
// <20><>ȡ<EFBFBD>ʹ<EFBFBD>ӡģ<D3A1><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
if ((uint64_t)entry.FullDllName.Buffer != 0 && entry.FullDllName.Length > 0) {
|
||||
size_t nameLen = entry.FullDllName.Length / sizeof(wchar_t);
|
||||
wchar_t* nameBuffer = new wchar_t[nameLen + 1];
|
||||
|
||||
if (uc_mem_read(m_ucEngine, (uint64_t)entry.FullDllName.Buffer, nameBuffer, entry.FullDllName.Length) == UC_ERR_OK) {
|
||||
nameBuffer[nameLen] = L'\0';
|
||||
|
||||
// ת<><D7AA>Ϊ<EFBFBD><CEAA><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
char mbName[MAX_PATH * 2] = { 0 };
|
||||
wcstombs(mbName, nameBuffer, sizeof(mbName) - 1);
|
||||
printf(" FullDllName: %s\n", mbName);
|
||||
}
|
||||
else {
|
||||
printf(" ERROR: <20><EFBFBD><DEB7><EFBFBD>ȡFullDllName @ 0x%llx (<28><><EFBFBD><EFBFBD>: %d)\n",
|
||||
(uint64_t)entry.FullDllName.Buffer, entry.FullDllName.Length);
|
||||
}
|
||||
|
||||
delete[] nameBuffer;
|
||||
}
|
||||
else {
|
||||
printf(" FullDllName: <<3C>ջ<EFBFBD><D5BB><EFBFBD>Ч>\n");
|
||||
}
|
||||
|
||||
// ͬ<><CDAC><EFBFBD><EFBFBD>ӡBaseDllName
|
||||
if ((uint64_t)entry.BaseDllName.Buffer != 0 && entry.BaseDllName.Length > 0) {
|
||||
size_t nameLen = entry.BaseDllName.Length / sizeof(wchar_t);
|
||||
wchar_t* nameBuffer = new wchar_t[nameLen + 1];
|
||||
|
||||
if (uc_mem_read(m_ucEngine, (uint64_t)entry.BaseDllName.Buffer, nameBuffer, entry.BaseDllName.Length) == UC_ERR_OK) {
|
||||
nameBuffer[nameLen] = L'\0';
|
||||
|
||||
char mbName[MAX_PATH * 2] = { 0 };
|
||||
wcstombs(mbName, nameBuffer, sizeof(mbName) - 1);
|
||||
printf(" BaseDllName: %s\n", mbName);
|
||||
}
|
||||
else {
|
||||
printf(" ERROR: <20><EFBFBD><DEB7><EFBFBD>ȡBaseDllName @ 0x%llx (<28><><EFBFBD><EFBFBD>: %d)\n",
|
||||
(uint64_t)entry.BaseDllName.Buffer, entry.BaseDllName.Length);
|
||||
}
|
||||
|
||||
delete[] nameBuffer;
|
||||
}
|
||||
else {
|
||||
printf(" BaseDllName: <<3C>ջ<EFBFBD><D5BB><EFBFBD>Ч>\n");
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>
|
||||
printf(" <20><><EFBFBD><EFBFBD>: Flink=0x%llx, Blink=0x%llx\n",
|
||||
(uint64_t)entry.InLoadOrderLinks.Flink, (uint64_t)entry.InLoadOrderLinks.Blink);
|
||||
|
||||
// <20>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ŀ
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7>Flink<6E>ֶ<EFBFBD>
|
||||
if (listOffset == offsetof(X64_PEB_LDR_DATA, InLoadOrderModuleList))
|
||||
currentLink = (uint64_t)entry.InLoadOrderLinks.Flink;
|
||||
else if (listOffset == offsetof(X64_PEB_LDR_DATA, InMemoryOrderModuleList))
|
||||
currentLink = (uint64_t)entry.InMemoryOrderLinks.Flink;
|
||||
else if (listOffset == offsetof(X64_PEB_LDR_DATA, InInitializationOrderModuleList))
|
||||
currentLink = (uint64_t)entry.InInitializationOrderLinks.Flink;
|
||||
|
||||
// <20>ڴ<EFBFBD><DAB4><EFBFBD>֤ - <20><>ֹ<EFBFBD><D6B9>Чָ<D0A7><D6B8>
|
||||
if (currentLink == 0 || currentLink == entryAddr) {
|
||||
printf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><EFBFBD>Flinkָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (entryCount == 0) {
|
||||
printf("<EFBFBD><EFBFBD><EFBFBD>棺û<EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷָʾ<EFBFBD>ǿ<EFBFBD>\n");
|
||||
}
|
||||
else if (entryCount >= 100) {
|
||||
printf("<EFBFBD><EFBFBD><EFBFBD>棺<EFBFBD><EFBFBD><EFBFBD>ܵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ṹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n");
|
||||
}
|
||||
else {
|
||||
printf("\n<EFBFBD>ܹ<EFBFBD><EFBFBD>ҵ<EFBFBD> %d <20><><EFBFBD><EFBFBD>Ŀ\n", entryCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
277
ai_anti_malware/sandbox_setupvm.cpp
Normal file
277
ai_anti_malware/sandbox_setupvm.cpp
Normal file
@@ -0,0 +1,277 @@
|
||||
#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);
|
||||
|
||||
/*
|
||||
ӳ<><D3B3> 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;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user