怎么打开dll文件(运行dll文件的方法)

一、背景

二、dll注入说明

DLL注入技术,一般来讲是向一个正在运行的进程插入/注入代码的过程。我们注入的代码以动态链接(DLL)的形式存在。DLL文件在运行时将按需加载。

三、dll注入能做什么:

1.为目标进程添加新的“实用”功能;

2.需要一些手段来辅助调试被注入dll的进程;

3.为目标进程安装勾子程序(API Hook);

四、dll注入方法:    

1.修改注册表来注入dll;

2.使用CreateRemoteThread函数对运行中的进程注入dll;

3.使用SetWindowsHookEx函数对应用程序挂钩(HOOK)迫使程序加载dll;4.替换应用程序一定会使用的dll;

5.把dll作为调试器来注入;

6.用CreateProcess对子进程注入dll

(一)、修改注册表注入dll

  如果使用过Windows,那么对注册表应该不会陌生。整个系统的配置都保存在注册表中,我们可以通过修改其中的设置来改变系统的行为。首先打开注册表并定位到HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows项,如下图所示,他显示了该注册表项中的条目。

怎么打开dll文件(运行dll文件的方法)

AppInit_Dlls键值位于注册表 HKLM\Microsoft\Windows NT\CurrentVersion\Windows下面,相对于其他的注册表启动项来说,这个键值的特殊之处在于任何使用到User32.dll 的EXE、DLL、OCX等类型的PE文件都会读取这个地方,并且根据约定的规范将这个键值下指向的DLL文件进行加载,加载的方式是调用 LoadLibrary。

由于AppInit_Dlls是一种系统全局性的Hook(system-wide hook),要规避此类的Hook的确很困难,虽然使用驱动程序进行保护能够规避此类问题,但也不是非要使用驱动程序进行处理的。前文说过,只有当使用到User32.DLL这个模块的时候才会触发读取AppInit_Dlls指向的DLL,如果不使用User32.DLL,那么AppInit_Dlls是不会被使用到的。但是要让一个程序不使用User32.DLL会变得非常困难(命令行窗口没有使用User32.DLL),因为任何的窗口、消息都和这个模块有关,为了保证有良好的用户体验,100%的窗口程序都和这个模块有关。从开发角度来说,最好的一种解决办法就是将程序功能逻辑和界面逻辑完全分离,功能逻辑模块负责功能,界面逻辑模块负责界面显示,2者之间采用IPC机制进行交互,功能逻辑模块不依靠User32.DLL,,而且作为独立进程进行处理,这样就可以规避AppInit_Dlls造成的Hook了。

1.如何使用

AppInit_DLLs键的值可以是一个dll的文件名或一组dll的文件名(通过逗号或空格来分隔),由于空格是用来分隔文件名的,因此dll文件名不能含有空格。第一个dll的文件名可以包含路径,但其他的dll包含的路径将被忽略。

2.使用约定

LoadAppInit_DLLs键的值表示AppInit_DLLs键是否有效,为了让AppInit_DLLs键的值有效,需要将LoadAppInit_DLLs的值设置为1。

3.一些缺点

(1)只有调用了User32.dll的进程才会发生这种dll注入。

(2)该方法会使得所有的调用了User32.dll的程序都被注入指定的dll。

(3)这种注入会使得在应用程序的整个生命周期内被注入的dll都不会被卸载。

(二)使用CreateRemoteThread函数对运行中的进程注入dll

dll注入技术要求目标进程中的一个线程调用LoadLibrary函数来载入我们想要注入的dll,由于我们不能轻易的控制别人进程中的线程,因此这种方法要求我们在目标进程中创建一个线程并在线程中执行LoadLibrary函数加载我们要注入的dll。

主要函数

1.创建进程函数

HANDLE WINAPI CreateRemoteThread(

_In_ HANDLE hProcess,

_In_ LPSECURITY_ATTRIBUTES lpThreadAttributes,

_In_ SIZE_T dwStackSize,

_In_ LPTHREAD_START_ROUTINE lpStartAddress,

_In_ LPVOID lpParameter,

_In_ DWORD dwCreationFlags,

_Out_ LPDWORD lpThreadId

);

2.LoadLibrary加载自己的DLL

HMODULE WINAPI LoadLibrary(

_In_ LPCTSTR lpFileName

);

3.VirtualAllocEx开辟加载DLL的内存

LPVOID WINAPI VirtualAllocEx(

_In_ HANDLE hProcess,

_In_opt_ LPVOID lpAddress,

_In_ SIZE_T dwSize,

_In_ DWORD flAllocationType,

_In_ DWORD flProtect

);

4.WriteProcessMemory函数将dll文件路径的数据复制到目标进程中。

BOOL WINAPI WriteProcessMemory(

_In_ HANDLE hProcess,

_In_ LPVOID lpBaseAddress,

_In_ LPCVOID lpBuffer,

_In_ SIZE_T nSize,

_Out_ SIZE_T *lpNumberOfBytesWritten

);

6.梳理下步骤。

(2).用WriteProcessMemory函数把本进程中保存dll路径的内存中的数据拷贝到第(1)步得到的目标进程的内存中。

(4).用CreateRemoteThread函数让目标进程执行LoadLibraryW来加载被注入的dll。函数结束将返回载入dll后的模块句柄。

(5).用VirtualFreeEx释放第(1)步开辟的内存。

在需要卸载dll时我们可以在上述第(5)步的基础上继续执行以下步骤:

(7).用CreateRemoteThread函数让目标进程执行FreeLibrary来卸载被注入的dll。(其参数是第(4)步返回的模块句柄)。

如果不在上述步骤基础上执行操作,卸载dll时你需要这么做:

(1).获得被注入的dll在目标进程的模块句柄。

(2).重复上述步骤的第(6)、(7)两步。

五、操作

1.创建一个弹窗dll

使用g 编译一下生成MessageBox.dll:g –share -o MessageBox.dll MessageBox.cpp

(坑)直接使用编译使用失败

需要使用vs2019–>dll动态链接库编译

编译完成

2.使用vs2019中c 应用控制台项目

编译RemoteInject.cpp生成RemoteInject.exe

编译生成RemoteInject.exe

在这里对上面源码中的部分函数进行简单剖析:

hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);

调用OpenProcess() API,通过参数dwPID,来获取dwPID所对应进程的句柄。在得到PROCESS_ALL_ACCESS权限以后,就可以使用获取的句柄(hProcess)来控制对应进程。

pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGA_READWRITE);

为即将写入目标进程的DLL文件的路径(字符串)在目标进程空间中申请内存。

writeProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllName, dwBufSize, NULL);

注入测试

首先找到想要注入进程的PID

使用命令tasklist | findstr “nodepad ”

测试时,注入dll使用绝对路径。

普通用户权限,注入成功。

六、获取文中项目文件

七、参考文章

https://www.cnblogs.com/wf751620780/p/10730013.html

https://juejin.cn/post/7017729981627269128

https://blog.csdn.net/u013565525/article/details/27585387

若有侵权,请联系删除。

发表评论

登录后才能评论