- UID
- 1
- 精华
- 积分
- 76365
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
这个东西的原理是在运行的时候,注入一段Shellcode到Minecraft游戏使用的LWJGL窗口(java.exe)拦截输入法打字的消息(WM_IME_CHAR)并将字符传递到剪贴板,然后发送Ctrl+V的模拟按键消息来让Minecraft游戏本身接收中文输入。用于按T键或/键聊天时输入中文。
Minecraft游戏在Win7上使用的Java库LWJGL对中文的输入存在问题:它会将WM_CHAR发送的大于0x7F的字符过滤掉导致游戏不接收中文输入。但是Minecraft聊天窗口接收Ctrl+C和Ctrl+V的复制粘贴操作。因此我写了这个玩意儿用于让Minecraft可以直接输入中文聊天。
不过这个东西我只完成了x86版。x64的Shellcode对CallWindowProcA的调用貌似会让Minecraft游戏退出(并且存一下档。这个存档的行为太可疑了!)但是如果是注入到自己进程创建的窗口的话似乎并没有什么问题。
这个程序目前只支持32位的Java的注入,不支持64位Java。
下载:
MCIME.exe
(12 KB, 下载次数: 15)
以下是32位注入的Shellcode的源码。用nasm编译为win32格式。- %define WM_IME_CHAR 0x0286
- %define WM_KEYDOWN 0x0100
- %define WM_KEYUP 0x0101
- %define WM_CHAR 0x0102
- %define WM_TIMER 0x0113
- %define GWLP_WNDPROC (-4)
- %define CF_TEXT 1
- %define LPTR 0x0040
- %define VK_CONTROL 0x11
- %define VK_V 0x56
- %define KEYEVENTF_KEYUP 0x0002
- %define USER_TIMER_MINIMUM 0x0000000A
- ;==============================================================================
- ;宏名:ProcBegin
- ;描述:用于每个过程的开头,建立栈帧,并使ebx指向指令起始地址
- ;------------------------------------------------------------------------------
- %macro ProcBegin 0-1
- push ebp;建立栈帧
- mov ebp,esp
- %if %0
- sub esp,(%1)*4;局部变量内存
- %endif
- push ebx;保存ebx
- call %%GetCurPos;取得指令原点
- %%GetCurPos:
- pop ebx
- sub ebx,%%GetCurPos-_InjectCode
- %endmacro
- ;==============================================================================
- ;宏名:ProcEnd
- ;描述:用于每个过程的结尾,恢复寄存器并返回,选择性清理栈内存
- ;------------------------------------------------------------------------------
- %macro ProcEnd 0-1
- pop ebx;恢复ebx
- mov esp,ebp
- pop ebp
- %if %0;返回
- ret %1
- %else
- ret
- %endif
- %endmacro
- ;==============================================================================
- ;宏名:Arg
- ;描述:用于过程中读取函数参数
- ;------------------------------------------------------------------------------
- %define Arg(x) (ebp+8+(x)*4)
- ;==============================================================================
- ;宏名:Var
- ;描述:用于过程中读取变量
- ;------------------------------------------------------------------------------
- %define Var(x) (ebp-4-(x)*4)
- ;==============================================================================
- ;宏名:Local
- ;描述:读取局部变量
- ;------------------------------------------------------------------------------
- %define Local(x) [ebx+(x)-_InjectCode]
- global _InjectCode
- global _InjWndProc@16
- global _InjTimerProc@16
- global _SizeOfInjCode
- segment .data
- ;==============================================================================
- ;void InjectCode(HWND);
- ;------------------------------------------------------------------------------
- _InjectCode:
- ProcBegin
- lea eax,Local(KrnlDll)
- push eax
- call Local(_LoadLib)
- mov Local(.hKernel32),eax
- lea eax,Local(UserDll)
- push eax
- call Local(_LoadLib)
- mov Local(.hUser32),eax
- %macro LoadFunc 2
- lea eax,Local(%2_n)
- push eax
- push dword %1
- call Local(_GetProcAddr)
- mov Local(%2),eax
- %endmacro
- LoadFunc Local(.hUser32), _GetWndLong
- LoadFunc Local(.hUser32), _SetWndLong
- LoadFunc Local(.hUser32), _Call_WndProc
- LoadFunc Local(.hUser32), _OpenClp
- LoadFunc Local(.hUser32), _EmptyClp
- LoadFunc Local(.hKernel32), _LocAlloc
- LoadFunc Local(.hKernel32), _LocFree
- LoadFunc Local(.hKernel32), _LocLock
- LoadFunc Local(.hKernel32), _LocUnlock
- LoadFunc Local(.hUser32), _SetClpData
- LoadFunc Local(.hUser32), _CloseClp
- LoadFunc Local(.hUser32), _SendMsg
- LoadFunc Local(.hUser32), _SetTmr
- LoadFunc Local(.hUser32), _KillTmr
- %unmacro LoadFunc 2
- ;取得原始的WndProc
- push dword GWLP_WNDPROC
- push dword[Arg(0)]
- call Local(_GetWndLong)
- mov Local(_OrgWndProc),eax
- ;Hook掉
- lea eax,Local(_InjWndProc@16)
- push eax
- push dword GWLP_WNDPROC
- push dword[Arg(0)]
- call Local(_SetWndLong)
- ProcEnd
- .hUser32 dd 0
- .hKernel32 dd 0
- ;==============================================================================
- ;LRESULT CALLBACK InjWndProc(HWND,UINT,WPARAM,LPARAM);
- ;------------------------------------------------------------------------------
- _InjWndProc@16:
- ProcBegin
- ;处理WM_IME_CHAR消息
- cmp dword[Arg(1)],WM_IME_CHAR
- jnz .WndProcEnd
- ;将字符添加到缓冲区
- cmp dword Local(cbString),StringBufLen-2
- ja .WndProcEnd;保证不要超过缓冲区的大小
- ;在末尾追加字符
- lea eax,Local(StringBuf)
- add eax,Local(cbString)
- mov dx,[Arg(2)]
- xchg dl,dh
- or dl,dl
- jz .OneByte
- mov [eax],dl
- inc dword Local(cbString)
- inc eax
- .OneByte:
- mov [eax],dh
- inc dword Local(cbString)
- mov byte[eax+1],0
- ;添加一个定时器,用于复制字符到游戏中
- lea eax,Local(_InjTimerProc@16)
- push eax
- push USER_TIMER_MINIMUM
- push TimerID
- push dword[Arg(0)]
- call Local(_SetTmr)
- .WndProcEnd:
- ;通过调用CallWindowProc来调用旧的消息处理函数
- push dword[Arg(3)]
- push dword[Arg(2)]
- push dword[Arg(1)]
- push dword[Arg(0)]
- push dword Local(_OrgWndProc)
- call Local(_Call_WndProc)
- ProcEnd 16
- ;==============================================================================
- ;VOID CALLBACK InjTimerProc(HWND,UINT Msg,UINT_PTR idEvent,DWORD dwTime);
- ;------------------------------------------------------------------------------
- _InjTimerProc@16:
- ProcBegin 1
- cmp byte Local(CtrlVDown),0
- jz .CVNotDown
- dec byte Local(CtrlVDown)
- jnz .CVNotDown
- push 0xC02F0001;松开按键,扫描码0x2F,一次
- push VK_V
- push WM_KEYUP
- push dword[Arg(0)]
- push dword Local(_OrgWndProc)
- call Local(_Call_WndProc)
- push 0xC01D0001;松下按键,扫描码0x1D,一次
- push VK_CONTROL
- push WM_KEYUP
- push dword[Arg(0)]
- push dword Local(_OrgWndProc)
- call Local(_Call_WndProc)
- push TimerID
- push dword[Arg(0)]
- call Local(_KillTmr)
- .CVNotDown:
- ;判断是否输入了字符串
- cmp dword Local(cbString),0
- jz .TimerProcEnd
- ;打开剪贴板
- .OpenClp:
- push dword[Arg(0)]
- call Local(_OpenClp)
- or eax,eax
- jz .OpenClp
- call Local(_EmptyClp);清空剪贴板
- ;给剪贴板分配内存
- mov eax,Local(cbString)
- inc eax
- push eax
- push LPTR
- call Local(_LocAlloc)
- mov [Var(0)],eax
- ;锁定内存
- push eax
- call Local(_LocLock)
- ;写入字符数据
- push esi
- push edi
- lea esi,Local(StringBuf)
- mov edi,eax
- mov ecx,Local(cbString)
- rep movsb
- pop edi
- pop esi
- mov dword Local(cbString),0
- ;解锁内存
- push dword[Var(0)]
- call Local(_LocUnlock)
- ;设置剪贴板数据
- push dword[Var(0)]
- push dword CF_TEXT
- call Local(_SetClpData)
- ;关闭剪贴板
- call Local(_CloseClp)
- push 0x001D0001;按下按键,扫描码0x1D,一次
- push VK_CONTROL
- push WM_KEYDOWN
- push dword[Arg(0)]
- push dword Local(_OrgWndProc)
- call Local(_Call_WndProc)
- push 0x002F0001;按下按键,扫描码0x2F,一次
- push VK_V
- push WM_KEYDOWN
- push dword[Arg(0)]
- push dword Local(_OrgWndProc)
- call Local(_Call_WndProc)
- ;两个定时器周期后,松开按键
- mov byte Local(CtrlVDown),2
- .TimerProcEnd:
- ProcEnd 16
- ;==============================================================================
- ;全局变量区
- ;------------------------------------------------------------------------------
- _OrgWndProc dd 0 ;原先的WndProc
- ;定义Dll函数:制造一个变量,以及相应的字符串用于读取
- %macro DefDllFunc 2
- global %1
- %1 dd 0
- %1_n db %2,0
- %endmacro
- KrnlDll db "kernel32.dll",0
- UserDll db "user32.dll",0
- DefDllFunc _LoadLib, "LoadLibraryA"
- DefDllFunc _GetProcAddr, "GetProcAddress"
- DefDllFunc _GetWndLong, "GetWindowLongA"
- DefDllFunc _SetWndLong, "SetWindowLongA"
- DefDllFunc _Call_WndProc, "CallWindowProcA"
- DefDllFunc _OpenClp, "OpenClipboard"
- DefDllFunc _EmptyClp, "EmptyClipboard"
- DefDllFunc _LocAlloc, "LocalAlloc"
- DefDllFunc _LocFree, "LocalFree"
- DefDllFunc _LocLock, "LocalLock"
- DefDllFunc _LocUnlock, "LocalUnlock"
- DefDllFunc _SetClpData, "SetClipboardData"
- DefDllFunc _CloseClp, "CloseClipboard"
- DefDllFunc _SendMsg, "SendMessageA"
- DefDllFunc _SetTmr, "SetTimer"
- DefDllFunc _KillTmr, "KillTimer"
- cbString dd 0 ;字符串长度
- StringBufLen equ 1024
- StringBuf: ;字符串缓冲
- times StringBufLen db 0
- CtrlVDown db 0 ;是否按下了Ctrl+V
- TimerID equ 0xAA55
- ;统计注入的字节数
- InjCodeLen equ $-_InjectCode
- _SizeOfInjCode dd InjCodeLen
复制代码 以下为注入器的源码(C语言)的源码(注意是控制台程序。)
你只需要把其中的重点代码抽出来用就行了。可以写成Dll。- #include<Windows.h>
- #include<stdio.h>
- #include<conio.h>
- #include<process.h>
- HWND g_hWnd=NULL;
- extern DWORD InjectCode(LPVOID);
- extern DWORD SizeOfInjCode;
- extern void*LoadLib;
- extern void*GetProcAddr;
- //=============================================================================
- //函数:PrintLE
- //描述:打印GetLastError的字符串信息。
- //-----------------------------------------------------------------------------
- void PrintLE()
- {
- LPVOID lpMsgBuf;
- DWORD dwLastErr;
- FormatMessageA
- (
- FORMAT_MESSAGE_ALLOCATE_BUFFER | //返回一个已分配的内存
- FORMAT_MESSAGE_FROM_SYSTEM | //系统消息
- FORMAT_MESSAGE_IGNORE_INSERTS, //无视插入信息
- NULL,
- dwLastErr=GetLastError(),
- 0, //默认语言
- (LPSTR)&lpMsgBuf,
- 0,
- NULL
- );
- fprintf(stderr,"GetLastError()==%d,%s\n",dwLastErr,lpMsgBuf);
- LocalFree(lpMsgBuf);
- }
- //=============================================================================
- //函数:SetPrivilege
- //描述:提权,使自己拥有注射指令到别的进程的权限。
- //-----------------------------------------------------------------------------
- BOOL SetPrivilege()
- {
- HANDLE hToken=INVALID_HANDLE_VALUE;
- TOKEN_PRIVILEGES tkp;
- LUID SEDebugNameValue;
- if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
- {
- PrintLE();
- return FALSE;
- }
- if(!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&SEDebugNameValue))
- {
- PrintLE();
- CloseHandle(hToken);
- return FALSE;
- }
- tkp.PrivilegeCount = 1;
- tkp.Privileges[0].Luid=SEDebugNameValue;
- tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
- if(!AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(tkp),NULL,NULL))
- {
- PrintLE();
- CloseHandle(hToken);
- return FALSE;
- }
- CloseHandle(hToken);
- return TRUE;
- }
- //=============================================================================
- //函数:InjectToProcess
- //描述:注射到指定窗口句柄所在的进程。
- //-----------------------------------------------------------------------------
- BOOL InjectToProcess(HWND hWnd)
- {
- HANDLE hProc=INVALID_HANDLE_VALUE,hRemoteProc=INVALID_HANDLE_VALUE;
- HMODULE hKernel32=NULL;
- SIZE_T cbWrite;
- void*pMemAddr=NULL;
- # ifdef _DEBUG
- DWORD dwProcID=GetCurrentProcessId();
- DWORD dwOldProtect;
- # else
- DWORD dwProcID;
- # endif
- hKernel32=LoadLibrary(TEXT("kernel32.dll"));
- if(!hKernel32)
- {
- fputs("Could not load library.\n",stderr);
- PrintLE();
- return FALSE;
- }
-
- //写入API地址到要注射的代码中
- LoadLib= GetProcAddress(hKernel32, "LoadLibraryA");
- GetProcAddr= GetProcAddress(hKernel32, "GetProcAddress");
- FreeLibrary(hKernel32);hKernel32=NULL;
- //Debug编译的代码并没有注入的行为,主要用于调试。
- # ifdef _DEBUG
- VirtualProtectEx(GetCurrentProcess(),InjectCode,SizeOfInjCode,PAGE_EXECUTE_READWRITE,&dwOldProtect);
- InjectCode(hWnd);
- return TRUE;
- # endif
- //取得进程ID
- GetWindowThreadProcessId(hWnd,&dwProcID);
- if(!dwProcID)
- {
- fputs("Could not get process Id.\n",stderr);
- PrintLE();
- return FALSE;
- }
- fprintf(stderr,"Process Id = %u\n",dwProcID);
-
- //打开进程
- hProc=OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcID);
- if(!hProc||hProc==INVALID_HANDLE_VALUE)
- {
- fputs("Open process failed.\n",stderr);
- PrintLE();
- return FALSE;
- }
- //远程分配内存
- pMemAddr=VirtualAllocEx(hProc,NULL,SizeOfInjCode,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
- if(!pMemAddr)
- {
- fputs("Could not allocate remote memory.\n",stderr);
- PrintLE();
- goto FailRet;
- }
- //注入代码
- if(!WriteProcessMemory(hProc,pMemAddr,InjectCode,SizeOfInjCode,&cbWrite))
- {
- fputs("Could not write data to remote memory.\n",stderr);
- PrintLE();
- goto FailRet;
- }
-
- //创建远程线程
- hRemoteProc=CreateRemoteThread(hProc,NULL,0,(LPTHREAD_START_ROUTINE)pMemAddr,hWnd,0,NULL);
- if(!hRemoteProc||hRemoteProc==INVALID_HANDLE_VALUE)
- {
- fputs("Could not create remote thread.\n",stderr);
- PrintLE();
- goto FailRet;
- }
- CloseHandle(hRemoteProc);
- CloseHandle(hProc);
- return TRUE;
- FailRet:
- if(hKernel32)
- FreeLibrary(hKernel32);
- if(hProc&&hProc!=INVALID_HANDLE_VALUE)
- CloseHandle(hProc);
- if(hRemoteProc&&hRemoteProc!=INVALID_HANDLE_VALUE)
- CloseHandle(hRemoteProc);
- return FALSE;
- }
- //=============================================================================
- //函数:MatchWindow
- //描述:判断窗口是不是指定的窗口类
- //-----------------------------------------------------------------------------
- BOOL MatchWindow(HWND hWnd,LPCTSTR szClassName)
- {
- TCHAR*szClass;
- int nClass,nNewClass;
- int cbClass;
- nClass=lstrlen(szClassName);
- nNewClass=nClass+2;
- cbClass=nNewClass*sizeof(TCHAR);
- szClass=(TCHAR*)malloc(cbClass);
- if(!szClass)return FALSE;
- memset(szClass,0,cbClass);
- if(GetClassName(hWnd,szClass,nNewClass)==nClass)
- {
- if(!lstrcmp(szClass,szClassName))
- {
- free(szClass);
- return TRUE;
- }
- }
- free(szClass);
- return FALSE;
- }
- //=============================================================================
- //函数:EnumWindowsProc
- //描述:枚举窗口的回调函数。
- //-----------------------------------------------------------------------------
- BOOL CALLBACK EnumWindowsProc(HWND hWnd,LPARAM lParam)
- {
- TCHAR szClass[7]={0};
- if(MatchWindow(hWnd,TEXT("LWJGL")))
- {
- printf("0x%08X\n",hWnd);
- InjectToProcess(hWnd);
- }
-
- return TRUE;
- }
- //Debug编译时创建窗口的一系列操作
- #ifdef DEBUG
- //=============================================================================
- //函数:WndProc
- //描述:自己的窗口的消息处理函数
- //-----------------------------------------------------------------------------
- LRESULT CALLBACK WndProc(HWND hWnd,UINT Msg,WPARAM wp,LPARAM lp)
- {
- switch(Msg)
- {
- default:
- return DefWindowProc(hWnd,Msg,wp,lp);
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
- }
- return 0;
- }
- //=============================================================================
- //函数:CreateWnd
- //描述:创建并显示自己的窗口
- //-----------------------------------------------------------------------------
- HWND CreateWnd()
- {
- HINSTANCE hInst=GetModuleHandle(NULL);
- WNDCLASSEX WCEx={sizeof(WNDCLASSEX),0,WndProc,0,0,hInst,NULL,LoadCursor(NULL,MAKEINTRESOURCE(IDC_ARROW)),(HBRUSH)COLOR_BTNFACE,NULL,TEXT("mcime"),NULL};//窗口类
- HWND hWnd=CreateWindowEx(0,MAKEINTATOM(RegisterClassEx(&WCEx)),TEXT("mcime"),WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInst,NULL);//窗口句柄
- ShowWindow(hWnd,SW_SHOW);
- UpdateWindow(hWnd);
- return hWnd;
- }
- //=============================================================================
- //函数:RunWnd
- //描述:线程函数,用于处理所有的窗口消息。
- //-----------------------------------------------------------------------------
- void RunWnd(void*p)
- {
- MSG msg;
- g_hWnd=CreateWnd();
- if(!g_hWnd)
- return;
- while(GetMessage(&msg,NULL,0,0))//消息循环
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- #endif
- int main(int argc,char**argv)
- {
- //先提权
- if(!SetPrivilege())
- {
- fputs("Take privilege failed.(%u)\n",stderr);
- return 1;
- }
- # ifdef _DEBUG
- //创建线程用于显示窗口
- _beginthread(RunWnd,0,NULL);
- //等窗口创建好
- while(!g_hWnd)
- Sleep(1);
- //注入到窗口
- InjectToProcess(g_hWnd);
- # else
- EnumWindows(EnumWindowsProc,0);
- # endif
- //暂停一下以便于看到错误信息。
- _getch();
- return 0;
- }
复制代码 另外附上x64的Shellcode。这个会让Minecraft退出,原因不明。- %define WM_IME_CHAR 0x0286
- %define WM_KEYDOWN 0x0100
- %define WM_KEYUP 0x0101
- %define WM_CHAR 0x0102
- %define WM_TIMER 0x0113
- %define STD_ERROR_HANDLE 0xFFFFFFF4
- %define GWLP_WNDPROC (-4)
- %define GCL_WNDPROC (-24)
- %define CF_TEXT 1
- %define LPTR 0x0040
- %define VK_CONTROL 0x11
- %define VK_V 0x56
- %define KEYEVENTF_KEYUP 0x0002
- %define USER_TIMER_MINIMUM 0x0000000A
- ;==============================================================================
- ;宏名:ProcBegin
- ;描述:用于每个过程的开头,建立栈帧,并使ebx指向指令起始地址
- ;------------------------------------------------------------------------------
- %macro ProcBegin 0-1
- push rbp;建立栈帧
- mov rbp,rsp
- ;如果有参数
- ;参数的作用:指定当前过程中调用的所有子过程中最大参数个数
- %if %0
- %if (%1)!=0
- %define LocalVarsMem
- %assign LocalVarsMem (((((%1)+1)/2)*16)+8);参数个数16字节对齐,外加8字节
- sub rsp,LocalVarsMem;分配局部变量内存
- %endif
- %endif
- push rbx;保存rbx
- call %%GetCurPos;取得指令原点
- %%GetCurPos:
- pop rbx
- sub rbx,%%GetCurPos-InjectCode
- %endmacro
- ;==============================================================================
- ;宏名:ProcEnd
- ;描述:用于每个过程的结尾,恢复寄存器并返回,选择性清理栈内存
- ;------------------------------------------------------------------------------
- %macro ProcEnd 0-1
- .EndOfProc:
- %ifdef LocalVarsMem
- %if LocalVarsMem;释放局部变量内存
- add rsp,LocalVarsMem
- %endif
- %undef LocalVarsMem
- %endif
- pop rbx;恢复ebx
- mov rsp,rbp
- pop rbp
- ret
- %endmacro
- ;==============================================================================
- ;宏名:Arg
- ;描述:用于过程中读取函数参数
- ;------------------------------------------------------------------------------
- %define Arg(x) (rbp+16+(x)*8)
- ;==============================================================================
- ;宏名:Var
- ;描述:用于过程中读取变量
- ;------------------------------------------------------------------------------
- %define Var(x) (rbp-8-(x)*8)
- ;==============================================================================
- ;宏名:Param
- ;描述:用于设置函数的参数
- ;------------------------------------------------------------------------------
- %define Param(x) (rsp+(x)*8)
- ;==============================================================================
- ;宏名:Local
- ;描述:读取局部变量
- ;------------------------------------------------------------------------------
- %define Local(x) [rbx+(x)-InjectCode]
- global InjectCode
- global InjWndProc
- global InjTimerProc
- global SizeOfInjCode
- segment .data
- ;==============================================================================
- ;void InjectCode(HWND);
- ;------------------------------------------------------------------------------
- InjectCode:
- ProcBegin 4;过程中调用的函数参数个数最大4个
- mov [Arg(0)],rcx
- lea rcx,Local(KrnlDll)
- call Local(LoadLib)
- mov Local(.hKernel32),rax
- lea rcx,Local(UserDll)
- call Local(LoadLib)
- mov Local(.hUser32),rax
- %macro LoadFunc 2
- lea rdx,Local(%2_n)
- mov rcx,%1
- call Local(GetProcAddr)
- mov Local(%2),rax
- %endmacro
- LoadFunc Local(.hUser32), GetWndLong
- LoadFunc Local(.hUser32), SetWndLong
- LoadFunc Local(.hUser32), Call_WndProc
- LoadFunc Local(.hUser32), DefWndProc
- LoadFunc Local(.hUser32), OpenClp
- LoadFunc Local(.hUser32), EmptyClp
- LoadFunc Local(.hKernel32), LocAlloc
- LoadFunc Local(.hKernel32), LocFree
- LoadFunc Local(.hKernel32), LocLock
- LoadFunc Local(.hKernel32), LocUnlock
- LoadFunc Local(.hUser32), SetClpData
- LoadFunc Local(.hUser32), CloseClp
- LoadFunc Local(.hUser32), SendMsg
- LoadFunc Local(.hUser32), SetTmr
- LoadFunc Local(.hUser32), KillTmr
- %unmacro LoadFunc 2
- ;取得原始的WndProc
- mov rdx,GWLP_WNDPROC
- mov rcx,[Arg(0)]
- call Local(GetWndLong)
- mov Local(OrgWndProc),rax
- ;Hook掉
- lea r8,Local(InjWndProc)
- mov rdx,GWLP_WNDPROC
- mov rcx,[Arg(0)]
- call Local(SetWndLong)
- ProcEnd
- .hUser32 dq 0
- .hKernel32 dq 0
- ;==============================================================================
- ;LRESULT CALLBACK InjWndProc(HWND,UINT,WPARAM,LPARAM);
- ;------------------------------------------------------------------------------
- InjWndProc:
- ProcBegin 5;过程中调用的函数参数个数最大5个
- mov[Arg(0)],rcx
- mov[Arg(1)],rdx
- mov[Arg(2)],r8
- mov[Arg(3)],r9
- ;处理WM_IME_CHAR消息
- cmp edx,WM_IME_CHAR
- jnz .WndProcEnd
- ;将字符添加到缓冲区
- cmp qword Local(cbString),StringBufLen-1
- ja .WndProcEnd;保证不要超过缓冲区的大小
- ;在末尾追加字符
- lea rax,Local(StringBuf)
- add rax,Local(cbString)
- mov dx,r8w
- xchg dl,dh
- or dl,dl
- jz .OneByte
- mov [rax],dl
- inc qword Local(cbString)
- inc rax
- .OneByte:
- mov [rax],dh
- inc qword Local(cbString)
- ;添加一个定时器,用于复制字符到游戏中
- lea r9,Local(InjTimerProc)
- mov r8,USER_TIMER_MINIMUM
- mov rdx,TimerID
- mov rcx,[Arg(0)]
- call Local(SetTmr)
- jmp .DefProc
- .WndProcEnd:
- ;通过调用CallWindowProc来调用旧的消息处理函数
- mov rax,[Arg(3)]
- mov [Param(4)],rax;第五个参数入栈
- mov r9,[Arg(2)]
- mov r8,[Arg(1)]
- mov rdx,[Arg(0)]
- mov rcx,Local(OrgWndProc)
- call Local(Call_WndProc)
- jmp .EndOfProc
- .DefProc:
- call Local(DefWndProc)
- ProcEnd
- ;==============================================================================
- ;VOID CALLBACK InjTimerProc(HWND,UINT Msg,UINT_PTR idEvent,DWORD dwTime);
- ;------------------------------------------------------------------------------
- InjTimerProc:
- ProcBegin 5;过程中调用的函数参数个数最大5个
- mov[Arg(0)],rcx
- mov[Arg(1)],rdx
- cmp byte Local(CtrlVDown),0
- jz .CtrlVUp
- dec byte Local(CtrlVDown)
- jnz .CtrlVUp
- mov dword[Param(4)],0xC02F0001
- mov r9,VK_V
- mov r8,WM_KEYUP
- mov rdx,[Arg(0)]
- mov rcx,Local(OrgWndProc)
- call Local(Call_WndProc)
- ;发送Ctrl+V的松开
- mov dword[Param(4)],0xC01D0001
- mov r9,VK_CONTROL
- mov r8,WM_KEYUP
- mov rdx,[Arg(0)]
- mov rcx,Local(OrgWndProc)
- call Local(Call_WndProc)
- mov rdx,TimerID
- mov rcx,[Arg(0)]
- call Local(KillTmr)
- .CtrlVUp:
- ;判断是否输入了字符串
- cmp qword Local(cbString),0
- jz .TimerProcEnd
- ;打开剪贴板
- .OpenClp:
- mov rcx,[Arg(0)]
- call Local(OpenClp)
- or rax,rax
- jz .OpenClp
- call Local(EmptyClp);清空剪贴板
- ;给剪贴板分配内存
- mov rdx,Local(cbString)
- inc rdx
- mov rcx,LPTR
- call Local(LocAlloc)
- mov[Arg(2)],rax;用参数2的位置(没用)来存储内存句柄
- ;锁定内存
- mov rcx,rax
- call Local(LocLock)
- ;写入字符数据
- push rsi
- push rdi
- lea rsi,Local(StringBuf)
- mov rdi,rax
- mov rcx,Local(cbString)
- rep movsb
- pop rdi
- pop rsi
- mov qword Local(cbString),0
- ;解锁内存
- mov rcx,[Arg(2)]
- call Local(LocUnlock)
- ;设置剪贴板数据
- mov rdx,[Arg(2)]
- mov rcx,CF_TEXT
- call Local(SetClpData)
- ;关闭剪贴板
- call Local(CloseClp)
- ;发送Ctrl+V的按键信息
- mov dword[Param(4)],0x001D0001
- mov r9,VK_CONTROL
- mov r8,WM_KEYDOWN
- mov rdx,[Arg(0)]
- mov rcx,Local(OrgWndProc)
- call Local(Call_WndProc)
- mov dword[Param(4)],0x002F0001
- mov r9,VK_V
- mov r8,WM_KEYDOWN
- mov rdx,[Arg(0)]
- mov rcx,Local(OrgWndProc)
- call Local(Call_WndProc)
- ;已按下这个键
- mov byte Local(CtrlVDown),2;键盘反应时间
- .TimerProcEnd:
- ProcEnd 16
- ;==============================================================================
- ;全局变量区
- ;------------------------------------------------------------------------------
- OrgWndProc dq 0 ;原先的WndProc
- ;定义Dll函数:制造一个变量,以及相应的字符串用于读取
- %macro DefDllFunc 2
- global %1
- %1 dq 0
- %1_n db %2,0
- %endmacro
- KrnlDll db "kernel32.dll",0
- UserDll db "user32.dll",0
- hStdErr dq 0
- StrLen dq 0
- DefDllFunc LoadLib, "LoadLibraryA"
- DefDllFunc GetProcAddr, "GetProcAddress"
- DefDllFunc GetWndLong, "GetWindowLongPtrA"
- DefDllFunc SetWndLong, "SetWindowLongPtrA"
- DefDllFunc Call_WndProc,"CallWindowProcA"
- DefDllFunc DefWndProc, "DefWindowProcA"
- DefDllFunc OpenClp, "OpenClipboard"
- DefDllFunc EmptyClp, "EmptyClipboard"
- DefDllFunc LocAlloc, "LocalAlloc"
- DefDllFunc LocFree, "LocalFree"
- DefDllFunc LocLock, "LocalLock"
- DefDllFunc LocUnlock, "LocalUnlock"
- DefDllFunc SetClpData, "SetClipboardData"
- DefDllFunc CloseClp, "CloseClipboard"
- DefDllFunc SendMsg, "SendMessageA"
- DefDllFunc SetTmr, "SetTimer"
- DefDllFunc KillTmr, "KillTimer"
- cbString dq 0 ;字符串长度
- StringBufLen equ 1024
- StringBuf: ;字符串缓冲
- times StringBufLen db 0
- CtrlVDown db 0 ;是否按下了Ctrl+V
- TimerID equ 0xAA55
- ;统计注入的字节数
- InjCodeLen equ $-InjectCode
- SizeOfInjCode dq InjCodeLen
复制代码 全部源码:
MCIME.7z
(12 KB, 下载次数: 0, 售价: 1 个宅币)
|
|