Dll注入技术之输入法注入
输入法注入原理是利用Windows系统中在切换输入法需要输入字符时,系统就会把这个输入法需要的ime文件装载到当前进程中,而由于这个Ime文件本质上只是个存放在C:\WINDOWS\system32目录下的特殊的DLL文件,因此我们可以利用这个特性,在Ime文件中使用LoadLibrary()函数待注入的DLL文件。
1.编写Ime文件
输入法的Ime文件其实就是个显式导出19个特殊函数的DLL文件。如下图所示:
- 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 //选择汉字窗口注册函数
如果想编写输入法程序,那么这19个导出函数都需要仔细的研究,但是对于只想实现注入的我们,现在只需要对ImeInquire()有比较深的认识就可以了。ImeInquire()是启动并初始化当前Ime输入法函数,他的声明如下:
- BOOL WINAPI ImeInquire(LPIMEINFO lpIMEInfo,LPTSTR lpszUIClass,LPCTSTR lpszOption)
第一个参数lpIMEInfo比较重要,用于输入对Ime输入法初始化的内容结构,如果这个结构填写错误,就会导致输入法不能正常运行。第二个参数是输入一个class类名,我们需要先使用RegisterClassEx()注册出一个窗口类。初始化ImeInquire()主要代码如下所示:
- //启动并初始化当前ime输入法
- BOOL WINAPI ImeInquire(LPIMEINFO lpIMEInfo,LPTSTR lpszUIClass,LPCTSTR lpszOption)
- {
- //输入法初始化过程
- //系统根据它为INPUTCONTEXT.hPrivate分配空间
- lpIMEInfo->dwPrivateDataSize = 0;
- lpIMEInfo->fdwProperty = IME_PROP_KBD_CHAR_FIRST |
- IME_PROP_IGNORE_UPKEYS |
- IME_PROP_END_UNLOAD;
- lpIMEInfo->fdwConversionCaps = IME_CMODE_FULLSHAPE |
- IME_CMODE_NATIVE;
- lpIMEInfo->fdwSentenceCaps = IME_SMODE_NONE;
- lpIMEInfo->fdwUICaps = UI_CAP_2700;
- lpIMEInfo->fdwSCSCaps = 0;
- lpIMEInfo->fdwSelectCaps = SELECT_CAP_CONVERSION;
- // 注意该输入法基本窗口类必须注册,否则输入法不能正常运行
- _tcscpy(lpszUIClass,CLSNAME_UI);
- return TRUE;
- }
注册出一个窗口类的主要代码如下:
- BOOL ImeClass_Register(HINSTANCE hInstance)
- {
- WNDCLASSEX wc;
- wc.cbSize = sizeof(WNDCLASSEX);
- wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS | CS_IME;
- wc.lpfnWndProc = UIWndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 2 * sizeof(LONG);
- wc.hInstance = hInstance;
- wc.hCursor = LoadCursor( NULL, IDC_ARROW );
- wc.hIcon = NULL;
- wc.lpszMenuName = (LPTSTR)NULL;
- wc.lpszClassName = CLSNAME_UI;
- wc.hbrBackground = NULL;
- wc.hIconSm = NULL;
- if( !RegisterClassEx( (LPWNDCLASSEX)&wc ) )
- return FALSE;
- return TRUE;
- }
CLSNAME_UI是一个宏定义,如下:
- #define CLSNAME_UI _T("DLLCLASSNAME")
在DllMain进程加载的过程中注册窗口类,主要代码如下:
- case DLL_PROCESS_ATTACH:
- if(!ImeClass_Register(hinstDLL)) return FALSE;
- //这里填写要load的DLL的路径
- g_hModule = LoadLibrary(_T("D:\\MyDll\\ImeInject\\Debug\\MfcImeInjectDll.dll"));
- if (!g_hModule)
- {
- MessageBox(NULL,_T("模块没有load成功"),_T("提示"),MB_OK);
- }
- break;
PS: 编写DLL时需要注意,当作IME文件的Dll需要有版本信息,Version资源中FILETYPE为VFT_DRV, FILESUBTYPE为VFT2_DRV_INPUTMETHOD,否则调用ImmInstallIME安装时会失败
2.编写装载输入法程序:
装载输入法的基本逻辑就是将他们编写的输入法设置为默认输入法,这样只要系统中所有进程都会默认加载他们的恶意输入法程序。
黑客们首先需要得到系统当前的默认的输入法,以便恢复时使用。然后需要将ime文件拷贝到C:\WINDOWS\system32目录下,最后将装载成功后将我们的输入法设置成为默认输入法,主要代码如下:
- void CMfcImeInjectDlg::OnBnClickedAttach()
- {
- // TODO: 在此添加控件通知处理程序代码
- //得到默认的输入法句柄并保存
- ::SystemParametersInfo(
- SPI_GETDEFAULTINPUTLANG,
- 0,
- &m_retV,
- 0);
- //拷贝到system目录,只有ime文件在system32下才能装载成功
- CopyFile(
- _T("D:\\MyDll\\ImeInject\\Debug\\MyImeDll.ime"),
- _T("C:\\WINDOWS\\system32\\MyImeDll.ime"),
- FALSE);
- //装载输入法
- m_hImeFile = ImmInstallIME(
- _T("MyImeDll.ime"),
- _T("我的输入法"));
- if( ImmIsIME(m_hImeFile) )
- {
- //设置为默认输入法
- SystemParametersInfo(
- SPI_SETDEFAULTINPUTLANG,
- 0,
- &m_hImeFile,
- SPIF_SENDWININICHANGE);
- MessageBox(_T("安装输入法成功"));
- }
- }
3.编写卸载输入法:
当新建进程不再需要注入时,我们就需要卸载输入法。卸载输入法时需要先判定系统当前的输入法不是其原有默认输入法,确认无误后将系统的默认输入法恢复后,再将恶意输入法卸载即可,主要代码如下:
- void CMfcImeInjectDlg::OnBnClickedDettach()
- {
- // TODO: 在此添加控件通知处理程序代码
- ::SystemParametersInfo(
- SPI_SETDEFAULTINPUTLANG,
- 0,
- &m_retV,
- SPIF_SENDWININICHANGE);
- if (UnloadKeyboardLayout(m_hImeFile))
- {
- MessageBox(_T("输入法卸载成功"));
- }
- }
输入法注入的实现需要对输入法IME文件的生成有所了解,API使用较多,所以实现起来比较难,但是由于系统存在多个输入法,被注入进程很难判别当前是可信赖输入法还是用于注入的恶意输入法,所以难以阻止,大大提高了注入的几率。
Dll注入技术之输入法注入的更多相关文章
- DLL注入技术(输入法注入)
输入法注入原理 IME输入法实际就是一个dll文件(后缀为ime),此dll文件需要导出必要的接口供系统加载输入法时调用.我们可以在此ime文件的DllMain函数的入口通过调用LoadLibrary ...
- Dll注入技术之ComRes注入
DLL注入技术之ComRes注入 ComRes注入的原理是利用Windows 系统中C:\WINDOWS\system32目录下的ComRes.dll这个文件,当待注入EXE如果使用CoCreateI ...
- Dll注入技术之APC注入
APC注入的原理是利用当线程被唤醒时APC中的注册函数会被执行的机制,并以此去执行我们的DLL加载代码,进而完成DLL注入的目的,其具体流程如下: 1)当EXE里某个线程执行到SleepEx( ...
- 注入技术--LSP劫持注入
1.原理 简单来说,LSP就是一个dll程序. 应用程序通过winsock2进行网络通信时,会调用ws2_32.dll的导出函数,如connect,accept等. 而后端通过LSP实现这些函数的底层 ...
- Dll注入技术之注册表注入
DLL注入技术之REG注入 DLL注入技术指的是将一个DLL文件强行加载到EXE文件中,并成为EXE文件中的一部分,这样做的目的在于方便我们通过这个DLL读写EXE文件内存数据,(例如 HOOK EX ...
- <ReversingEngineering>关于windows32位系统下的dll注入技术经验汇
上个学期把自己闷在图书馆一直在看关于逆向工程技术方面的书,从入门到初级,现在也敢说自己一条腿已经迈进了这片知识的大门里,因为该博客刚开通先将一些经验记录下来,也是留给自己一方面做个参照. <逆向 ...
- HOOK -- DLL的远程注入技术详解(1)
DLL的远程注入技术是目前Win32病毒广泛使用的一种技术.使用这种技术的病毒体通常位于一个DLL中,在系统启动的时候,一个EXE程序会将这个DLL加载至某些系统进程(如Explorer.exe)中运 ...
- DLL的远程注入技术
DLL的远程注入技术是目前Win32病毒广泛使用的一种技术.使用这种技术的病毒体通常位于一个DLL中,在系统启动的时候,一个EXE程序会将这个DLL加载至某些系统进程(如Explorer.exe)中运 ...
- Dll注入技术之消息钩子
转自:黑客反病毒 DLL注入技术之消息钩子注入 消息钩子注入原理是利用Windows 系统中SetWindowsHookEx()这个API,他可以拦截目标进程的消息到指定的DLL中导出的函数,利用这个 ...
随机推荐
- springcloud笔记一
微服务的概述 什么是微服务? 现今微服务界没有一个统一的.标准的定义 微服务化的核心就是将统一的一站式应用,根据业务拆分成一个一个的服务,彻底的去耦合,每一个微服务提供单个业务功能的服务,一个服务做一 ...
- 使用用Intellij Idea从Github上获取代码
1.打开File菜单,选择Setting,在Version Control下找到Github. 2.分别在Login与Password中输入自己在Github注册的用户名和密码,然后点击Test按钮: ...
- Shiro学习(4)INI配置
之前章节我们已经接触过一些INI配置规则了,如果大家使用过如spring之类的IoC/DI容器的话,Shiro提供的INI配置也是非常类似的,即可以理解为是一个IoC/DI容器,但是区别在于它从一个根 ...
- js (ECMAScript) 对数据处理的 方法、属性总结
注意:原生类型的数据本身是没有属性.方法的.但是 有的原始类型(如 string),当他 调用属性或方法时,JS引擎会先对原始类型数据进行包装(即隐式的转换为相应的对象) https://www.c ...
- Unity通过Jar包调用Android
Unity通过Jar包调用Android 我们会需要面对下面几个问题,我们一个一个来解决: 怎样在Android Studio中打Jar包 怎样打一个Unity使用的Jar包 怎样在Unity工程中使 ...
- 剑指offer第二版面试题6:重建二叉树(JAVA版)
题目:输入某二叉树的前序遍历和中序遍历的结果,请重新构造出该二叉树.假设输入的前序遍历和中序遍历的结果中不包含重复的数字.例如输入的前序遍历序列为{1,2,4,7,3,5,6,8}和中序遍历为{4,7 ...
- 反射与类加载之反射基本概念与Class(一)
更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章将从以下几个内容来阐述反射与类加载: [三种获取Class对象的方式] [ ...
- 深入分析Synchronized原理
前言 记得开始学习Java的时候,一遇到多线程情况就使用synchronized,相对于当时的我们来说synchronized是这么的神奇而又强大,那个时候我们赋予它一个名字“同步”,也成为了我们解决 ...
- 2-Ubuntu命令安装mysql服务器和客户端及安装后的简单验证操作
转自: https://www.cnblogs.com/zhuyp1015/p/3561470.html 安装完成之后可以使用如下命令来检查是否安装成功: sudo netstat -tap | ...
- webpack 配置之入门二(css 篇)
在项目中我们通过 css 来美化页面,css 也成为了网站不可或缺的一部分,这章节主要介绍 webpack 处理 css 部分, 1.webpack 处理 css 在 webpack 中,我们通过 s ...