上一主题 下一主题
返回列表 发新帖

Windows输入法注入原理

[复制链接]

78

主题

532

帖子

756

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
756
发表于 2020-12-8 15:57:21 | 显示全部楼层 | 阅读模式
            
  • 引言
  • 输入法简介
  • 输入法安装
  • 输入法初始化
  • 输入法注入
  • 输入法激活
  • 输入法卸载
  • 输入法标号的获取
引言
国内输入法相关的资料相对缺乏,大部分都是抄来抄去,我参考了一部分源码和代码总结出来了这篇文章,可能依然有一定的错误(由于本人薄弱的编程功底)
推荐一部分相关的资料
IME输入:https://www.jianshu.com/p/ba7ef776112e
IME输入:https://www.cnblogs.com/freedoms ... 0/ime_learning.html
第二个好像是正版
IME输入法编程溯源https://www.cnblogs.com/freedoms ... /ime-resources.html
加密与解密第四版:https://detail.tmall.com/item.ht ... 09&ns=1&abbucket=10
易语言输入法注入:http://www.511yj.com/eyuyan-zr-srf.html
dll技术之输入法注入:https://blog.csdn.net/qq446569365/article/details/71155557
精益模块注入法注入:http://ec.125.la/
输入法简介
输入法注入利用的是ime文件,ime是一个符合windows平台输入法接口规范的dll
有以下标准接口
  1. ImeConversionList
  2. ImeConfigure
  3. ImeDestroy
  4. ImeEscape
  5. ImeInquire
  6. ImeProcessKey
  7. ImeSelect
  8. ImeSetActiveContext
  9. ImeSetCompositionString
  10. ImeToAsciiEx
  11. NotifyIME
  12. ImeRegisterWord
  13. ImeUnregisterWord
  14. ImeGetRegisterWordStyle
  15. ImeEnumRegisterWord
  16. UIWndProc
  17. StatusWndProc
  18. CompWndProc
  19. CandWndProc
复制代码
在此贴上网上的功能解释段

ImeConversionList           //将字符串或字符转换成目标字串        

ImeConfigure                //配置当前ime参数函数        

ImeDestroy                  //退出当前使用的IME        

ImeEscape                   //应用软件访问输入法的接口函数        

ImeInquire                  //启动并初始化当前ime输入法        

ImeProcessKey               //ime输入键盘事件管理函数        

ImeSelect                   //启动当前的ime输入法        

ImeSetActiveContext         //设置当前的输入处于活动状态        

ImeSetCompositionString     //由应用程序设置输入法编码        

ImeToAsciiEx                //将输入的键盘事件转换为汉字编码事件        

NotifyIME                   //ime事件管理函数      

ImeRegisterWord             //向输入法字典注册字符串      

ImeUnregisterWord           //删除被注册的字符串        

ImeGetRegisterWordStyle        

ImeEnumRegisterWord        

UIWndProc        //用户界面接口函数        

StatusWndProc    //状态窗口注册函数        

CompWndProc      //输入编码窗口注册函数        

CandWndProc      //选择汉字窗口注册函数  
输入法安装

当目标进程切换输入法的时候imme32.dll(输入法管理dll)会加载对应ime模块
我们一般是调用ImmInstallIME进行安装输入法
ImmInstallIME函数原型:HKL ImmInstallIME(LPCTSTR lpszIMEFileName, LPCTSTR lpszLayoutText);函数的两个参数分别为输入法IME文件的文件名和在控制面板的是输入法选项中显示的输入法名称。函数调用后将返回一个被安装输入法的输入法标识符(或称做输入法句柄)。示例代码:HKL hKL = ImmInstallIME("c:\\winwb86.ime", "王码五笔型输入法86版");输入法初始化输入法初始化过程调用的是ImeInquire,会在dllmain调用后第一个调用这个

  1. BOOL WINAPI ImeInquire(LPIMEINFO lpIMEInfo,LPTSTR lpszUIClass,LPCTSTR lpszOption)
  2. {
  3.     // 输入法初始化过程
  4.     lpIMEInfo->dwPrivateDataSize = 0; //系统根据它为INPUTCONTEXT.hPrivate分配空间

  5.     lpIMEInfo->fdwProperty = IME_PROP_KBD_CHAR_FIRST |
  6.                              IME_PROP_IGNORE_UPKEYS |
  7.                              IME_PROP_END_UNLOAD;

  8.     lpIMEInfo->fdwConversionCaps = IME_CMODE_FULLSHAPE |
  9.                                 IME_CMODE_NATIVE;

  10.     lpIMEInfo->fdwSentenceCaps = IME_SMODE_NONE;
  11.     lpIMEInfo->fdwUICaps = UI_CAP_2700;

  12.     lpIMEInfo->fdwSCSCaps = 0;

  13.     lpIMEInfo->fdwSelectCaps = SELECT_CAP_CONVERSION;

  14.     _tcscpy(lpszUIClass,CLSNAME_UI);  // 注意该输入法基本窗口类必须注册,否则输入法不能正常运行

  15.     return TRUE;
  16. }
  17. <code class=""></code>
复制代码
输入法注入
然后向输入法注入dll,使用的是IMESetPubString
tmpStr是dll的路径
UnloadDLL是输入法退出的时候是否卸载dll 0代表是 1代表否
loadNextIme切换目标输入法的时候是否直接切换到下一个输入法  0代表否 1代表是
DllData1 数据1
DllData2 数据2
DllData3 数据3
  1. int WINAPI IMESetPubString(LPCTSTR tmpStr,DWORD UnloadDLL,DWORD loadNextIme,DWORD DllData1,DWORD DllData2,DWORD DllData3)
  2. {
  3.     CallBackData1=DllData1;
  4.     CallBackData2=DllData2;
  5.     CallBackData3=DllData3;
  6.     OnloadDllWhenExit=UnloadDLL;
  7.     LoadNextWhenActive=loadNextIme;

  8.     memset(g_IMEDLLString,0,802);
  9.     if (lstrlen(tmpStr)>800)
  10.     {
  11.         lstrcpyn(g_IMEDLLString,tmpStr,800);
  12.     }
  13.     else
  14.     {
  15.         lstrcpy(g_IMEDLLString,tmpStr);
  16.     }
  17.     return 1;
  18. }<code class=""></code>
复制代码
输入法激活

激活的时候调用SendMessageA (WinHwnd, 80, 1, ImeHwnd)
WinHwnd是对应窗口的句柄
ImwHwnd是输入法的句柄
这里目测应该是用过spy抓取消息获取的
输入法停止注入

停止注入的时候调用IMEClearPubString
附上IMEClearPubString的源码
  1. int WINAPI IMEClearPubString()
  2. {
  3.     CallBackData1=0;
  4.     CallBackData2=0;
  5.     CallBackData3=0;
  6.     OnloadDllWhenExit=0;
  7.     LoadNextWhenActive=0;

  8.     memset(g_IMEDLLString,0,802);
  9.     return 1;
  10. }
复制代码

输入法卸载

卸载输入法的时候首先要获取输入法的标号
输入法标号的获取
输入法标号的获取首先调用api GetKeyboardLayoutList来获取输入法总数然后循环调用api LoadKeyboardLayoutA获取每个输入法的句柄通过判断输入法的句柄是否相等来获得输入法标号删除以下注三个册表内的输入法标号
  1. “Keyboard Layout\Preload\”
  2. “SYSTEM\CurrentControlSet\Control\Keyboard Layouts\”
  3. “S-1-5-21-1060284298-606747145-682003330-500\Keyboard Layout\Preload”<code class=""></code>
复制代码
然后调用api UnloadKeyboardLayout卸载键盘布局
并且删除目录下的对应ime文件以及缓存文件
缓存文件的路径以及名称在注册表的“SYSTEM\CurrentControlSet\Control\Keyboard Layouts\”下
输入法的表示路径在注册表的 “Keyboard Layout\Preload\”下        
回复

使用道具 举报

43

主题

426

帖子

619

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
619
发表于 2020-12-8 16:25:57 | 显示全部楼层
上不慕古,下不肖俗。为疏为懒,不敢为狂。为拙为愚,不敢为恶。/ 微信公众号:一之哥哥
回复

使用道具 举报

1

主题

22

帖子

100

积分

注册会员

Rank: 2

积分
100
发表于 2020-12-17 10:58:33 | 显示全部楼层
膜拜大佬(⊙x⊙;)
回复

使用道具 举报

1

主题

17

帖子

53

积分

注册会员

Rank: 2

积分
53
发表于 2020-12-17 21:34:06 | 显示全部楼层
大佬大佬
回复

使用道具 举报

0

主题

1

帖子

18

积分

新手上路

Rank: 1

积分
18
发表于 2021-1-14 21:06:37 | 显示全部楼层
回想起学Window(win32api)时的恐惧,并表示win32这玩意再也不会去碰了(哭
回复

使用道具 举报

78

主题

277

帖子

428

积分

中级会员

Rank: 3Rank: 3

积分
428
发表于 2021-1-14 22:35:32 | 显示全部楼层
我来水点经验
提及少年一词,应与平庸相斥!微信公众号——智家乐享
回复

使用道具 举报

78

主题

277

帖子

428

积分

中级会员

Rank: 3Rank: 3

积分
428
发表于 2021-1-14 22:35:47 | 显示全部楼层
ggnb,ggnb,ggnb
提及少年一词,应与平庸相斥!微信公众号——智家乐享
回复

使用道具 举报

78

主题

532

帖子

756

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
756
发表于 2021-1-15 10:44:12 | 显示全部楼层

哥哥nb
回复

使用道具 举报

78

主题

532

帖子

756

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
756
发表于 2021-1-21 23:02:04 | 显示全部楼层
widcardw 发表于 2021-1-14 21:06
回想起学Window(win32api)时的恐惧,并表示win32这玩意再也不会去碰了(哭

我学桌面学吐了...最后找不到工作,mmp
回复

使用道具 举报

发表回复

本版积分规则

快速回复 返回顶部 返回列表