windows核心编程之DLL注入例子分析
来源:互联网 发布:ukcn中介怎么样 知乎 编辑:程序博客网 时间:2024/05/22 04:41
windows核心编程一书中的注入DLL的例子是一个小应用:Desktop Item Position Saver(DIPS)工具。该工具的作用是:保存桌面上图标的位置,并可在之后恢复桌面图标的位置。
实现DISP的先决条件是取得桌面各个图标的位置,我们需要先取得桌面的ListView控件的窗口句柄,向该窗口发送消息来枚举其中的元素,得到桌面图标的位置。获取桌面位置可以用下面的宏实现:
#define ListView_GetItemPosition(hwndLV, i, ppt) \ (BOOL)SNDMSG((hwndLV), LVM_GETITEMPOSITION, (WPARAM)(int)(i), (LPARAM)(POINT *)(ppt))
该宏实质上是向ListView控件发送一条LVM_GETITEMPOSITION的消息,有一个WPARAM和一个LPARAM的参数。其中LPARAM参数实际上传的是一个地址,这要求发送消息方和接收消息方必须为同一个进程,这是大多数公共控件的窗口消息的特别之处:不能跨越进程边界进行消息收发。
而桌面的ListView控件是在Windows程序管理器Explorer.exe进程中的,我们必须先把获取桌面图标的代码注入到Explorer.exe中,在Explorer.exe的进程空间中才能向ListView控件发送获取桌面图标位置的消息。这里把获取桌面图标的代码注入就是DLL注入了,DISP采用窗口挂钩注入方式。
DISP.exe的实现步骤如下:
(1)获取ListView控件的窗口句柄;要想获取ListView句柄可先用Spy++工具来查看ListView所在的窗口:
打开Spy++,在工具栏的第五个按钮按下:
弹出一个框,将中间的Finder Tool按键拖到桌面,然后按下OK键:
可以找到桌面对应的窗口:
可以看到有一个SysListView32,这个就是我们要找的桌面的ListView控件,同时,可看到SysListView32的父窗口为SHELLDLL_DefView,SHELLDLL_DefView的父窗口为Progman,所以,可获取桌面的ListView控件的窗口句柄为:
// The Desktop ListView window is the grandchild of the ProgMan window. HWND hWndLV = GetFirstChild(GetFirstChild( FindWindow(TEXT("ProgMan"), NULL)));
(2)获取创建ListView的线程标识符:
DWORD dwThreadId = GetWindowThreadProcessId(hWndLV, NULL)
(3)向创建ListView控件的线程安装一个WH_GETMESSAGE挂钩:
SetDIPSHook(dwThreadId);
这个函数是在DIPSLib.dll中实现的,展开如下:
BOOL WINAPI SetDIPSHook(DWORD dwThreadId) { BOOL bOk = FALSE; if (dwThreadId != 0) { // Make sure that the hook is not already installed. chASSERT(g_hHook == NULL); g_dwThreadIdDIPS = GetCurrentThreadId(); // Install the hook on the specified thread g_hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hInstDll, dwThreadId); bOk = (g_hHook != NULL); if (bOk) { bOk = PostThreadMessage(dwThreadId, WM_NULL, 0, 0); } } else { bOk = UnhookWindowsHookEx(g_hHook); g_hHook = NULL; } return(bOk);}
这个函数里面首先将DISP.exe的线程Id存在了一个共享变量里面,其声明如下:
#pragma data_seg("Shared")HHOOK g_hHook = NULL;DWORD g_dwThreadIdDIPS = 0;#pragma data_seg()这种声明方式是让同个DLL的多个实例可以共享同一个变量,这个变量在后面两个进程进行通信时会用到。
接着调用SetWindowsHookEx()注册挂钩到目的线程,同时,如果注册成功,则马上发送一条消息到目的线程:PostThreadMessage()。目的线程一收到消息则会马上加载DLL并调用挂钩过滤函数GetMsgProc()。
(4)目的线程(即创建ListView的线程)中,GetMsgProc()函数被执行:
LRESULT WINAPI GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) { static BOOL bFirstTime = TRUE; if (bFirstTime) { // The DLL just got injected. bFirstTime = FALSE; // Uncomment the line below to invoke the debugger // on the process that just got the injected DLL. // ForceDebugBreak(); // Create the DIPS Server window to handle the client request. CreateDialog(g_hInstDll, MAKEINTRESOURCE(IDD_DIPS), NULL, Dlg_Proc); // Tell the DIPS application that the server is up // and ready to handle requests. PostThreadMessage(g_dwThreadIdDIPS, WM_NULL, 0, 0); }该函数会在目的线程创建一个隐藏的对话框。这个对话框是用来和DISP.exe进行通信的,DISP.exe中通过发送窗口消息给这个对话框来执行命令,这个对话框的窗口过程如下:
INT_PTR WINAPI Dlg_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { chHANDLE_DLGMSG(hWnd, WM_CLOSE, Dlg_OnClose); case WM_APP: // Uncomment the line below to invoke the debugger // on the process that just got the injected DLL. // ForceDebugBreak(); if (lParam) SaveListViewItemPositions((HWND) wParam); else RestoreListViewItemPositions((HWND) wParam); break; } return(FALSE);}即收到一条WM_APP消息时,如果参数为true则保存桌面图标位置信息,如果收到的命令为false时,则恢复桌面图标的位置。SaveListViewItemPositions()和RestoreListViewItemPosition()的实现就是文章开头将的向ListView控件发送LVM_GETITEMPOSITION等消息。
同时,目的线程也可以通过之前保存的DISP.exe的线程标识符向DISP.exe发送消息:
PostThreadMessage(g_dwThreadIdDIPS, WM_NULL, 0, 0);
windows给出的这个例子程序还有很多细节可以通过源码琢磨出来,但是大体的步骤就是上面讲的几个步骤。通过这么一个实例的分析,相信可以更好的理解windows的DLL注入的使用。
阅读全文
0 0
- windows核心编程之DLL注入例子分析
- Windows 核心编程之Dll注入
- windows核心编程之DLL注入
- 基于visual c++之windows核心编程代码分析(54)实现Winlogon注入dll
- 基于visual c++之windows核心编程代码分析(54)实现Winlogon注入dll
- Windows核心编程Dll注入之远程线程
- 《Windows核心编程》之“DLL注入”(一)
- 《Windows核心编程》之”DLL注入“(二)
- 《Windows核心编程》之22远程线程注入DLL
- 基于visual c++之windows核心编程代码分析(53)在C++中嵌入汇编实现DLL注入源代码
- Windows核心编程:DLL注入和API拦截
- Windows核心编程(二十一)远程线程注入DLL
- 【Windows核心编程学习笔记】远程注入DLL
- windows核心编程---DLL注入和API拦截
- Windows 核心编程之Dll 延时加载
- Windows核心编程之DLL基础
- 基于visual c++之windows核心编程代码分析(18)远程代码注入执行
- 基于visual c++之windows核心编程代码分析 远程代码注入执行
- vijos1538 [WC2001]高性能计算机(dp)
- MySQL数据库的基本操作
- 面试时需要了解公司的相关情况
- 实现一个菜单的简单的动画效果
- yum命令
- windows核心编程之DLL注入例子分析
- Impala 3、Impala、Hbase整合
- 装饰器模式
- c++里的线程相关创建
- 单机Redis的安装以及基本操作简介
- Impala 4、Impala JDBC
- poj 1065 Wooden Sticks
- 事件分发和滑动冲突知识点总结
- POJ 1185 炮兵阵地(状压DP)