您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  win32 api path winapi