特性

因为输入法的本身特性,能注入任何一个程序,还可以开机启动,很是友好

网上大都是一个版本方法,我记录下我自己过程

思路

1.编写一个正常的输入法
2.将它安装到电脑上,并设置为默认输入法,这样就可以在程序打开的时候就调用它的处理函数

因为输入是一个特殊的dll,本质就是一个dll,只是后最不同而已。

一个最简ime文件都必须两个函数

一个dllmain() 还有一个ImeInquire()这两个是必须的

编写输入法主要文件

创建一个dll项目,解释都在注释中(注意项目为多字节字符集)
dllmain.cpp

#include "stdafx.h"
#include "windows.h"
#include "imm.h"
#include "immdev.h"
#pragma comment(lib,"imm32.lib")

LPCSTR injectDllPaht = "C://expDll.dll"; //我们最终利用的Dll,写入自己的功能
void injectDLL();//定义函数,下面用
LRESULT WINAPI UIWndProc(HWND hUIWnd, 
                        UINT message,
                        WPARAM wParam, 
                        LPARAM lParam) 
{ return 0; }//窗口消息处理函数,可以不要

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
    )//主函数的标准格式
{
    HINSTANCE hinstDLL = (HINSTANCE)hModule;//下面需要用这个句柄,格式强转以下
    switch (ul_reason_for_call)
    {

    case DLL_PROCESS_ATTACH:
    {        //定义一个窗口类
           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 = hinstDLL;
           wc.hCursor = LoadCursor(NULL, IDC_ARROW); //IDC_ARROW
           wc.hIcon = NULL;
           wc.lpszMenuName = (LPTSTR)NULL;
           wc.lpszClassName = TEXT("CInjWindow");//定义的窗口类的名字
           wc.hbrBackground = NULL;
           wc.hIconSm = NULL;
           if (!RegisterClassEx((LPWNDCLASSEX)&wc))//注册这个窗口,IME必须要注册一个窗口才能安装
           {
               break;
           }
           injectDLL();//干事的func
           break;
    }
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:
        UnregisterClass("CInjWindow", hinstDLL);//程序退出时注销窗口实例
        break;
    }
    return TRUE;
}

void injectDLL()
{
    WCHAR Mes[MAX_PATH];
    //这里就可以写注入func,我这里就调用一个自己写的测试dll,每次加载的时候都会打印父窗口名称
    HMODULE hMyDll = LoadLibrary(injectDllPaht);//因为现在已经在别的进程中,所以导入后的就成功注入想要的进程了
    if (!hMyDll)
    {
        DWORD ERRCODE = GetLastError();
        MessageBox(0, (LPCSTR)ERRCODE, 0, 0);
    }
    else
    {
        HMODULE hParentM = GetModuleHandle(0);
        //FARPROC fRunFunc = GetProcAddress(hMyDll, "Run");
        //fRunFunc();
    }

}


BOOL WINAPI ImeInquire(LPIMEINFO lpImeInfo, LPTSTR lpszUIClass, LPCTSTR lpszOption)
{
    //初始化ImeInquire
    //这个函数是除了DllMain后第一个会被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, "CInjWindow");//注意这里,对ImeInquire赋予我们刚刚创建的类
    return TRUE;
}

因为输入法需要图标,所以需要添加资源文件,右键dll项目添加
在这里插入图片描述
添加位图
在这里插入图片描述
要修改version值如下

在这里插入图片描述

然后生成就好了

真正需要注入的dll

其实干正事的过程也可以直接放到ime中,但是步方便管理,我这里写出来了
也是一个dll项目

因为我只是测试,所以就写的很简单,一个验证父进程函数名的就可以了。(游戏辅助代码就可以写在这)
dllmain.cpp如下

    case DLL_PROCESS_ATTACH:
        //获取当前程序名
        GetModuleFileName(GetModuleHandle(0),lpFileName,sizeof(lpFileName));
        //打印出来
        MessageBox(0,lpFileName, 0, 0);
}

加载ime

把上面生成的dll改名为ime结尾,复制到windows32目录下

接下来创建一个控制台项目

如下

#include "stdafx.h"
#include "windows.h"
#include "imm.h"
#pragma comment(lib,"imm32.lib")


int _tmain(int argc, _TCHAR* argv[])
{
    if (argc<3)
    {
        MessageBox(0, "请注意参数 exp:exeName.exe imeName.ime Jerry", 0, 0);
        return 0;
    }
    LPCSTR infecPath = argv[1];
    LPCSTR infecName = argv[2];
    PVOID m_retV;
    //得到默认的输入法句柄并保存
    ::SystemParametersInfo(
        SPI_GETDEFAULTINPUTLANG,
        0,
        &m_retV,
        0);
    //安装输入法
    HKL m_hImeFile = ImmInstallIME(
        infecPath,
        infecName);

    if (ImmIsIME(m_hImeFile))
    {
        //设置为默认输入法
        SystemParametersInfo(
            SPI_SETDEFAULTINPUTLANG,
            0,
            &m_hImeFile,
            SPIF_SENDWININICHANGE);
        MessageBox(0, "安装输入法成功", 0, 0);
    }
    else
    {
        MessageBox(0, "error 安装出错了", 0, 0);
    }
}

把编译生成的exe文件也拷贝到windows32

安装命令如下 exeName.exe imeName.ime Jerry

安装程序可以自由发挥,只要把ime文件安装到系统上就是了

最终效果

当你安装成功后,就会有弹窗提示,你打开任意一个程序,都会有弹窗提示这个程序的路径。这就说明已经注入成功了。

开机后在切换输入法时也会启动



逆向  

注入 开机启动

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!