输入法注入

系统在切换进程时会自动将输入法ime文件加载到进程内存,因此可以利用这一点实现自己的ime文件

不需要编写完整的输入法,只需要完成ImeInquire函数即可

输入法代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include<windows.h>
#include<imm.h>
#include<immdev.h>
#pragma comment(lib,"imm32.lib")
void MyFun();

BOOL WINAPI DllMain(HMODULE hModule,DWORD reason_call,LPVOID lpReserved)
{
switch(reason_call)
{
case DLL_PROCESS_ATTACH:
{
WNDCLASSEXA wndClass = { 0 };//输入法必须注册窗口类
wndClass.lpfnWndProc = DefWindowProc;
wndClass.lpszClassName = "yeanhoo";
wndClass.lpszMenuName = "yean";
wndClass.cbSize = sizeof(WNDCLASSEXA);
RegisterClassExA(&wndClass);
MyFun();
}
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
void MyFun()
{
MessageBoxA(NULL,"yeanhoo","run",MB_OK);
}

BOOL WINAPI ImeInquire(LPIMEINFO lpImeInfo,LPTSTR lpszUIClass,LPCTSTR lpszOption)
{
//这个函数会在DlllMain之后被win32调用,用来了解输入法特性
lpImeInfo->dwPrivateDataSize = 0 ;
lpImeInfo->fdwProperty = IME_PROP_KBD_CHAR_FIRST |IME_PROP_UNICODE |IME_PROP_IGNORE_UPKEYS|IME_PROP_SPECIAL_UI;
lpImeInfo->fdwConversionCaps = IME_CMODE_NATIVE |IME_CMODE_NOCONVERSION;
lpImeInfo->fdwSentenceCaps = 0 ;
lpImeInfo->fdwUICaps = UI_CAP_ROT90;
lpImeInfo->fdwSCSCaps = SCS_CAP_COMPSTR |SCS_CAP_MAKEREAD;
lpImeInfo->fdwSelectCaps = (DWORD)0;
lstrcpy(lpszUIClass,"yeanhoo");

}

加载器代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<windows.h>
#include<imm.h>
#include<stdio.h>

#pragma comment(lib,"imm32.lib")
int main()
{
PVOID m_retV;
SystemParametersInfoA(SPI_GETDEFAULTINPUTLANG,0,&m_retV,0);//检查输入环境
HKL m_hImeFile = ImmInstallIMEA("yeanhoo.ime","yean");
SystemParametersInfo(SPI_GETDEFAULTINPUTLANG,0,&m_hImeFile,SPIF_SENDWININICHANGE);//设置为默认输入法
getchar();
return 0;
}

注意:

  • ​ 编辑输入法的项目为dll项目

  • ​ 输入法需要添加资源文件包括输入法图标和(如下图)

  • dllmain()ImeInquire()是必须存在的

  • 编译好后修改dll命名为ime文件并拷贝到system32目录

  • 加载器为控制台项目

  • 安装成功后切换输入法触发弹框