Windows下DLL注入可执行程序(EXE)在操作过程中注入动态库并加载指定的操作线程,以实现操作目标过程的内存或读取指定的数据。
举个栗子:
例如,在之前的虚拟化项目中,有安全U盘配套软件,U如果使用普通的重定向,只能识别非加密分区,因为我们没有将加密分区重定向到虚拟化服务器。如果我们想在检测到安全U盘接入后立即收到通知,并将安全U盘的所有分区远程重定向和隔离。您可以在原安全U盘软件中注入相应的DLL,监控是否有安全U盘接入信息,并在安全U盘接入时调用我们的重定向和隔离驱动服务,实现相应的功能。这样,在加密U盘软件用户解锁密码输入正确后,可以立即重定向和隔离加密分区Session里。
DLL注入的方法1、DLL一个注入的例子
我们可以调用SetWindowLongPtr让内存块中的窗口过程指向新的(我们自己的)WndProc。
SetWindowLongPtr(hWnd, GWLP_WNDPROC, MySubclassProc) ;然而,从另一个过程中创建的窗口衍生子窗的问题是,子窗的窗口过程在另一个地址空间中。这样,当函数成功时,访问新的窗口过程 MySubclassProc ,有问题,因为 MySubclassProc 地址将是不可预测的。
2.使用注册表注入DLL
HKEY_LOCAL_MACHINE/Software/Microsoft /Windows NT/CurrentVersion/Windows/
我们可以在注册表中添加它AppInit_Dlls键的值,可能包含一个DLL文件名或一组DLL为了让系统使用文件名(通过空格或逗号分隔) 我们还应该创建一个名称LoadAppInit_Dlls,类型为DWORD并将其值宿设为1。
当User.dll当它被映射到一个新的过程时,它收到DLL_PROCESS_ATTACH通知。
当User.dll当它被映射到一个新的过程时,它收到DLL_PROCESS_ATTACH通知。当User.dll处理时,将获得上述注册表 并调用键值LoadLibrary加载字符串中指定的每个字符DLL。当系统载入每个系统时DLL它们会被调用DllMain函数和参数 fdwReason的值设为DLL_PROCESS_ATTACH,这样每个DLL能够初始化自己。
在用来注入DLL这是所有方法中最方便的一种。但这种方法也有一些缺点:
- 我们的DLL它只会映射到那些使用它的人User.dll的进程中。所有基于GUI所有了所有的应用程序User.dll,但大部分基于CUI不会使用应用程序。
- 我们的DLL回到每个基础GUI但我们可能只想把它放在应用程序中DLL注入一个或几个应用程序。
- 我们的DLL回到每个基础GUI在应用程序中,它将永远存在于应用程序终止前的地址空间中。
3、使用Windows挂钩来注入DLL通过调用SetWindowsHookEx安装挂钩:
HHOOK hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc,hInstDll, 0);
并注入注册表DLL与方法相比,这种方法允许我们不需要它DLL从过程的地址空间中取消映射:
BOOL UnhookWindowsHookEx(HHOOK hHook);
目前还不清楚是什么,估计要看程序的实现。
4.注入远程线程DLLDLL注入的一般步骤如下:
(1)注入过程ID dwRemoteProcessId;
(2)注入DLL完整路径,并将其转换为宽字符模式pszLibFileName;
(3)利用Windows API OpenProcess打开宿主过程,以下选项应打开:
a. PROCESS_CREATE_THREAD:允许在宿主过程中创建线程;
b. PROCESS_VM_OPERATION:允许在宿主的过程中VM操作;
c. PROCESS_VM_WRITE:宿主进程允许VM写。
(4)利用Windows API VirtualAllocEx远程线程中的函数VM中分配DLL完整路径宽字符所需的存储空间,并利用Windows API WriteProcessMemory函数将完整路径写入存储空间;
(5)利用Windows API GetProcAddress取得Kernel32模块中LoadLibraryW函数地址,该函数将作为随后启动的远程线程的入口函数;
(6)利用Windows API CreateRemoteThread启动远程线程,将LoadLibraryW远程线程的入口函数地址,完全存储在宿主过程中被分配的空间中DLL作为线程入口函数的参数,路径应另行启动DLL;
(7)清理现场。以下是一段示例代码:
//打开目标流程
HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,g_Pid);
if (!hProcess)
{
AfxMessageBox(TEXT(\\"打开过程失败\\"));
return;
}
///在目标过程中申请内存区域 来存放DLL路径
LPVOID pRemoteBase=VirtualAllocEx(hProcess,NULL,0x1000,MEM_COMMIT,PAGE_READWRITE);
if 电脑知识 (pRemoteBase==NULL)
{
AfxMessageBox(TEXT(\\"内存区申请失败\\"));
return;
}
///在目标过程中写入DLL路径 写入长度 1 字符串终止符
if (!WriteProcessMemory(hProcess,pRemoteBase,(LPTSTR)(LPCTSTR)DllPath,DllPath.GetLength() 1,NULL))
{
AfxMessageBox(TEXT(\\"过程写入失败\\"));
///失败释放原申请的内存区域 撤销内存页面的提交状态
VirtualFreeEx(hProcess,pRemoteBase,0x1000,MEM_DECOMMIT);
return;
}
//得到LoadLibraryA的函数地址 因为Kernel32的加载地址在每个应用程序中都是一样的
LPTHREAD_START_ROUTINE pfn=(LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(\\"Kernel32.dll\\"),\\"LoadLibraryA\\");
//创建远程线程 执行加载
HANDLE hRemoteThread = CreateRemoteThread(hProcess,NULL,0,pfn,pRemoteBase,0,NULL);
if (hRemoteThread==NULL)
{
AfxMessageBox(TEXT(\\"创建远程线程失败\\"));
///释放原申请的内存区域 撤销内存页面的提交状态
VirtualFreeEx(hProcess,pRemoteBase,0x1000,MEM_DECOMMIT);
return;
}
AfxMessageBox(TEXT(\\"成功注入\\"));
//等待线程退出
WaitForSingleObject(hRemoteThread,-1);
///释放原申请的内存区域 撤销内存页面的提交状态
VirtualFreeEx(hProcess,pRemoteBase,0x1000,MEM_DECOMMIT);
///关闭句柄
CloseHandle(hRemoteThread);
CloseHandle(hProcess);点评:SetWindowsHookEx就是钩子
,窗口程序的特定消息,如程序键盘敲击事件,原则上可以用来钩住特定线程I/O系统驱动的filter类型驱动,因为,因为它只能是特定事件的消息。第四种是最强大的,想要不受限制的。第四种是最强大、最不受限制的。例如,一些客户端可以这样注入csrss.exe,实现后台守护自己,避免被杀,除非想关机,没事,反正我也不用玩。再比如可以注入大家常用的。QQ程序,然后截取QQ聊天信息,然后发送给自己的服务器。
提醒:慎用好方法。Windows这使得360等流氓软件如此强大软件如此强大。
另外x64的WindowsVista因为系统后面有ProGuard和Session隔离特性后,实现注入需要增加跨度Session这里提到的注入方法主要针对32位Windows操作系统架构。相关文章链接:
##后期会介绍更多关于关于更多的关于Windows, Linux, C语言等相关知识点,以及牛人的工作经验工作经验等相关内容IT技术兴趣!
感觉不错,请点赞、分享或收藏
↓↓↓请关注:
IT科研室作者:
Kevin创作和分享不端原创文字,不装梦有趣!感觉不错,请点赞、分享或收藏↓↓↓请关注:IT科研室作者:Kevin创作和分享不端原创文字,不装梦有趣!电脑知识