Refactor import library parsing with SEH-safe function and README update
- Extract SEH-based import library parsing into a separate function for better modularity - Add new processImportWithSEH and processImportWithSEH_Internal functions to handle import parsing safely - Update README.md with more detailed project description and initial engine classification - Improve error handling and exception management during PE import directory traversal - Standardize library name processing with lowercase transformation
This commit is contained in:
@@ -243,6 +243,63 @@ bool MachineLearning::ParseRichHeader(const uint8_t* peBuffer,
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 添加一个C风格的函数处理SEH部分
|
||||
auto processImportWithSEH_Internal(const uint8_t* buffer, size_t bufferSize,
|
||||
char** libNames, size_t* libCount,
|
||||
size_t maxLibs) -> BOOL {
|
||||
__try {
|
||||
// 懒得JB处理了,累了.这里是不安全的
|
||||
size_t impRva = 0;
|
||||
size_t count = 0;
|
||||
IMAGE_DATA_DIRECTORY* impDir =
|
||||
peconv::get_directory_entry(buffer, IMAGE_DIRECTORY_ENTRY_IMPORT);
|
||||
if (impDir) {
|
||||
impRva = impDir->VirtualAddress;
|
||||
IMAGE_IMPORT_DESCRIPTOR* impDesc =
|
||||
reinterpret_cast<IMAGE_IMPORT_DESCRIPTOR*>(
|
||||
RvaToPtr(impRva, (BYTE*)buffer));
|
||||
while (impDesc && impDesc->Name != 0 && count < maxLibs) {
|
||||
char* libName = reinterpret_cast<char*>(
|
||||
RvaToPtr(impDesc->Name, (BYTE*)buffer));
|
||||
if (libName) {
|
||||
libNames[count] = libName;
|
||||
count++;
|
||||
}
|
||||
impDesc++;
|
||||
}
|
||||
*libCount = count;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
printf("skip file: (access violation)\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
auto processImportWithSEH(const uint8_t* buffer, size_t bufferSize,
|
||||
std::vector<std::string>& importedLibraries) -> void {
|
||||
const size_t MAX_LIBS = 1000; // 设置一个合理的最大值
|
||||
char* libNames[MAX_LIBS] = {0};
|
||||
size_t libCount = 0;
|
||||
|
||||
// 调用处理SEH的内部函数
|
||||
if (processImportWithSEH_Internal(buffer, bufferSize, libNames, &libCount,
|
||||
MAX_LIBS)) {
|
||||
// 将结果转换为C++对象
|
||||
for (size_t i = 0; i < libCount; i++) {
|
||||
if (libNames[i]) {
|
||||
std::string libNameStr = libNames[i];
|
||||
std::transform(libNameStr.begin(), libNameStr.end(),
|
||||
libNameStr.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); });
|
||||
importedLibraries.push_back(libNameStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<double> MachineLearning::ExtractFeatures(const uint8_t* buffer,
|
||||
size_t bufferSize) {
|
||||
// 使用libpeconv解析PE文件
|
||||
@@ -381,33 +438,7 @@ std::vector<double> MachineLearning::ExtractFeatures(const uint8_t* buffer,
|
||||
|
||||
// 获取导入DLL列表
|
||||
if (peInfo.hasImports) {
|
||||
__try {
|
||||
// 懒得JB处理了,累了.这里是不安全的
|
||||
size_t impRva = 0;
|
||||
IMAGE_DATA_DIRECTORY* impDir = peconv::get_directory_entry(
|
||||
peBuffer, IMAGE_DIRECTORY_ENTRY_IMPORT);
|
||||
if (impDir) {
|
||||
impRva = impDir->VirtualAddress;
|
||||
IMAGE_IMPORT_DESCRIPTOR* impDesc =
|
||||
reinterpret_cast<IMAGE_IMPORT_DESCRIPTOR*>(
|
||||
RvaToPtr(impRva, peBuffer));
|
||||
while (impDesc && impDesc->Name != 0) {
|
||||
char* libName = reinterpret_cast<char*>(
|
||||
RvaToPtr(impDesc->Name, peBuffer));
|
||||
if (libName) {
|
||||
std::string libNameStr = libName;
|
||||
std::transform(libNameStr.begin(), libNameStr.end(),
|
||||
libNameStr.begin(), [](unsigned char c) {
|
||||
return std::tolower(c);
|
||||
});
|
||||
importedLibraries.push_back(libNameStr);
|
||||
}
|
||||
impDesc++;
|
||||
}
|
||||
}
|
||||
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
printf("skip file: (access violation)\n");
|
||||
}
|
||||
processImportWithSEH(peBuffer, bufferSize, importedLibraries);
|
||||
}
|
||||
|
||||
// 获取节区信息
|
||||
|
||||
23
readme.md
23
readme.md
@@ -5,10 +5,25 @@
|
||||
|
||||
为什么突然想搞这个,因为在做国内安全业务的时候,我意识到,国内的平均技术水平还有很大的挖掘价值.很多人从事安全,可能也对自己的电脑上的安全软件的工作原理感兴趣.也有很多人把做安全软件视为自己的梦想.或者一个努力方向.所以我觉得,有必要花一些时间,系统的整理一下杀毒引擎的工作原理,在整理工作原理的时候我发现网上基本0资料,有也停留在2006年之前什么特征码扫描,云查杀毒.仿佛杀毒软件这玩意就是个黑盒.
|
||||
|
||||
所以,为了系统性的以及确定性的处理,我花了大概两天时间,写了一个符合现代(2025年)情况的杀毒引擎.现在我将介绍他是如何工作的.以及他的缺陷是什么.并且在文末我还会开源源码,能直接VS编译.方便大家学习
|
||||
简而言之,为了系统性的科普知识,而不是其他公众号那种胡言乱语,meme,免杀巫术,我花了大概两天时间,写了一个符合现代(2025年)情况的杀毒引擎.现在我将介绍他是如何工作的.以及他的缺陷是什么.并且在文末我还会开源源码,能直接VS编译.方便大家学习
|
||||
|
||||
## 杀毒引擎分类
|
||||
目前查杀引擎各家瞎吹的什么NGAV无非就这几种:
|
||||
1. 云查引擎
|
||||
这包括:模糊hash引擎(ssdeep,simhash等都算),模糊hash是一种算法,能比较文件相似度,具体可以看我之前的文章:
|
||||
|
||||
2.
|
||||
这包括:
|
||||
模糊hash引擎(ssdeep,simhash等都算),模糊hash是一种算法,能比较文件相似度(某些PPT叫病毒基因),具体可以看我之前的文章:
|
||||
[2021]余弦定理检测文件相似度 & 病毒样本基因检测
|
||||
https://key08.com/index.php/2021/08/19/1306.html
|
||||
hash base引擎,没什么好说的,基于sha1或者sha256等固定唯一hash
|
||||
背后的各种沙箱/人工/自动机鉴定
|
||||
2. 特征引擎
|
||||
3. ai机器学习引擎
|
||||
4. 启发式沙箱引擎
|
||||
|
||||
云引擎说起来非常复杂,属于是各家的**核心能力**,我们不讨论其实现(某些直接买了VT当云引擎的除外).所以除了1外,2,3,4往往是同时打包在一起的,
|
||||
这几个引擎各有特点,比如特征引擎不具备启发能力,纯靠人力堆.启发的沙箱引擎检出弱,很容易被针对,技术落后一代.AI机器学习引擎高检出,但是也高误报,对业务造成很大影响,to B/G基本不开这玩意.
|
||||
## 我们要做什么
|
||||
我们今天所做的,是一个机器学习+沙箱行为检测的引擎,为什么不做特征引擎,因为特征引擎太普通了,如果对其感兴趣的,可以去看yara.
|
||||
整个引擎的构造如下图所示:
|
||||
|
||||
我们需要
|
||||
Reference in New Issue
Block a user