首页
社区
课程
招聘
dll文件判断方法——UPX加壳器中isdll变量
发表于: 5天前 3298

dll文件判断方法——UPX加壳器中isdll变量

5天前
3298

前文提到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直播授课

上传的附件:
收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//