-
-
dll文件判断方法——UPX加壳器中isdll变量
-
发表于: 2024-10-12 20:23 7193
-
前文提到UPX通过变量isdll判断是否为dll文件,因此UPX源码中搜索isdll字段,找到isdll的来源并观察UPX判断逻辑。
在src/pefile.cpp中观察到变量isdll的变化,首先默认为为非dll文件(isdll=false)
然后在函数readPeHeader中,有阅读PE文件头部以确定isdll值的语句
对代码进行分析:
根据isdll赋值的方法,写出判断dll文件的程序。对一些样本进行测试,基本验证了其正确性。代码如下(也可见附件isdll.cpp):
#include <windows.h>
#include <iostream>
#include <stdexcept>
// 函数:检查文件是否为DLL文件
bool
isDllFile(
const
char
* filePath) {
// 打开文件,使用 CreateFileA 以支持窄字符串
HANDLE
file = CreateFileA(filePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if
(file == INVALID_HANDLE_VALUE) {
throw
std::runtime_error(
"无法打开文件"
);
}
// 创建文件映射
HANDLE
fileMapping = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
if
(fileMapping == NULL) {
CloseHandle(file);
throw
std::runtime_error(
"无法创建文件映射"
);
}
// 映射文件到内存
LPVOID
fileBase = MapViewOfFile(fileMapping, FILE_MAP_READ, 0, 0, 0);
if
(fileBase == NULL) {
CloseHandle(fileMapping);
CloseHandle(file);
throw
std::runtime_error(
"无法映射文件"
);
}
// 获取DOS头(IMAGE_DOS_HEADER)
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)fileBase;
if
(dosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
// 不合法的PE文件
UnmapViewOfFile(fileBase);
CloseHandle(fileMapping);
CloseHandle(file);
throw
std::runtime_error(
"文件不是有效的PE文件"
);
}
// 获取NT头(IMAGE_NT_HEADERS)
PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((
BYTE
*)fileBase + dosHeader->e_lfanew);
if
(ntHeaders->Signature != IMAGE_NT_SIGNATURE) {
// 不合法的PE文件
UnmapViewOfFile(fileBase);
CloseHandle(fileMapping);
CloseHandle(file);
throw
std::runtime_error(
"文件不是有效的PE文件"
);
}
// 检查标志位(Flags)中的 IMAGE_FILE_DLL 位
bool
isDll = (ntHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL) != 0;
// 释放资源
UnmapViewOfFile(fileBase);
CloseHandle(fileMapping);
CloseHandle(file);
return
isDll;
}
int
main() {
const
char
* filePath =
"test.dll"
;
// 使用窄字符串
try
{
if
(isDllFile(filePath)) {
std::cout <<
"该文件是DLL文件。"
<< std::endl;
}
else
{
std::cout <<
"该文件不是DLL文件。"
<< std::endl;
}
}
catch
(
const
std::runtime_error& e) {
std::cerr <<
"错误:"
<< e.what() << std::endl;
}
return
0;
}
#include <windows.h>
#include <iostream>
#include <stdexcept>
// 函数:检查文件是否为DLL文件
bool
isDllFile(
const
char
* filePath) {
// 打开文件,使用 CreateFileA 以支持窄字符串
HANDLE
file = CreateFileA(filePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if
(file == INVALID_HANDLE_VALUE) {
throw
std::runtime_error(
"无法打开文件"
);
}
// 创建文件映射
HANDLE
fileMapping = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
if
(fileMapping == NULL) {
CloseHandle(file);
throw
std::runtime_error(
"无法创建文件映射"
);
}
// 映射文件到内存
LPVOID
fileBase = MapViewOfFile(fileMapping, FILE_MAP_READ, 0, 0, 0);
if
(fileBase == NULL) {
CloseHandle(fileMapping);
CloseHandle(file);
throw
std::runtime_error(
"无法映射文件"
);
}
// 获取DOS头(IMAGE_DOS_HEADER)
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)fileBase;
if
(dosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
// 不合法的PE文件
UnmapViewOfFile(fileBase);
CloseHandle(fileMapping);
CloseHandle(file);
throw
std::runtime_error(
"文件不是有效的PE文件"
);
}
// 获取NT头(IMAGE_NT_HEADERS)
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
他的文章
- [原创]UPX加载逻辑的处理细节分析 5569
- dll文件判断方法——UPX加壳器中isdll变量 7194
- UPX代码buildloader函数分析 2085
谁下载
看原图
赞赏
雪币:
留言: