This commit is contained in:
huoji
2025-03-06 18:39:01 +08:00
parent dbe2e6a92b
commit 2c18f7fd15
11 changed files with 1642 additions and 90 deletions

View File

@@ -0,0 +1,21 @@
{
"configurations": [
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"compilerPath": "E:/Program Files/LLVM/bin/clang++.exe",
"cStandard": "c11",
"cppStandard": "c++23",
"intelliSenseMode": "windows-clang-x64",
"windowsSdkVersion": "10.0.22000.0"
}
],
"version": 4
}

57
ai_anti_malware/.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,57 @@
{
"files.associations": {
"stdexcept": "cpp",
"algorithm": "cpp",
"atomic": "cpp",
"bit": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"compare": "cpp",
"concepts": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"exception": "cpp",
"list": "cpp",
"map": "cpp",
"set": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"initializer_list": "cpp",
"ios": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"iterator": "cpp",
"limits": "cpp",
"memory": "cpp",
"new": "cpp",
"ostream": "cpp",
"sstream": "cpp",
"streambuf": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"typeinfo": "cpp",
"utility": "cpp",
"xfacet": "cpp",
"xhash": "cpp",
"xiosbase": "cpp",
"xlocale": "cpp",
"xlocinfo": "cpp",
"xlocnum": "cpp",
"xmemory": "cpp",
"xstddef": "cpp",
"xstring": "cpp",
"xtr1common": "cpp",
"xtree": "cpp",
"xutility": "cpp",
"functional": "cpp"
}
}

View File

@@ -32,9 +32,7 @@ auto getPeInfo(std::string inputFilePath) -> std::shared_ptr<BasicPeInfo> {
return sampleInfo;
}
int main() {
auto sampleInfo = getPeInfo(
"E:\\对战平台\\CrowAntiCheat\\CrowAntiCheat\\client\\Console_"
"Test\\Release\\Console_Test.exe");
auto sampleInfo = getPeInfo("C:\\ConsoleApplication1.exe");
printf("input new file %s \n", sampleInfo->inputFilePath);
printf("is x64: %d\n", sampleInfo->isX64);
printf("is relocated: %d\n", sampleInfo->isRelocated);

View File

@@ -115,7 +115,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>false</ConformanceMode>
<LanguageStandard>stdcpplatest</LanguageStandard>
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
@@ -171,6 +171,7 @@
<ClCompile Include="libpeconv\libpeconv\src\resource_util.cpp" />
<ClCompile Include="libpeconv\libpeconv\src\util.cpp" />
<ClCompile Include="sandbox.cpp" />
<ClCompile Include="sandbox_api_emu.cpp" />
<ClCompile Include="sandbox_callbacks.cpp" />
</ItemGroup>
<ItemGroup>

View File

@@ -114,6 +114,9 @@
<ClCompile Include="sandbox_callbacks.cpp">
<Filter>源文件\sandbox</Filter>
</ClCompile>
<ClCompile Include="sandbox_api_emu.cpp">
<Filter>源文件\sandbox</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="head.h">

View File

@@ -937,6 +937,7 @@ struct moudle_export {
char name[MAX_PATH];
uint64_t function_address;
void* function_callback;
uint64_t ordinal;
};
struct moudle_import {
char name[MAX_PATH];

View File

@@ -1,5 +1,7 @@
#include "sandbox.h"
#include "sandbox_callbacks.h"
std::string getDllNameFromApiSetMap(const std::string& apiSet) {
const std::wstring wApiSet(apiSet.begin(), apiSet.end());
@@ -129,7 +131,37 @@ class cListImportNames : public peconv::ImportThunksCallback {
std::vector<std::shared_ptr<moudle_import>>& nameToAddr;
};
class cFixImprot : public peconv::t_function_resolver {
public:
// 构造函数接收Sandbox实例的引用
explicit cFixImprot(Sandbox* sandbox) : m_sandbox(sandbox) {}
// 实现导入函数解析
virtual FARPROC resolve_func(LPSTR lib_name, LPSTR func_name) override {
// 遍历所有已加载的模块
for (const auto& module : m_sandbox->m_moduleList) {
// 检查模块名是否匹配
if (_stricmp(module->name, lib_name) == 0) {
// 遍历模块的导出函数
for (const auto& exp : m_sandbox->m_exportFuncDict) {
// 检查函数名是否匹配
if (strcmp(exp->name, func_name) == 0) {
auto newBase = reinterpret_cast<FARPROC>(
module->base + exp->function_address);
printf("fix import: %s => %llx \n", func_name, newBase);
// 返回在模拟器中的虚拟地址
return newBase;
}
}
}
}
__debugbreak();
return nullptr;
}
private:
Sandbox* m_sandbox; // Sandbox实例的指针
};
Sandbox::Sandbox() {}
Sandbox::~Sandbox() {}
@@ -167,7 +199,6 @@ auto Sandbox::PushModuleToVM(const char* dllName, uint64_t moduleBase) -> void {
newModule.real_base = moduleBase;
newModule.entry = ntHeaders->OptionalHeader.AddressOfEntryPoint;
newModule.size = ntHeaders->OptionalHeader.SizeOfImage;
// 处理区段
for (WORD i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++) {
const auto& section = sectionHeader[i];
@@ -208,9 +239,13 @@ auto Sandbox::PushModuleToVM(const char* dllName, uint64_t moduleBase) -> void {
uc_mem_map(m_ucEngine, newModule.base, newModule.size,
UC_PROT_READ | UC_PROT_EXEC);
uc_mem_write(m_ucEngine, newModule.base, (void*)moduleBase, newModule.size);
if (peconv::relocate_module((BYTE*)moduleBase, newModule.size,
newModule.base) == false) {
throw std::runtime_error("Failed to relocate module");
}
auto Sandbox::ResolveExport() -> void {
}
auto Sandbox::ResolveExport(uint64_t moduleBase)
-> std::vector<std::shared_ptr<moudle_export>> {
DWORD exportSize = 0;
static RtlImageDirectoryEntryToDataFn fnRtlImageDirectoryEntryToData;
if (fnRtlImageDirectoryEntryToData == nullptr) {
@@ -221,25 +256,25 @@ auto Sandbox::ResolveExport() -> void {
// 获取导出表
PIMAGE_EXPORT_DIRECTORY exportDirectory =
static_cast<PIMAGE_EXPORT_DIRECTORY>(fnRtlImageDirectoryEntryToData(
m_peInfo->peBuffer, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT,
&exportSize));
reinterpret_cast<PUCHAR>(moduleBase), TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT, &exportSize));
if (exportDirectory) {
const DWORD numberOfNames = exportDirectory->NumberOfNames;
PDWORD addressOfFunctions =
reinterpret_cast<PDWORD>(static_cast<PUCHAR>(m_peInfo->peBuffer) +
reinterpret_cast<PDWORD>(reinterpret_cast<PUCHAR>(moduleBase) +
exportDirectory->AddressOfFunctions);
PDWORD addressOfNames =
reinterpret_cast<PDWORD>(static_cast<PUCHAR>(m_peInfo->peBuffer) +
reinterpret_cast<PDWORD>(reinterpret_cast<PUCHAR>(moduleBase) +
exportDirectory->AddressOfNames);
PWORD addressOfNameOrdinals =
reinterpret_cast<PWORD>(static_cast<PUCHAR>(m_peInfo->peBuffer) +
reinterpret_cast<PWORD>(reinterpret_cast<PUCHAR>(moduleBase) +
exportDirectory->AddressOfNameOrdinals);
// 遍历导出函数
for (size_t i = 0; i < numberOfNames; i++) {
PCHAR functionName = reinterpret_cast<PCHAR>(
static_cast<PUCHAR>(m_peInfo->peBuffer) + addressOfNames[i]);
reinterpret_cast<PUCHAR>(moduleBase) + addressOfNames[i]);
// 获取函数RVA
const DWORD functionRva =
@@ -249,11 +284,24 @@ auto Sandbox::ResolveExport() -> void {
moudle_export exportData{};
memcpy(exportData.name, functionName, strlen(functionName));
exportData.function_address = functionRva;
exportData.ordinal = static_cast<WORD>(
addressOfNameOrdinals[i] + exportDirectory->Base); // 设置序号
m_exportFuncDict.push_back(
std::make_shared<moudle_export>(exportData));
}
}
return m_exportFuncDict;
}
auto Sandbox::ResolveImportExports() -> void {
for (auto module : m_moduleList) {
const auto exports = ResolveExport(module->real_base);
for (const auto item : exports) {
printf("import export: [%s] %s => %llx\n", module->name, item->name,
item->function_address);
module->export_function.push_back(item);
}
}
}
auto Sandbox::processImportModule(const moudle_import* importModule) -> void {
@@ -442,7 +490,6 @@ auto Sandbox::SetupVirtualMachine() -> void {
}
auto Sandbox::InitEnv(std::shared_ptr<BasicPeInfo> peInfo) -> void {
m_peInfo = peInfo;
if (cs_open(CS_ARCH_X86, peInfo->isX64 ? CS_MODE_64 : CS_MODE_32,
&m_csHandle) != CS_ERR_OK) {
throw std::runtime_error("Failed to initialize Capstone");
@@ -453,7 +500,14 @@ auto Sandbox::InitEnv(std::shared_ptr<BasicPeInfo> peInfo) -> void {
throw std::runtime_error("Failed to initialize Unicorn");
}
ResoveImport();
ResolveExport();
ResolveImportExports();
// 修复导入表
cFixImprot importFixer(this);
if (!peconv::load_imports(m_peInfo->peBuffer, &importFixer)) {
throw std::runtime_error("Failed to fix imports");
}
uc_err ucErr = uc_mem_map(m_ucEngine, m_peInfo->RecImageBase,
m_peInfo->peSize, UC_PROT_ALL);
if (ucErr != UC_ERR_OK) {
@@ -464,6 +518,8 @@ auto Sandbox::InitEnv(std::shared_ptr<BasicPeInfo> peInfo) -> void {
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);
}
auto Sandbox::Run() -> void {
@@ -551,6 +607,7 @@ auto Sandbox::Run() -> void {
// 开始执行
std::cout << "Starting execution at " << std::hex << entryPoint
<< std::endl;
InitApiHooks();
err = uc_emu_start(m_ucEngine, entryPoint, m_peInfo->imageEnd, 0, 0);
if (err != UC_ERR_OK) {
std::cerr << "Emulation error: " << uc_strerror(err) << std::endl;

View File

@@ -1,6 +1,8 @@
#pragma once
#include "head.h"
#include <functional>
#include <map>
#include "head.h"
#define PAGE_SIZE 0x1000
#define CF_MASK (1 << 0)
#define PF_MASK (1 << 2)
@@ -17,8 +19,10 @@
#define HEAP_ADDRESS_32 0x5000000
#define HEAP_SIZE_32 0x5000000
#define PEB_BASE 0x80000
#define PEB_BASE 0x90000
#define TEB_BASE 0x90000
#define CMDLINE_ADDRESS 0x100000 // 命令行字符串的固定地址
#define CMDLINEW_ADDRESS 0x110000 // 宽字符命令行字符串的固定地址
#define X86_GDT_ADDR 0x30000
#define X86_GDT_LIMIT 0x1000
@@ -45,20 +49,60 @@ enum class WinVer {
kWin1019H2 = 0x0A07, // November 2019 update 19H2
kWin1020H1 = 0x0A08 // April 2020 update 20H1
};
struct _fakeApi {
std::function<void(void*, uc_engine*, uint64_t)> func;
uint32_t paramCount;
};
// 添加堆管理相关的结构定义
struct HeapBlock {
uint64_t address; // 块的起始地址
size_t size; // 块的大小
bool is_free; // 是否是空闲块
HeapBlock* next; // 下一个块
HeapBlock* prev; // 上一个块
};
struct HeapSegment {
uint64_t base; // 堆段的基址
size_t size; // 堆段的总大小
HeapBlock* blocks; // 块链表
};
class Sandbox {
friend class cFixImprot; // 声明cFixImprot为友元类
public:
Sandbox();
~Sandbox();
// Public methods
auto InitEnv(std::shared_ptr<BasicPeInfo> peInfo) -> void;
auto Run() -> void;
auto GetCapstoneHandle() const -> csh { return m_csHandle; }
auto GetUnicornHandle() const -> uc_engine* { return m_ucEngine; }
auto GetPeInfo() const -> std::shared_ptr<BasicPeInfo> { return m_peInfo; }
auto GetModuleList() const -> std::vector<std::shared_ptr<struct_moudle>> {
return m_moduleList;
}
auto EmulateApi(uc_engine* uc, uint64_t address, uint64_t rip,
std::string ApiName) -> void;
auto GetPeb32() -> X32PEB* { return &m_peb32; }
auto GetPeb64() -> X64PEB* { return &m_peb64; }
auto GetTeb32() -> X32TEB* { return &m_teb32; }
auto GetTeb64() -> X64TEB* { return &m_teb64; }
auto GetCommandLine() const -> const char* { return m_commandLine.c_str(); }
auto GetCommandLineAddress() const -> uint64_t { return CMDLINE_ADDRESS; }
auto GetCommandLineWAddress() const -> uint64_t { return CMDLINEW_ADDRESS; }
auto InitCommandLine() -> void;
// 堆管理相关的公共方法
auto CreateHeapSegment(uint64_t base, size_t size) -> HeapSegment*;
auto AllocateFromSegment(HeapSegment* segment, size_t size) -> uint64_t;
auto FreeBlock(uint64_t address) -> bool;
auto FindHeapSegment(uint64_t address) -> HeapSegment*;
auto MergeBlocks(HeapBlock* block) -> void;
auto SplitBlock(HeapBlock* block, size_t size) -> void;
std::map<uint64_t, HeapSegment*> m_heapSegments; // 堆段映射表
private:
std::shared_ptr<BasicPeInfo> m_peInfo;
@@ -75,19 +119,26 @@ class Sandbox {
uint64_t m_heapSize;
uint64_t m_heapEnd;
uint64_t m_fakeBase;
struct_gs_base m_gsBaseStruct;
X64TEB m_teb64;
X64PEB m_peb64;
X32TEB m_teb32;
X32PEB m_peb32;
struct_gs_base m_gsBaseStruct = {0};
X64TEB m_teb64 = {0};
X64PEB m_peb64 = {0};
X32TEB m_teb32 = {0};
X32PEB m_peb32 = {0};
csh m_csHandle; // Capstone handle
uc_engine* m_ucEngine; // Unicorn engine handle
std::vector<std::shared_ptr<moudle_import>> m_impFuncDict;
std::vector<std::shared_ptr<moudle_export>> m_exportFuncDict;
std::vector<std::shared_ptr<struct_moudle>> m_moduleList;
std::map<std::string, std::shared_ptr<_fakeApi>> api_map;
std::string m_commandLine; // 存储命令行字符串
auto ResoveImport() -> void;
auto SetupVirtualMachine() -> void;
auto ResolveExport() -> void;
auto PushModuleToVM(const char* dllName, uint64_t moduleBase) -> void;
auto processImportModule(const moudle_import* importModule) -> void;
auto ResolveImportExports() -> void;
auto ResolveExport(uint64_t moduleBase)
-> std::vector<std::shared_ptr<moudle_export>>;
auto InitApiHooks() -> void;
auto InitCommandLine(std::string commandLine) -> void;
};

File diff suppressed because it is too large Load Diff

View File

@@ -1 +1,97 @@
#include "sandbox_callbacks.h"
#define LOG_LEVEL 0
namespace sandboxCallbacks {
void handleCodeRun(uc_engine* uc, uint64_t address, uint32_t size,
void* userData) {
uint64_t currentRip = 0;
uint64_t currentRsp = 0;
uint64_t currentRax = 0;
auto* sandbox = static_cast<Sandbox*>(userData);
if (!sandbox) return;
// 读取当前执行的代码
auto codeBuffer = std::make_unique<uint8_t[]>(size);
if (uc_mem_read(uc, address, codeBuffer.get(), size) != UC_ERR_OK) {
return;
}
uc_reg_read(uc,
sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&currentRax);
uc_reg_read(uc,
sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RIP : UC_X86_REG_EIP,
&currentRip);
uc_reg_read(uc,
sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RSP : UC_X86_REG_ESP,
&currentRsp);
for (auto module : sandbox->GetModuleList()) {
for (auto item : module->export_function) {
const auto vmAddress = module->base + item->function_address;
if (vmAddress == currentRip) {
printf("[%s] call function %s at file address: %llx\n",
module->name, item->name, address);
sandbox->EmulateApi(uc, vmAddress, currentRip, item->name);
}
}
}
if (LOG_LEVEL > 0) {
// 使用Capstone反汇编
cs_insn* instruction;
size_t instructionCount =
cs_disasm(sandbox->GetCapstoneHandle(), codeBuffer.get(), size,
address, 0, &instruction);
if (instructionCount > 0) {
// 打印地址和反汇编结果
printf("0x%016" PRIx64 " %-12s %s\n", instruction[0].address,
instruction[0].mnemonic, instruction[0].op_str);
}
cs_free(instruction, instructionCount);
}
}
void handleMemoryRead(uc_engine* uc, uc_mem_type type, uint64_t address,
int size, int64_t value, void* userData) {
auto* sandbox = static_cast<Sandbox*>(userData);
if (!sandbox) return;
uint64_t regRax, regRip;
uc_reg_read(uc,
sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&regRax);
uc_reg_read(uc,
sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RIP : UC_X86_REG_EIP,
&regRip);
uint64_t readAddress;
auto readError =
uc_mem_read(sandbox->GetUnicornHandle(), address, &readAddress, size);
if (LOG_LEVEL > 0) {
printf(
"[handleMemoryRead] Address: %p Size: %p Rax: %p Rip: %p Error: %d "
"ReadData: %p\n",
address, size, regRax, regRip, readError, readAddress);
}
}
void handleMemoryUnmapRead(uc_engine* uc, uc_mem_type type, uint64_t address,
int size, int64_t value, void* userData) {
// 待实现
auto* sandbox = static_cast<Sandbox*>(userData);
uint64_t Rip = 0;
uc_reg_read(uc,
sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RIP : UC_X86_REG_EIP,
&Rip);
printf("[handleMemoryUnmapRead] Address: %p Size: %p Value: %p Rip: %p\n",
address, size, value, Rip);
}
void handleMemoryWrite(uc_engine* uc, uc_mem_type type, uint64_t address,
int size, int64_t value, void* userData) {
// 待实现
}
void handleSyscall(uc_engine* uc, void* userData) {
// 待实现
}
} // namespace sandboxCallbacks

View File

@@ -1,70 +1,16 @@
#pragma once
#include "sandbox.h"
namespace sandboxCallbacks {
static void handleCodeRun(uc_engine* uc, uint64_t address, uint32_t size,
void* userData) {
auto* sandbox = static_cast<Sandbox*>(userData);
if (!sandbox) return;
// 读取当前执行的代码
uint8_t* codeBuffer = new uint8_t[size];
if (uc_mem_read(uc, address, codeBuffer, size) != UC_ERR_OK) {
delete[] codeBuffer;
return;
}
// 使用Capstone反汇编
cs_insn* instruction;
size_t instructionCount =
cs_disasm(sandbox->GetCapstoneHandle(), codeBuffer, size, address, 0,
&instruction);
if (instructionCount > 0) {
// 打印地址和反汇编结果
printf("0x%016" PRIx64 " %-12s %s\n", instruction[0].address,
instruction[0].mnemonic, instruction[0].op_str);
cs_free(instruction, instructionCount);
}
delete[] codeBuffer;
}
static void handleMemoryRead(uc_engine* uc, uc_mem_type type, uint64_t address,
int size, int64_t value, void* userData) {
auto* sandbox = static_cast<Sandbox*>(userData);
if (!sandbox) return;
uint64_t regRax, regRip;
uc_reg_read(uc,
sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RAX : UC_X86_REG_EAX,
&regRax);
uc_reg_read(uc,
sandbox->GetPeInfo()->isX64 ? UC_X86_REG_RIP : UC_X86_REG_EIP,
&regRip);
uint64_t readAddress;
auto readError =
uc_mem_read(sandbox->GetUnicornHandle(), address, &readAddress, size);
printf(
"[handleMemoryRead] Address: %p Size: %p Rax: %p Rip: %p Error: %d "
"ReadData: %p\n",
address, size, regRax, regRip, readError, readAddress);
}
static void handleMemoryUnmapRead(uc_engine* uc, uc_mem_type type,
void handleCodeRun(uc_engine* uc, uint64_t address, uint32_t size,
void* userData);
void handleMemoryRead(uc_engine* uc, uc_mem_type type, uint64_t address,
int size, int64_t value, void* userData);
void handleMemoryUnmapRead(uc_engine* uc, uc_mem_type type,
uint64_t address, int size, int64_t value,
void* userData) {
// 待实现
}
void* userData);
void handleMemoryWrite(uc_engine* uc, uc_mem_type type, uint64_t address,
int size, int64_t value, void* userData);
void handleSyscall(uc_engine* uc, void* userData);
auto InitApiHooks() -> void;
static void handleMemoryWrite(uc_engine* uc, uc_mem_type type, uint64_t address,
int size, int64_t value, void* userData) {
// 待实现
}
static void handleSyscall(uc_engine* uc, void* userData) {
// 待实现
}
} // namespace sandboxCallbacks
}; // namespace sandboxCallbacks