Inline hook ImmGetCompositionStringW获取中文输入
2015-01-23 20:30
411 查看
// dllmain.cpp : 定义 DLL 应用程序的入口点。 // 本程序通过hook ImmGetCompositionStringW获取中文输入记录 // #include "stdafx.h" #define OPCODESIZE 6 #define INFO_BUFFER_SIZE 32767 typedef BOOL(WINAPI *lpImmGetCompositionString)(HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen); BOOL WINAPI myImmGetCompositionString( HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen); VOID WINAPI BeginRedirect(LPVOID); lpImmGetCompositionString lpOrigImmGetCompositionString = NULL; BYTE oldBytes[OPCODESIZE] = {0}; BYTE JMP[OPCODESIZE] = {0}; DWORD oldProtect, myProject = PAGE_EXECUTE_READWRITE; WCHAR wzDbg[512] = {NULL}; BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { WCHAR wzProcName[MAX_PATH] = {NULL}; WCHAR wzUserName[INFO_BUFFER_SIZE] = {NULL}; DWORD wzUserNameLen = INFO_BUFFER_SIZE; HMODULE hIMM32 = 0; switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: GetModuleFileNameW( NULL, wzProcName, MAX_PATH); if ( GetUserNameW( wzUserName, &wzUserNameLen)) { if ( (lstrcmpiW( wzUserName, L"SYSTEM") == 0) || (lstrcmpiW( wzUserName, L"LOCAL SERVICE") == 0) || (lstrcmpiW( wzUserName, L"NETWORK SERVICE") == 0) ) { break; } } OutputDebugStringW( wzProcName); //获取初始函数的首地址 //hIMM32 = GetModuleHandleW( L"IMM32.dll"); hIMM32 = LoadLibraryW( L"IMM32.dll"); if ( hIMM32 == NULL) { #ifdef _DEBUG OutputDebugStringW( L"load IMM32.dll failed!\r\n"); #endif break; } else { #ifdef _DEBUG wsprintfW( wzDbg, L"IMM32.dll address is %u\r\n", hIMM32); OutputDebugStringW( wzDbg); #endif } lpOrigImmGetCompositionString = (lpImmGetCompositionString)GetProcAddress( hIMM32, "ImmGetCompositionStringW"); if ( lpOrigImmGetCompositionString == NULL) { #ifdef _DEBUG wsprintfW(wzDbg, L"get ImmGetCompositionStringW failed!error = %d\r\n", GetLastError()); OutputDebugStringW( wzDbg); #endif } else { #ifdef _DEBUG OutputDebugStringW( L"get ImmGetCompositionStringW successed!\r\n"); wsprintfW( wzDbg, L"myImmGetCompositionString = %d, lpOrigImmGetCompositionString = %d\r\n", (DWORD)myImmGetCompositionString, (DWORD)lpOrigImmGetCompositionString); OutputDebugStringW( wzDbg); #endif BeginRedirect(myImmGetCompositionString); } case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } VOID WINAPI BeginRedirect(LPVOID lpNewFunAddr) { DWORD dwJmpSize; BYTE tempJMP[OPCODESIZE] = {0xE9,0x90,0x90,0x90,0x90,0xC3}; //检查参数是否合法 if ( lpNewFunAddr == 0) { #ifdef _DEBUG OutputDebugStringW( L"非法参数!"); #endif return; } memcpy(JMP, tempJMP, OPCODESIZE); dwJmpSize = ((DWORD)lpNewFunAddr - (DWORD)lpOrigImmGetCompositionString - 5); //计算跳转距离 #ifdef _DEBUG wsprintfW( wzDbg, L"lpNewFunAddr = %d , lpOrigImmGetCompositionString = %d\r\n", (DWORD)lpNewFunAddr, (DWORD)lpOrigImmGetCompositionString); OutputDebugStringW( wzDbg); wsprintfW( wzDbg, L"jmp %d, distance is %d\r\n", lpNewFunAddr, dwJmpSize); OutputDebugStringW( wzDbg); #endif //改变函数前6个字节页属性 VirtualProtect((LPVOID)lpOrigImmGetCompositionString, OPCODESIZE, PAGE_EXECUTE_READWRITE, &oldProtect); //保存原函数前6个字节的机器码 memcpy(oldBytes, lpOrigImmGetCompositionString, OPCODESIZE); //补齐跳转距离 memcpy(&JMP[1], &dwJmpSize, 4); //把跳转到自定义函数的机器码复制到原函数前5个字节 memcpy(lpOrigImmGetCompositionString, JMP, OPCODESIZE); //还原初始页属性 VirtualProtect((LPVOID)lpOrigImmGetCompositionString, OPCODESIZE, oldProtect, NULL); } BOOL WINAPI myImmGetCompositionString( HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen) { //进入自定义的函数中首先需要还原原始函数的前6字节的操作码 VirtualProtect( (LPVOID)lpOrigImmGetCompositionString, OPCODESIZE, PAGE_EXECUTE_READWRITE, &oldProtect); memcpy(lpOrigImmGetCompositionString, oldBytes, OPCODESIZE); //还原完之后调用原函数 BOOL bRetValue = lpOrigImmGetCompositionString( hIMC, dwIndex, lpBuf, dwBufLen); //还原为hook后的操作码 memcpy(lpOrigImmGetCompositionString, JMP, OPCODESIZE); //还原页属性 VirtualProtect( (LPVOID)lpOrigImmGetCompositionString, OPCODESIZE, oldProtect, NULL); OutputDebugStringW((LPWCH)lpBuf); return bRetValue; }
相关文章推荐
- Inline hook ImmGetCompositionStringW获取中文输入
- Inline hook ImmGetCompositionStringW获取中文输入
- Inline hook ImmGetCompositionStringW获取中文输入
- Inline hook ImmGetCompositionStringW获取中文输入
- Inline hook ImmGetCompositionStringW获取中文输入
- Inline hook ImmGetCompositionStringW获取中文输入
- Inline hook ImmGetCompositionStringW获取中文输入
- Inline hook ImmGetCompositionStringW获取中文输入
- request用getQueryString()获取参数中文转码问题
- WinAPI: midiInGetID - 获取输入设备 ID
- request用getQueryString()获取参数中文转码问题
- c++中字符输入函数cin.getline在输入char与string时的不同
- 从内部和外部的js文件中获取ASPX页面的控件ClientID(get control reference from inline and external javascript)
- 从内部和外部的js文件中获取ASPX页面的控件ClientID(get control reference from inline and external javascript)
- VC6.0 中 getline(cin, string) 需按两次回车解决方法,getiline输入时的用法
- WinAPI: waveInGetPosition - 获取当前输入设备的输入位置
- 关于HOOK截入中文输入
- How to get MetaData on client side in WCF?如何在客户端获取WCF service的元数据
- Inline Hook IofCallDriver 截获所有IRP
- Inline Hook IofCallDriver 截获所有IRP