// 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获取中文输入
最新推荐文章于 2020-05-09 21:30:21 发布