[笔记]Windows核心编程《二十二》注入DLL和拦截API(二)

简介: [笔记]Windows核心编程《二十二》注入DLL和拦截API(二)

PostThreadMessage函数

将一个队列消息放入(寄送)到指定线程的消息队列里,不等待线程处理消息就返回。

BOOLPostThreadMessage(
  DWORDidThread,
  UINTMsg,
  WPARAMwParam,
  LPARAMIParam
);

idThread:其消息将被寄送的线程的线程标识符。如果线程没有消息队列,此函数将失败。当线程第一次调用一个Win 32 USER或GDI函数时,系统创建线程的消息队列。要得到更多的信息,参见备注。

Msg:指定将被寄送的消息的类型。

wParam:指定附加的消息特定信息。

IParam:指定附加的消息特定信息。

返回值:返回线程号。

GetMessage函数

从调用线程的消息队列里取得一个消息并将其放于指定的结构。此函数可取得与指定窗口联系的消息和由PostThreadMessage寄送的线程消息。此函数接收一定范围的消息值。GetMessage不接收属于其他线程或应用程序的消息。获取消息成功后,线程将从消息队列中删除该消息。函数会一直等待直到有消息到来才有返回值。

GetMessage(
  LPMSG lpMsg,
  HWND hWnd,
  UINT wMsgFilterMin,
  UINT wMsgFilterMax
)

lpMsg:指向MSG结构的指针,该结构从线程的消息队列里接收消息信息。

hWnd:取得其消息的窗口的句柄。当其值取NULL时,GetMessage为任何属于调用线程的窗口检索消息,线程消息通过PostThreadMessage寄送给调用线程。

wMsgFilterMin:指定被检索的最小消息值的整数。

wMsgFilterMax:指定被检索的最大消息值的整数。

返回值:如果函数取得WM_QUIT之外的其他消息,返回非零值。如果函数取得WM_QUIT消息,返回值是零。如果出现了错误,返回值是-1。例如,当hWnd是无效的窗口句柄或lpMsg是无效的指针时。若想获得更多的错误信息,请调用GetLastError函数。

SendMessage函数

将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回。

LRESULT SendMessage(
    HWND hWnd,
    UINT Msg,
    WPARAM wParam,
    LPARAM IParam
)

hWnd:指定要接收消息的窗口的句柄。如果此参数为HWND_BROADCAST,则消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口,但消息不被发送到子窗口。

Msg:指定被发送的消息。

wParam:指定附加的消息特定信息。

IParam:指定附加的消息特定信息。

返回值:返回值指定消息处理的结果,依赖于所发送的消息。

GetFirstChild宏

GetFirstChild()函数其实是一个宏定义:

#define GetFirstChild(hwnd) GetTopWindow(hwnd)\

GetTopWindow函数

GetTopWindow函数检查与特定父窗口相联的子窗口z序,并返回在z序顶部的子窗口的句柄。

HWND GetTopWindow(HWND hWnd);

hWnd:被查序的父窗口的句柄。如果该参数为NULL,函数返回Z序顶部的窗口句柄。

返回值;如果函数成功,返回值为在Z序顶部的子窗口句柄。如果指定的窗口无子窗口,返回值为NULL。

FindWindow函数

FindWindow这个函数检索处理顶级窗口的类名和窗口名称匹配指定的字符串。这个函数不搜索子窗口。

HWND FindWindow(LPCSTR lpClassName,LPCSTR lpWindowName);

lpClassName:指向一个以NULL字符结尾的、用来指定类名的字符串或一个可以确定类名字符串的原子。如果这个参数是一个原子,那么它必须是一个在调用此函数前已经通过GlobalAddAtom函数创建好的全局原子。这个原子(一个16bit的值),必须被放置在lpClassName的低位字节中,lpClassName的高位字节置零。如果该参数为null时,将会寻找任何与lpWindowName参数匹配的窗口。

lpWindowName:指向一个以NULL字符结尾的、用来指定窗口名(即窗口标题)的字符串。如果此参数为NULL,则匹配所有窗口名。

返回值

如果函数执行成功,则返回值是拥有指定窗口类名或窗口名的窗口的句柄。

如果函数执行失败,则返回值为 NULL 。

挂载调用

HHO0K hHook = SetWindowsHookEx(
        WH_GETMESSAGE,
        GetMsgProc,
        hinstDll,
        0
       );
  1. 进程B中的一个线程准备将一条消息发送到一个窗口。
  2. 系统查看该线程上是否已经安装了WH_GETMESSAGE挂钩。
  3. 系统查看包含GetMsgProc函数的DLL是否被映射到进程B的地址空间中。
  4. 如果该DLL尚未被映射,系统将强制该 DLL映射到进程B的地址空间,并且将进程 B中 的DLL映像的自动跟踪计数递增1。
  5. 当D L L的hinstDll用于进程B时,系统查看该函数,并检查该 D L L的hinstDll是否与它用于进程A时所处的位置相同。
  6. 系统将进程B中的D L L映像的自动跟踪计数递增1。
  7. 系统调用进程B的地址空间中的GetMsgProc函数。
  8. 当GetMsgProc函数返回时,系统将进程B中的D L L映像的自动跟踪计数递减1。

3.1 桌面项目位置保存器实用程序 DIPS

桌面项目位置保存器实用程序 DIPS。

当你将 S 作为命令行参数传递给 DIPS时,它就创建下面这个注册表子

关键字,并且给桌面窗口上的每个项目添加一个值:

HKEY_CURRENT_USER\Software\Richter\Desktop Item Position Saver

每个项目都有一个与它一起保存的位置值。当改变屏幕分辨率以便玩游戏之前,运行 DIPS的S。当玩完游戏后,将屏幕的分辨率改为原来的状态,并且运行 DIPS R。这使得DIPS打开注册表子关键字,对于桌面上与注册表中保存的项目相匹配的每个项目来说,当运行 DIPS S时,项目的位置将被重新设置为原来的值。

原理

DIPS应用程序使用窗口挂钩将一个DIPSLib.dll插入Explorer.exe的地址空间。

Explorer.exe进程用于管理Windows的图形界面,包括开始菜单、任务栏、桌面和文件管理,如果结束这个该程序会导致Windows图形界面无法使用,就是电脑只会剩下一张壁纸,其他的东西统统消失。所以这个Explorer.exe进程的正常运行对系统的稳定性有很大的帮助。如果用户发现任务管理器中有两个或多个Explorer.exe进程,那么就要检查是否中了远控了,最好用木马专杀工具扫扫。

windows下使用Hook实现对远程进程注入DLL技术,通过共用操作系统下同一份DLL,实现对目标进程的特定消息传输,甚至达到控制的技术。

DIPS功能

DIPS主要调用DIPSLib,DIPSLib主要实现Hook以及保存屏幕信息至注册表。

DIPS主要功能:

  • 界面显示 save、resave等
  • 获取ProgMan的线程ID
  • 调用SetDPISHook和UnHook
  • 作为客户端像DIPSLib发送WM_APP消息

ProgMan是显示出来的总桌面,也是总程序,如果你向Progman窗口发送一个WM_CLOSE消息,Windows就会提醒你是否要关机。

参考 编写Windows动态壁纸(关于Windows10桌面的了解)(一)

参考 Windows动态桌面原理

可以通过spy++ 查看

DIPSLib功能

DIPSLib主要功能:

  • 导出SetDIPSHook接口用来Hook线程
  • 保存DIPS信息到注册表。(SaveListViewItemPositions/RestoreListViewItemPositions)
  • 共享数据段g_hHook、g_dwThreadIdDIPS
#pragma data_seg("Shared")
HHOOK g_hHook = NULL;
DWORD g_dwThreadIdDIPS = 0;
#pragma data_seg()
  • 作为服务端 接受处理WM_APP消息

过程

  1. 首先通过ProgMan进程,得到桌面的ListView控件的窗口句柄
HWND hWndLV = GetFirstChild(GetFirstChild(
      FindWindow(TEXT("ProgMan"), NULL)));
  1. 通过调用GetWindowThreadProcessId函数,就能够确定创建窗口的线程的ID。将这个ID传递给 SetDIPSHook函数(在DIPSLib.cpp中实现)。SetDIPSHook负责在该线程上安装一个WH_GETMESSAGE挂钩,然后调用PostThreadMessage函数,以强制Windows Explorer的线程醒来。
// Install the hook on the specified thread
     g_hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hInstDll, dwThreadId);
     bOk = (g_hHook != NULL);
     if (bOk) {
        // The hook was installed successfully; force a benign message to 
        // the thread's queue so that the hook function gets called.
        bOk = PostThreadMessage(dwThreadId, WM_NULL, 0, 0);
     }
  1. 由于已经在该线程上安装了一个 WH_GETMESSAGE挂钩,因此操作系统能够自动将DIPSLib. dll 文件插入Explorer.exe的地址空间,并且调用GetMsgProc函数。该函数首先查看它是否是初次被调用,如果是,那么它就创建一个隐藏的窗口,其标题是Wintellect DIPS,请记住,Explorer的线程正在创建这个隐藏窗口。
// 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);
  1. 调用GetMessage函数,这次函数调用将使线程进入睡眠状态,直到队列中显示一条消息为止。
  2. 服务端DIPS.dll隐藏窗口Wintellect DIPS创建完成后,客户端DIPS.exe 通过FindWindow其标题Wintellect DIPS获得其句柄,向其发送消息WM_APP,让服务端 DIPS.dll 此时处理S、R操作。
  3. 客户端DIPS.exe 发送消息WM_CLOSE
  4. SetDIPSHook(0),卸载挂钩,Explorer的地址空间中卸载DIPSLib.dll。
相关文章
|
4月前
|
JSON API 数据格式
实时获取小红书笔记详情的API使用与解析
小红书是一个以分享消费经验、生活方式为主的社交平台,拥有大量的用户和内容。为了更好地了解用户在小红书上的行为和内容,许多开发者选择使用小红书开放平台提供的API接口。本文将介绍如何通过小红书笔记详情API实现实时数据获取,并给出相应的代码示例。
|
4月前
|
存储 缓存 网络协议
dpdk课程学习之练习笔记二(arp, udp协议api测试)
dpdk课程学习之练习笔记二(arp, udp协议api测试)
67 0
|
3月前
|
API Python Windows
python3应用windows api对后台程序窗口及桌面截图并保存的方法
python3应用windows api对后台程序窗口及桌面截图并保存的方法
98 1
|
4月前
|
测试技术 API Python
小红书API接口测试 | 小红书笔记详情 API 接口测试指南
随着互联网的发展,越来越多的应用开始使用API接口来提供服务。而API接口的测试也变得越来越重要。本文将介绍如何使用Python语言进行小红书笔记详情API接口的测试。
|
1月前
|
数据采集 API 开发者
调用API接口获取小红书笔记详情数据(小红书怎么推广)
小红书平台对于其API的使用有严格的规定和限制,并且并非所有的功能和数据都通过公开API提供。关于获取小红书笔记详情的API,以下是一些建议和指导:
|
2月前
|
数据采集 安全 API
如何实时获取小红书笔记详情的API使用与解析
小红书是一个以分享消费经验、生活方式为主的社交平台,拥有大量的用户和内容。为了更好地了解用户在小红书上的行为和内容,许多开发者选择使用小红书开放平台提供的API接口。本文将介绍如何通过小红书笔记详情API实现实时数据获取,并给出相应的代码示例。
|
3月前
|
Web App开发 Rust JavaScript
Rust 笔记:WebAssembly 的 JavaScript API
Rust 笔记:WebAssembly 的 JavaScript API
93 0
|
4月前
|
数据挖掘 API
解锁新视角:小红书笔记详情API的隐藏价值探索
在数字化时代,小红书笔记详情API为我们提供了一个全新的视角,帮助我们深入挖掘隐藏的价值。通过这个强大的工具,我们可以解锁新视角,发现潜在的市场机会和用户需求,从而创造更大的商业价值。
|
4月前
|
JSON API 数据格式
使用Python调用API接口获取小红书笔记详情数据
本文将详细介绍如何使用Python编程语言调用小红书API接口,以获取小红书笔记的详情数据。我们将从以下几个方面展开讨论:1) API接口简介;2) Python环境准备;3) API密钥获取;4) 使用Requests库发送API请求;5) 解析响应数据;6) 异常处理与错误排查。
|
6月前
|
存储 缓存 API
[总结]Windows Crypto API 自动更新根证书问题原因及解决方案
[总结]Windows Crypto API 自动更新根证书问题原因及解决方案