输入法注入

来源:互联网 发布:linux物理内存分配 编辑:程序博客网 时间:2024/05/16 15:21

                                                                                      输入法注入

    整理一下输入法注入相关,思路很简单,很容易理解,但是,坑了好几天。已经无力吐槽。

    下面说了下基本原理以及在刚接触这个的时候的一些事,如果是想看结论和具体实现的直接搜索Mark00123:跳过去就行了。


原理:

IME:输入法相关文件,比如说你安装了输入法A,那么通常是会有两个或者多个IME文件,那搜狗为例(首先可以简单的把IME看成是一个dll文件)。

 

 

搜狗输入法里还多了TSF相关,这个这里不讨论。

上面那个SysWOW64里面的那个ime32位程序加载的,下面System32文件夹下面的那个则是32位程序加载的。

可以简单的把IME看成是dll,只是需要设置几个地方,然后在改下后缀名字就可以了。


通常IME会导出一些标准的输入法相关接口:

ImeConversionList

ImeConfigure

ImeDestroy

ImeEscape

ImeInquire

ImeProcessKey

ImeSelect

ImeSetActiveContext

ImeSetCompositionString

ImeToAsciiEx

NotifyIME

ImeRegisterWord

ImeUnregisterWord

ImeGetRegisterWordStyle

ImeEnumRegisterWord

而这些函数中很多都是不重要的,进行编程的时候可以不去具体实现。

比如搜狗输入法的导出函数列表:


那然后网上几乎所有的思路都是如下:

1.创建相关ime工程。

2.导出相关接口函数,然后可以都是空,除了在ImeInquire里面实现相关,比如这样:


然后还强调dll入口必须要注册窗口类:



上面那样。

3.然后在把相关文件拷贝到相关位置,最后用输入法安装函数安装,然后设置成默认输入法(为了激活已经开启的窗口可以POST几下)。

    看了N多个博客,也下载了N多个例子程序都是几乎一样的(当然很多博客都是一模一样的)。

然后我就是跟着这个思路去做,毕竟也没啥开发量,就是简单的导出空接口再实现几个东西就行了。结果是各种出现问题,后面会一一总结。但是最大的一个问题就是ime加载问题。比如我实现好了一个ime,然后拷贝到相关目录下,然后安装。安装成功之后可以看到输入法里增加了我自己的输入法程序,并且ico等都加载出来了。这个时候我打开一个32位程序,弹出了我在imeDllMain里的那个输出标记:


    然后我再一次打开其他的32位程序,发现这个DllMain函数都没有被调用。反复还原虚拟机,最终都是这个样子,后来找到了一些别人写好的例子,发现结果一样。就算是后期POST相关消息激活也不是100%注入。这让我很是蛋疼,尝试了很多解决的办法。期初是检查各种导出函数接口,看看有没有错。然后在看看网上的例子的接口怎么导出的。弄了好久,没有什么结果。还是那个现象(我测试的环境都是WIN764 一共在四台不同电脑上进行过多次测试)。甚至直接在DllMain后面或者ImeInquire函数里直接释放ime文件。当然这样会导致调用者崩溃。还发现DllMain的返回值如果是FALSE的话,会有被加载两次的时候,但是第三次就加载不起来了。这种不是我要的结果。

    但是要非常明确的提示一点,就是有可能一直我自己创建的工程都是有BUG的导致只加载了一次,虽然尝试过很多次创建,也下载过别人的结果都是这样。

    期初我挺无语的。为什么网上的关于这个的说明博客几乎都是一模一样。下载了很多例子代码结果都是上面我说的那个加载一次问题。然后也问了很多人,并没有得到想要的答案。虽然有的时候直接 拿来主义 挺好的,毕竟不用重复造轮子,所有的东西都是这样拿来使用。就连博客都直接抄过来了的,哎。最后到底得到了什么呢?

    但是现在的更重要的是要解决问题。在胡乱改胡乱测试的时候我发现一个可行的方法,就是ime里什么都别实现,什么都别导出,这样的话ImmInstallIME函数是可以安装上的,那些在博客里说如果不注册窗口类,如果不实现ImeInquire相关的就会导致ImmInstallIME失败的真是极强的误导性(但是还是那句话,我说的这些都是建立在我目前的手头机器上测试结果的)。废话说多了。直接说解决方案:


Mark00123:

1.vs创建一个dll项目:

    至于干活的地方可以添加在DllMain里,通常可以是在这里直接load另一个dll,然后在这里通过获取本地路径的方式来判断目前加载了这个dll(ime)的是不是要处理的程序。


2.项目相关属性修改:


创建资源版本文件:


然后有两个位置要修改:


然后在添加个ico文件作为输入法的显示ico


这个ico在安装成功切到这个输入法的时候会显示在这个位置:


这样可以认为ime文件就编写完了,当然如果是自己要加其他功能自己加就行了。

3.编写输入法安装/卸载程序:


然后就是说几个安装前的准备以及卸载后的其他清理工作:

    安装前要把生成的输入法安装程序以及***.ime文件放在同一个目录下,然后在把***.ime拷贝到C:\Windows\SysWOW64目录下。当然这个是32位的ime,如果想同时注入64位程序的话,在编译一个64位的ime,然后拷贝到C:\Windows\System32目录下,之后再调用上面的安装函数进行安装,这里有一个问题需要注入,就是说如果是你想同时安装32位和64位的输入法,是调用两次安装程序,还是只调用一次安装程序,如果只调用一次的话那个是32的还是64的等等一些问题。这个地方我自己手动试验了一下,得出的结论是这样,如果是想只注入32位的程序,也就是指安装32位输入法,那个就是32位安装程序+32ime,拷贝32imeSysWow64下就行,如果是同时还向安装64位,那么上面的32位什么都不用动,只是在拷贝文件到SysWow64下的时候在多拷贝一个64位的imeSystem32下就行了,然后安装(还是32位的那个安装),这样安装后输入法里就自动显示安装了两个。也就是只是多了一步拷贝文件。其他的都不动。但是我没尝试过就是反过来,就是走安装64位的流程然后多拷贝一个32ime进去。这个感觉也是应该可以的。如果好奇大家可以自己试验一下。

注册成功之后会有这样的效果

只注册32位:

 

这样只有打开32位程序的时候才会加载:

32ie


(64ie)无效果


两个都注册的:


32ie


64ie


卸载的时候直接调用卸载函数,然后恢复默认输入法,然后清理掉之前拷贝的那些ime文件,但是注册表也要清理一下


会在注册表里添加两项,但是


不会清理注册表相关


涉及到注册表两个位置:

(1)HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts\E0200804


(2)HKEY_CURRENT_USER\Keyboard Layout\Preload


这两个都删除了就行了。这样就算是清理干净了。

最后在说一个地方,就是说如果已经安装了A.ime,那么现在想替换A.ime可能有的时候被占用,导致替换不了,如果是一直处于被占中替换不了的状态的话可以换个名字B重新注册一个新的输入法,这样来回交替的安装就行了,如果是要调试的话可以自己再DllMain里根据本地路径指定一个进程,比如记事本(注意3264位问题),然后在里面判断如果是记事本就While(1){Sleep(1000)},Sleep的地方打个断点,当记事本程序开启的时候,直接附加进程到记事本就行了,然后断到之后可以直接拖运行位置到While(1)下面继续往下走,当然不用wehile(1)MessageBox也行。

还有就是上面的方式安装完输入法之后再启动的进程才会被注入,也就是先安装在启动要被注入的进程,如果是想注入已经启动的进程,可以自己找相关资料,也就是用PostMessage等激活。


顺便开发了一个注入工具方便测试:

地址(http://download.csdn.net/detail/u013761036/9687383


0.使用的时候直接把三个文件iii.ime Injuecion_Tools.exe injuection.dll放在一起,点击Injuecion_Tools.exe就可以实现安装和卸载。

{

    Injuecion_Tools.exe  输入法安装程序

    iii.ime              输入法程序

    injuection.dll       被注入程序加载的dll文件,如果想修改功能,可以在这个里面修改。目前只是测试用,输出被注入程序路径。

}

1.目前是写的一个32位的,所以安装成功之后只有32位的会被注入,如果需要64位请自行编译,源码都在这。

2.因为是测试用的,所以没写那么细,很多细节都么处理。这个可以自行修改代码。

3.没有采取PostMes...等相关函数进行已经启动的窗体输入法激活,如果需要,请在安装成功后自行添加代码。

4.如果当前安装过一次输入法,然后卸载掉了,再次安装很可能会失败,原因是老的iii.ime被占用,也就是你在安装的话会在拷贝新的iii.ime的地方失败,

但是injuection.dll替换成功的可能性会大一点,如果想保证加载的全是新的文件,处理方法有两个,卸载输入法执行完之后重启,

或者是直接再次注入另一个输入法,就是换个名字就行了。这个地方如果需要请自行加代码。都是简单逻辑。

 

目前(2016.11.19 win7 64)随便找了几个程序测试一下是测试并且可以注入的。

英雄联盟TenSafe_1.exe,Client.exe等都可以注入

封印者 登录程序CLOSERS.exe和游戏程序CW.EXE都可以

随便写了个mfc界面程序     

ie浏览器(32位)         

qq                       

点击360界面360safe.exe,360Preview.exe...

还有安装程序可能会被360报毒,这个地方报的位置应该是拷贝文件到SystemWow64的时候。

用这个的时候大多数都是为了编写外挂程序,和LSP注入,消息注入,代码注入,SHellCode注入,EIP注入等等不同,它不需要进行隐藏,因此就不用考虑免杀问题了。


0 0