Windows 操作系统通过“DLL路径搜索目录顺序”和“Know DLLs注册表项”的机制来确定应用程序所要调用的DLL的路径,之后,应用程序就将DLL载入了自己的内存空间,执行相应的函数功能。
DLL路径搜索目录顺序
1.程序所在目录
2.程序加载目录(SetCurrentDirectory)
3.系统目录即 SYSTEM32 目录
4.16位系统目录即 SYSTEM 目录
5.Windows目录
6.PATH环境变量中列出的目录
Know DLLs注册表项
Know DLLs注册表项里的DLL列表在应用程序运行后就已经加入到了内核空间中,多个进程公用这些模块,必须具有非常高的权限才能修改。
Know DLLs注册表项的路径为HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs
允许这些
Operation is CreateFile
Operation is Load Image
Path contains .cpl
Path contains .dll
Path contains .drv
Path contains .exe
Path contains .ocx
Path contains .scr
Path contains .sys
排除这些
Process Name is procmon.exe
Process Name is Procmon64.exe
Process Name is System
Operation begins with IRP_MJ_
Operation begins with FASTIO_
Result is SUCCESS
Path ends with pagefile.sys
找到符合条件的dll双击查看stack
LoadLibrary
和LoadLibraryEx
一个是本地加载,一个是远程加载,如果DLL不在调用的同一目录下,就可以使用LoadLibrary(L"DLL绝对路径")
加载。
ImpulsiveDLLHijack
Robber
DLLHijackingScanner
Rattler
测试软件路径不能有中文
result显示name not found意思就是应用中不存在dll
notepad++6.6.6在Rattler中发现Msimg32.dll是可以劫持的
vs创建一个dll项目
创建完成是这样的
加点代码,调用计算器出来
生成的dll在项目文件夹下
将生成的dll文件重命名为Msimg32.dll复制到notepad++目录下
运行notepad++就会弹出计算器了
result显示success意思就是应用中存在dll
同时也需要具备这个条件
然后查看该dll的导出表,导出表就相当于全局函数,谁都可以调用
编写dll时,有个重要的问题需要解决,那就是函数重命名——Name-Mangling。
C++的编译器通常会对函数名和变量名进行改编,这在链接的时候会出现一个严重的问题,假如dll是C++写的,可执行文件是C写的。在构建dll的时候,编译器会对函数名进行改编,但是在构建可执行文件的时候,编译器不会对函数名进行改。这个时候当链接器试图链接可执行文件的时候,会发现可执行文件引用了一个不存在的符号并报错,这里直接定义extern "C"
来告诉编译器不对变量名和函数名进行改编即可
代码如下,我们的目的就是让程序本身去LoadLibrary
去加载dll
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <stdlib.h>
extern "C" __declspec(dllexport) void Scintilla_DirectFunction();
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;
}
void Scintilla_DirectFunction()
{
system("calc");
}
这里已经说明加载了我们自己写的dll
但是我们劫持的dll已经影响到软件的正常运行,所以需要用到下面转发技术
转发技术就是加载恶意dll之后为了使软件正常运行将程序的执行过程转发到原来的执行流程
直接转发的利用方式只能在DllMain中利用
加载恶意dll后调用原dll,导出表的函数是在原dll执行的
加载恶意dll后,通过GetAddress函数获取原dll里导出表的函数的地址,在恶意dll里面通过地址调用导出表的函数
点击生成会在dll目录下生成一个cpp文件
创建一个dll项目
将cpp里面的文件复制到dllmain.cpp
头文件添加#include <stdlib.h>以及在函数入口处添加system("calc");调用计算器进行测试
生成dll的时候注意版本要选择对,软件是x86就算x86,64就选64
最终的结果
运行qq弹出计算器
这里notepad++6.6.6版本使用直接转发劫持SciLexer.dll会无法运行但是使用即时调用劫持可以运行
生成cpp文件
将cpp文件里面的内容复制到dllmain.cpp里
这里有必要说一下,在它自动生成的cpp里面是只有Windows.h的头
需要加上下面这两个头
然后在文件入口处调用下计算器测试
最后你的文件夹里一定是这样的
SciLexer.dll是你生成的dll
SciLexerOrg.dll是原来的dll
然后打开notepad就会弹出计算器了
http://www.yongsheng.site/2022/08/24/DLL%E5%8A%AB%E6%8C%81/
https://cloud.tencent.com/developer/article/1951503