diff --git a/ai_anti_malware/ai_anti_malware.cpp b/ai_anti_malware/ai_anti_malware.cpp
index bb16ff2..855728f 100644
--- a/ai_anti_malware/ai_anti_malware.cpp
+++ b/ai_anti_malware/ai_anti_malware.cpp
@@ -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;
}
diff --git a/ai_anti_malware/ai_anti_malware.vcxproj b/ai_anti_malware/ai_anti_malware.vcxproj
index aa47f0d..68b9668 100644
--- a/ai_anti_malware/ai_anti_malware.vcxproj
+++ b/ai_anti_malware/ai_anti_malware.vcxproj
@@ -191,6 +191,7 @@
+
diff --git a/ai_anti_malware/ai_anti_malware.vcxproj.filters b/ai_anti_malware/ai_anti_malware.vcxproj.filters
index ceb4e86..3d838d4 100644
--- a/ai_anti_malware/ai_anti_malware.vcxproj.filters
+++ b/ai_anti_malware/ai_anti_malware.vcxproj.filters
@@ -168,6 +168,9 @@
源文件\sandbox
+
+ 源文件\sandbox
+
diff --git a/ai_anti_malware/native_struct.h b/ai_anti_malware/native_struct.h
index ab6abbd..0a323f9 100644
--- a/ai_anti_malware/native_struct.h
+++ b/ai_anti_malware/native_struct.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;
diff --git a/ai_anti_malware/sandbox.cpp b/ai_anti_malware/sandbox.cpp
index 6e7c1bf..19cfbab 100644
--- a/ai_anti_malware/sandbox.cpp
+++ b/ai_anti_malware/sandbox.cpp
@@ -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(
@@ -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 {
// 解析PE头
@@ -283,9 +284,8 @@ auto Sandbox::CreateModuleInfo(const char* dllName, uint64_t moduleBase,
reinterpret_cast(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(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(Msr::kIa32GsBase);
- msr.value = m_gsBase;
- uc_reg_write(m_ucEngine, UC_X86_REG_MSR, &msr);
- } else {
- // 设置32位PEB
- m_peb32.ImageBaseAddress = static_cast(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(m_pebBase);
- m_teb32.NtTib.StackBase = static_cast(m_stackBase);
- m_teb32.NtTib.StackLimit = static_cast(m_stackSize);
- // 初始化NT_TIB结构的其余部分
- m_teb32.NtTib.Self =
- static_cast(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(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(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(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(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 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(m_peInfo->peBuffer));
+
_ASSERTE(m_moduleList.size() == 0);
m_moduleList.push_back(newModule);
@@ -692,7 +519,35 @@ auto Sandbox::InitEnv(std::shared_ptr 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 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;
}
diff --git a/ai_anti_malware/sandbox.h b/ai_anti_malware/sandbox.h
index ef1f959..3e2e133 100644
--- a/ai_anti_malware/sandbox.h
+++ b/ai_anti_malware/sandbox.h
@@ -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;
auto ResolveExport(uint64_t moduleBase)
@@ -333,6 +337,9 @@ class Sandbox {
// 将模块添加到LDR链表中
auto AddModuleToLdr(const std::shared_ptr& 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& module,
uint64_t entryAddress, uint64_t fullNameAddress,
diff --git a/ai_anti_malware/sandbox_api_emu.cpp b/ai_anti_malware/sandbox_api_emu.cpp
index 4fc6f72..f05b8b5 100644
--- a/ai_anti_malware/sandbox_api_emu.cpp
+++ b/ai_anti_malware/sandbox_api_emu.cpp
@@ -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);
- uint32_t dwInfoType = 0;
+ uint64_t dwInfoType = 0;
uint64_t lpSrcStr = 0;
int32_t cchSrc = 0;
uint64_t lpCharType = 0;
diff --git a/ai_anti_malware/sandbox_callbacks.cpp b/ai_anti_malware/sandbox_callbacks.cpp
index 1fe3cb2..421f68a 100644
--- a/ai_anti_malware/sandbox_callbacks.cpp
+++ b/ai_anti_malware/sandbox_callbacks.cpp
@@ -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");
diff --git a/ai_anti_malware/sandbox_dump_pe.cpp b/ai_anti_malware/sandbox_dump_pe.cpp
index f56174f..61c6652 100644
--- a/ai_anti_malware/sandbox_dump_pe.cpp
+++ b/ai_anti_malware/sandbox_dump_pe.cpp
@@ -4,7 +4,7 @@ auto Sandbox::DumpPE() -> std::pair, size_t> {
// Ŀģ - ʹģ(ͨDZĿִļ)
std::shared_ptr targetModule = nullptr;
for (const auto& module : m_moduleList) {
- if (strcmp(module->name, "huoji.exe") == 0) {
+ if ((*module).name == "HUOJI.EXE") {
targetModule = module;
break;
}
diff --git a/ai_anti_malware/sandbox_ldr.cpp b/ai_anti_malware/sandbox_ldr.cpp
index e8df912..bea5e83 100644
--- a/ai_anti_malware/sandbox_ldr.cpp
+++ b/ai_anti_malware/sandbox_ldr.cpp
@@ -2,7 +2,7 @@
auto Sandbox::InitializeLdrData() -> void {
- if (m_peInfo->isX64 && m_peb64.Ldr == 0) {
+ if (m_peInfo->isX64) {
// ΪLDR_DATAڴ
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;
- // ʼͷ - ʹʵת
- LIST_ENTRY inLoadOrderList = {
- reinterpret_cast(
- ldrDataAddress +
- offsetof(X64_PEB_LDR_DATA, InLoadOrderModuleList)),
- reinterpret_cast(
- ldrDataAddress +
- offsetof(X64_PEB_LDR_DATA, InLoadOrderModuleList)) };
- ldrData.InLoadOrderModuleList = inLoadOrderList;
+ // ʼͷ - ÿͷָԼ()
+ 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(
- ldrDataAddress +
- offsetof(X64_PEB_LDR_DATA, InMemoryOrderModuleList)),
- reinterpret_cast(
- ldrDataAddress +
- offsetof(X64_PEB_LDR_DATA, InMemoryOrderModuleList)) };
- ldrData.InMemoryOrderModuleList = inMemoryOrderList;
+ // ÿͷFlinkBlinkָԼ
+ ldrData.InLoadOrderModuleList.Flink = (LIST_ENTRY*)inLoadOrderListHead;
+ ldrData.InLoadOrderModuleList.Blink = (LIST_ENTRY*)inLoadOrderListHead;
- LIST_ENTRY inInitOrderList = {
- reinterpret_cast(
- ldrDataAddress +
- offsetof(X64_PEB_LDR_DATA, InInitializationOrderModuleList)),
- reinterpret_cast(
- 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;
+
+ // дLDR_DATAṹڴ
+ uc_mem_write(m_ucEngine, ldrDataAddress, &ldrData, sizeof(X64_PEB_LDR_DATA));
// PEBеLdrָ
uc_mem_write(m_ucEngine, m_pebBase, &m_peb64, sizeof(X64PEB));
}
}
-
auto Sandbox::CreateLdrEntry(const std::shared_ptr& module,
uint64_t entryAddress, uint64_t fullNameAddress,
uint64_t baseNameAddress) -> LDR_DATA_TABLE_ENTRY {
- LDR_DATA_TABLE_ENTRY entry = { 0 };
+
+ // ṹȷֶȷʼ
+ LDR_DATA_TABLE_ENTRY entry = {};
+ if (LOG_LEVEL > 4) {
+
+ // ģַ - nullָ
+ if (module->base == 0) {
+ printf("棺ģ'%s'ĻַΪ0ܵ\n", module->name);
+ }
+ }
+
entry.DllBase = reinterpret_cast(module->base);
entry.EntryPoint = reinterpret_cast(module->base + module->entry);
entry.SizeOfImages = static_cast(module->size);
-
// ģƵUnicodeַ
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);
- // ȫ·
- entry.FullDllName.Length =
- static_cast(wcslen(nameBuffer) * sizeof(wchar_t));
+ // ʹøȫmbstowcs_s
+ mbstowcs_s(&convertedChars, nameBuffer, MAX_PATH, fakeFullName.c_str(), fakeFullName.size());
+
+ // ֤תַ
+ size_t nameLen = wcslen(nameBuffer);
+ if (LOG_LEVEL > 4) {
+
+ if (nameLen == 0 || nameLen >= MAX_PATH) {
+ printf("棺ģ'%s'ת⣬=%zu\n", module->name, nameLen);
+ }
+ }
+ // ַ
+ entry.FullDllName.Length = static_cast(nameLen * sizeof(wchar_t));
entry.FullDllName.MaximumLength = MAX_PATH * sizeof(wchar_t);
entry.FullDllName.Buffer = reinterpret_cast(fullNameAddress);
- // û
- entry.BaseDllName.Length =
- static_cast(wcslen(nameBuffer) * sizeof(wchar_t));
+ entry.BaseDllName.Length = static_cast(nameLen * sizeof(wchar_t));
entry.BaseDllName.MaximumLength = MAX_PATH * sizeof(wchar_t);
entry.BaseDllName.Buffer = reinterpret_cast(baseNameAddress);
+ if (LOG_LEVEL > 4) {
+ // дַ - ӵ
+ printf("DEBUG: дģ '%s' ַ 0x%llx 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));
- // дUnicodeַ
- 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));
+ // ʼָΪNULLUpdateLdrLinksã
+ 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 {
- // LDR_DATAеͷ
- ldrData.InLoadOrderModuleList.Flink = reinterpret_cast(
- entryAddress + offsetof(LDR_DATA_TABLE_ENTRY, InLoadOrderLinks));
- ldrData.InMemoryOrderModuleList.Flink = reinterpret_cast(
- entryAddress + offsetof(LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks));
- ldrData.InInitializationOrderModuleList.Flink =
- reinterpret_cast(
- entryAddress +
- offsetof(LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks));
+ uint64_t entryAddress, X64_PEB_LDR_DATA& ldrData) -> void {
+ // ȡͷַ
+ 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);
- // дظºLDR_DATA
- uc_mem_write(m_ucEngine, m_peb64.Ldr, &ldrData, sizeof(X64_PEB_LDR_DATA));
+ // Ŀÿеĵַ
+ 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;
+
+ // InLoadOrderModuleList
+ uc_mem_read(m_ucEngine, inLoadOrderListHead, &listHead, sizeof(LIST_ENTRY));
+
+ // Ŀ (Ŀ뵽ͷ֮)
+ entryLinks.Flink = listHead.Flink; // ĿFlink = ԭͷFlink
+ entryLinks.Blink = (LIST_ENTRY*)inLoadOrderListHead; // ĿBlink = ͷ
+ uc_mem_write(m_ucEngine, entryInLoadOrder, &entryLinks, sizeof(LIST_ENTRY));
+
+ // ͷFlinkָĿ
+ listHead.Flink = (LIST_ENTRY*)entryInLoadOrder;
+ uc_mem_write(m_ucEngine, inLoadOrderListHead, &listHead, sizeof(LIST_ENTRY));
+
+ // ǿԭһڵ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));
+ }
+
+ // ͬ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));
+ }
+
+ // 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& module)
--> void {
+auto Sandbox::AddModuleToLdr(const std::shared_ptr& module) -> void {
if (!m_peInfo->isX64) {
- return; // ʱֻ64λ
+ return;
}
-
- if (m_peb64.Ldr == 0) {
- InitializeLdrData();
+ if (LOG_LEVEL > 4) {
+ //
+ printf("ģ: '%s', ַ: 0x%llx, ڵ: 0x%llx, С: 0x%llx\n",
+ module->name, module->base, module->entry, module->size);
}
+ // ڴ
+ const size_t stringSectionSize = MAX_PATH * sizeof(wchar_t) * 2;
+ uint64_t entrySize = sizeof(LDR_DATA_TABLE_ENTRY) + stringSectionSize;
- // Ϊģ鴴LDR_DATA_TABLE_ENTRY
- uint64_t entrySize = sizeof(LDR_DATA_TABLE_ENTRY) +
- MAX_PATH * 2; // ռUnicodeַ
- uint64_t entryAddress = m_pebEnd;
- m_pebEnd += entrySize;
-
+ // ȷַ뵽8ֽڱ߽磨64λṹҪ
+ uint64_t entryAddress = (m_pebEnd + 7) & ~7ULL;
+ if (LOG_LEVEL > 4) {
+ //
+ printf("LDRĿ: ַ=0x%llx, С=0x%llx\n", entryAddress, entrySize);
+ }
// ӳڴ
- uc_mem_map(m_ucEngine, entryAddress, entrySize, UC_PROT_ALL);
+ const size_t pageSize = 4096;
+ size_t alignedSize = (entrySize + pageSize - 1) & ~(pageSize - 1);
- // Unicodeַַ
- 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(": ӳLDRĿڴ @ 0x%llx (=%d)\n", entryAddress, err);
+ }
+ return;
+ }
- // ʼLDR_DATA_TABLE_ENTRY
- auto entry =
- CreateLdrEntry(module, entryAddress, fullNameAddress, baseNameAddress);
+ // Unicodeַַȷ8ֽڶ
+ 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) {
+ // ַ֤Χ
+ printf(": ַַ - FullName=0x%llx, BaseName=0x%llx\n",
+ fullNameAddress, baseNameAddress);
+ }
+ // ȷַַڴ淶Χ
+ if (baseNameAddress + (MAX_PATH * sizeof(wchar_t)) > entryAddress + alignedSize) {
+ if (LOG_LEVEL > 4) {
+ printf(": ַڴ淶Χ!\n");
+ }
+ return;
+ }
+ // LDRĿ
+ auto entry = CreateLdrEntry(module, entryAddress, fullNameAddress, baseNameAddress);
+ if (LOG_LEVEL > 4) {
+
+ // ֤DllBaseȷ
+ if ((uint64_t)entry.DllBase != module->base) {
+ printf(": DllBaseƥ (=%llx, =%llx)\n",
+ (uint64_t)entry.DllBase, module->base);
+ }
+ }
// PEBȡǰLDR_DATAṹ
X64_PEB_LDR_DATA ldrData;
uc_mem_read(m_ucEngine, m_peb64.Ldr, &ldrData, sizeof(X64_PEB_LDR_DATA));
- // ָ
- entry.InLoadOrderLinks.Flink = reinterpret_cast(
- reinterpret_cast(ldrData.InLoadOrderModuleList.Flink));
- entry.InLoadOrderLinks.Blink = reinterpret_cast(
- m_peb64.Ldr + offsetof(X64_PEB_LDR_DATA, InLoadOrderModuleList));
-
- entry.InMemoryOrderLinks.Flink = reinterpret_cast(
- reinterpret_cast(ldrData.InMemoryOrderModuleList.Flink));
- entry.InMemoryOrderLinks.Blink = reinterpret_cast(
- m_peb64.Ldr + offsetof(X64_PEB_LDR_DATA, InMemoryOrderModuleList));
-
- entry.InInitializationOrderLinks.Flink =
- reinterpret_cast(reinterpret_cast(
- ldrData.InInitializationOrderModuleList.Flink));
- entry.InInitializationOrderLinks.Blink = reinterpret_cast(
- m_peb64.Ldr +
- offsetof(X64_PEB_LDR_DATA, InInitializationOrderModuleList));
-
// дLDR_DATA_TABLE_ENTRYṹ
- uc_mem_write(m_ucEngine, entryAddress, &entry,
- sizeof(LDR_DATA_TABLE_ENTRY));
+ uc_mem_write(m_ucEngine, entryAddress, &entry, sizeof(LDR_DATA_TABLE_ENTRY));
//
UpdateLdrLinks(entry, entryAddress, ldrData);
- printf("Added module '%s' to LDR data tables at 0x%llx\n", module->name,
- entryAddress);
+ // PEBβλ
+ m_pebEnd = entryAddress + alignedSize;
+ if (LOG_LEVEL > 4) {
+
+ printf("ɹģ '%s' LDRݱ @ 0x%llx\n", module->name, entryAddress);
+ }
}
+auto Sandbox::TestLdrListTraversal() -> bool {
+ if (LOG_LEVEL > 4) {
+
+ printf("\n============ LDR ============\n");
+
+ // 1. ȡPEBַ
+ uint64_t pebAddress = m_pebBase; // PEBַ
+ X64PEB peb;
+ if (uc_mem_read(m_ucEngine, pebAddress, &peb, sizeof(X64PEB)) != UC_ERR_OK) {
+ printf("ERROR: ȡPEBṹ\n");
+ return false;
+ }
+
+ printf("PEBλ: 0x%llx\n", pebAddress);
+ printf("PEB.Ldrָ: 0x%llx\n", peb.Ldr);
+
+ // 2. ȡLDR_DATAṹ
+ if (peb.Ldr == 0) {
+ printf("ERROR: PEB.LdrΪNULLLDRδʼ\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: ȡLDR_DATAṹ\n");
+ return false;
+ }
+
+ printf("LDR_DATA.Length: %u\n", ldrData.Length);
+ printf("LDR_DATA.Initialized: %u\n", ldrData.Initialized);
+
+ // 3. 鲢ӡ
+ 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;
+}
+
+// ӡָLDR
+auto Sandbox::DumpLdrList(const char* listName, uint64_t ldrDataBase, size_t listOffset, size_t entryLinkOffset) -> void {
+ if (LOG_LEVEL > 4) {
+
+ printf("\n--- %s ---\n", listName);
+
+ // ȡͷַ
+ uint64_t listHeadAddr = ldrDataBase + listOffset;
+ LIST_ENTRY listHead;
+ if (uc_mem_read(m_ucEngine, listHeadAddr, &listHead, sizeof(LIST_ENTRY)) != UC_ERR_OK) {
+ printf("ERROR: ȡͷ @ 0x%llx\n", listHeadAddr);
+ return;
+ }
+
+ printf("бͷ @ 0x%llx: Flink=0x%llx, Blink=0x%llx\n",
+ listHeadAddr, (uint64_t)listHead.Flink, (uint64_t)listHead.Blink);
+
+ // ǷΪ
+ if (listHead.Flink == (LIST_ENTRY*)listHeadAddr) {
+ printf("Ϊ (Flinkָ)\n");
+ return;
+ }
+
+ //
+ uint64_t currentLink = (uint64_t)listHead.Flink;
+ int entryCount = 0;
+
+ while (currentLink != listHeadAddr && entryCount < 100) { // ֹѭ
+ entryCount++;
+
+ // 㵱ǰLDR_DATA_TABLE_ENTRYĵַ
+ uint64_t entryAddr = currentLink - entryLinkOffset;
+
+ // ȡĿ
+ LDR_DATA_TABLE_ENTRY entry;
+ if (uc_mem_read(m_ucEngine, entryAddr, &entry, sizeof(LDR_DATA_TABLE_ENTRY)) != UC_ERR_OK) {
+ printf("ERROR: ȡĿ @ 0x%llx\n", entryAddr);
+ break;
+ }
+
+ printf("\nĿ #%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);
+
+ // ȡʹӡģ
+ 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';
+
+ // תΪֽ
+ char mbName[MAX_PATH * 2] = { 0 };
+ wcstombs(mbName, nameBuffer, sizeof(mbName) - 1);
+ printf(" FullDllName: %s\n", mbName);
+ }
+ else {
+ printf(" ERROR: ȡFullDllName @ 0x%llx (: %d)\n",
+ (uint64_t)entry.FullDllName.Buffer, entry.FullDllName.Length);
+ }
+
+ delete[] nameBuffer;
+ }
+ else {
+ printf(" FullDllName: <ջЧ>\n");
+ }
+
+ // ͬӡ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: ȡBaseDllName @ 0x%llx (: %d)\n",
+ (uint64_t)entry.BaseDllName.Buffer, entry.BaseDllName.Length);
+ }
+
+ delete[] nameBuffer;
+ }
+ else {
+ printf(" BaseDllName: <ջЧ>\n");
+ }
+
+ // ָЧ
+ printf(" : Flink=0x%llx, Blink=0x%llx\n",
+ (uint64_t)entry.InLoadOrderLinks.Flink, (uint64_t)entry.InLoadOrderLinks.Blink);
+
+ // ƶһĿ
+ // ѡȷFlinkֶ
+ 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;
+
+ // ڴ֤ - ֹЧָ
+ if (currentLink == 0 || currentLink == entryAddr) {
+ printf("ЧFlinkָ\n");
+ break;
+ }
+ }
+
+ if (entryCount == 0) {
+ printf("棺ûҵĿͷָʾǿ\n");
+ }
+ else if (entryCount >= 100) {
+ printf("棺ܵѭṹ\n");
+ }
+ else {
+ printf("\nܹҵ %d Ŀ\n", entryCount);
+ }
+ }
+}
\ No newline at end of file
diff --git a/ai_anti_malware/sandbox_setupvm.cpp b/ai_anti_malware/sandbox_setupvm.cpp
new file mode 100644
index 0000000..0c5aa6d
--- /dev/null
+++ b/ai_anti_malware/sandbox_setupvm.cpp
@@ -0,0 +1,277 @@
+#include "sandbox.h"
+auto Sandbox::BuildPebParameter() -> void {
+ //peb->ProcessParameters
+ // ý̲
+ RTL_USER_PROCESS_PARAMETERS processParams = {};
+
+ // ӳ̲ṹڴ
+ 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");
+ }
+
+ // û
+ processParams.MaximumLength = sizeof(RTL_USER_PROCESS_PARAMETERS);
+ processParams.Length = sizeof(RTL_USER_PROCESS_PARAMETERS);
+
+ // ַַ
+ uint64_t stringBufferBase = m_processParamsBase + processParamsSize;
+ uint64_t currentStringPos = stringBufferBase;
+
+ // ӳַ
+ size_t stringBufferSize = AlignToSectionAlignment(4096, PAGE_SIZE); // 㹻Ŀռ洢ַ
+ uc_mem_map(m_ucEngine, stringBufferBase, stringBufferSize, UC_PROT_READ | UC_PROT_WRITE);
+
+ // ӳ·
+ std::wstring imagePath = L"C:\\Path\\To\\EmulatedImage.exe";
+ UNICODE_STRING imagePathUnicode;
+ imagePathUnicode.Length = static_cast(imagePath.length() * sizeof(wchar_t));
+ imagePathUnicode.MaximumLength = imagePathUnicode.Length + sizeof(wchar_t); // ռnullֹ
+ imagePathUnicode.Buffer = reinterpret_cast(currentStringPos);
+
+ // дӳ·ַ
+ uc_mem_write(m_ucEngine, currentStringPos, imagePath.c_str(), imagePath.length() * sizeof(wchar_t) + sizeof(wchar_t));
+ currentStringPos += AlignToSectionAlignment(imagePathUnicode.MaximumLength, 8);
+
+ //
+ std::wstring commandLine = L"EmulatedImage.exe argument1 argument2";
+ UNICODE_STRING commandLineUnicode;
+ commandLineUnicode.Length = static_cast(commandLine.length() * sizeof(wchar_t));
+ commandLineUnicode.MaximumLength = commandLineUnicode.Length + sizeof(wchar_t);
+ commandLineUnicode.Buffer = reinterpret_cast(currentStringPos);
+
+ // дַ
+ uc_mem_write(m_ucEngine, currentStringPos, commandLine.c_str(), commandLine.length() * sizeof(wchar_t) + sizeof(wchar_t));
+ currentStringPos += AlignToSectionAlignment(commandLineUnicode.MaximumLength, 8);
+
+ // õǰĿ¼
+ std::wstring currentDir = L"C:\\Path\\To";
+ UNICODE_STRING currentDirUnicode;
+ currentDirUnicode.Length = static_cast(currentDir.length() * sizeof(wchar_t));
+ currentDirUnicode.MaximumLength = currentDirUnicode.Length + sizeof(wchar_t);
+ currentDirUnicode.Buffer = reinterpret_cast(currentStringPos);
+
+ // д뵱ǰĿ¼ַ
+ uc_mem_write(m_ucEngine, currentStringPos, currentDir.c_str(), currentDir.length() * sizeof(wchar_t) + sizeof(wchar_t));
+ currentStringPos += AlignToSectionAlignment(currentDirUnicode.MaximumLength, 8);
+
+ // DLL·
+ std::wstring dllPath = L"C:\\Windows\\System32";
+ UNICODE_STRING dllPathUnicode;
+ dllPathUnicode.Length = static_cast(dllPath.length() * sizeof(wchar_t));
+ dllPathUnicode.MaximumLength = dllPathUnicode.Length + sizeof(wchar_t);
+ dllPathUnicode.Buffer = reinterpret_cast(currentStringPos);
+
+ // дDLL·ַ
+ uc_mem_write(m_ucEngine, currentStringPos, dllPath.c_str(), dllPath.length() * sizeof(wchar_t) + sizeof(wchar_t));
+
+ // ý̲ṹеֶַ
+ processParams.ImagePathName = imagePathUnicode;
+ processParams.CommandLine = commandLineUnicode;
+ processParams.CurrentDirectory.DosPath = currentDirUnicode;
+ processParams.DllPath = dllPathUnicode;
+ processParams.Environment = reinterpret_cast(m_envBlockBase);
+
+ // д̲ṹ
+ 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);
+
+ /*
+ ӳ 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; // ַ
+ m_processParamsBase = PROCESS_PARAMS_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;
+
+ BuildPebParameter();
+ InitializeLdrData();
+
+ // PEļPEBTEB
+ 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(m_pebBase);
+ m_teb64.NtTib.StackBase = (DWORD64)m_stackBase;
+ m_teb64.NtTib.StackLimit = (DWORD64)m_stackSize;
+ m_peb64.ProcessParameters = m_processParamsBase;
+
+ // ö
+ 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(Msr::kIa32GsBase);
+ msr.value = m_gsBase;
+ uc_reg_write(m_ucEngine, UC_X86_REG_MSR, &msr);
+ }
+ else {
+ // 32λPEB
+ m_peb32.ImageBaseAddress = static_cast(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(m_pebBase);
+ m_teb32.NtTib.StackBase = static_cast(m_stackBase);
+ m_teb32.NtTib.StackLimit = static_cast(m_stackSize);
+ // ʼNT_TIBṹಿ
+ m_teb32.NtTib.Self =
+ static_cast(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.ProcessParameters = m_processParamsBase;
+
+ // ö
+ m_peb32.ProcessHeap = static_cast(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;
+ // ҪpresentdplΪSegmentSelectorṹûЩֶ
+ uc_reg_write(m_ucEngine, UC_X86_REG_FS, &fs.all);
+
+ // FSַMSR
+ uc_x86_msr msr;
+ msr.rid = static_cast(Msr::kIa32FsBase);
+ msr.value = m_tebBase;
+ uc_reg_write(m_ucEngine, UC_X86_REG_MSR, &msr);
+
+ // ȷTEBйؼֶαȷʼ
+ // رFS:18h (0x18)Ӧָ
+ // Native_Struct.hX32TEB壬ƫ0x18SelfTeb
+ uint32_t self_teb_ptr = static_cast(m_tebBase);
+ // NT_TIBSelfTeb (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(m_pebBase);
+ // ƫ0x30ProcessEnvironmentBlock
+ 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;
+ }
+
+}
\ No newline at end of file