Inline hook ImmGetCompositionStringW获取中文输入

// 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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值