首页
社区
课程
招聘
[原创]Win7 x64鼠标键盘锁(SDK)
发表于: 2018-6-16 14:25 6384

[原创]Win7 x64鼠标键盘锁(SDK)

2018-6-16 14:25
6384

       曾经,学习孙鑫老师的《VC++深入详解》时,接触到了钩子HOOK原理,一度对HOOK技术特别感兴趣,便自然而然产生了实现“鼠标键盘锁”的想法。通过查资料和尝试,基本实现了鼠标和键盘的屏蔽,当然,会被叁陆灵等杀软拦截,本人小白,大神勿喷!!!

       开始写程序,安装全局钩子,WH_KEYBOARD和WH_MOUSE,运行,毫无疑问,被叁陆灵立马拦截,暂时退出叁陆灵的保护后,重新运行,鼠标可以移动,但是点击没有反应,键盘字母按键按下没反应,达到了一定的效果。然而,还是有问题,屏蔽了鼠标,但是键盘并没有完全“钩住”,包括Win+L、Ctrl+Alt+Del、WIN、 WIN+Tab、Ctrl+ESC、Ctrl+Shift+Esc、Ctrl+Alt+Tab、Ctrl+WIN+Tab、WIN+U WIN+D、WIN+E等等系统组合键都是可以用的。于是接着查资料,如何屏蔽系统键,通过底层钩子WH_KEYBOARD_LL可以屏蔽除了Ctrl+Alt+Del和Win+L的其他系统键,通过底层钩子WH_MOUSE_LL可以截获整个系统的鼠标事件。在DLL中设置共享节,保存调用进程的窗口自句柄,则在屏蔽了鼠标键盘后通过按下自己设置的组合键(如Alt+Q)后,用SendMessage向主进程发送WM_CLOSE消息实现退出。关于动态链接库的相关知识不是本文重点,在此不多赘述。KeymsLockHook.dll代码实现:

全局变量和初始化

钩子DLL中导出函数:

在调用主进程中,通过动态加载,调用以上DLL导出的函数SetKeymsHook安装全局钩子,创建互斥对象,仅允许主程序运行一个实例,调用程序主要代码实现:

       至此,除了Ctrl+Alt+Del、Win+L组合键之外,其他能想到的都屏蔽了,对于这两个组合键的屏蔽,论坛中有位前辈很早之前就写了一篇文章,但是不知道为什么帖子被删了,还好有幸找到了:

https://blog.csdn.net/linfei2707/article/details/25237671

文章提到四种想法,其中第四种方法堪称完美,好像这也是不用驱动实现屏蔽这两个组合键的最佳方法了。若想看具体原理和调试过程方法,请看该前辈的帖子,笔者win7 64位系统winlogon.exe中主要部分如下:

其中,Win+L很好屏蔽,将cmp ebx,5中的立即数改为其他比较大的值即可实现;Ctrl+Alt+Del有两个语句

按下Ctrl+Alt+Del时,ebx=0;所以可以通过85改为3B,75改为74改动两个字节即可,按下Alt+Q退出时可以还原。

具体实现笔者用远线程注入到winlogon.exe中进行修改,远线程注入DLL中代码如下:

获取进程PID子函数GetProId

获取winlogon.exe的进程ID,得到注入DLL路径,远线程注入

以上就是整个鼠标键盘锁的实现过程,纯SDK,没技术含量,功能虽然可以实现,但是这种方法有个问题,即系统不同,需要修改的字节在winlogon中的偏移也会有所不同,所以如果要写个具有普遍性的程序还需搜索找到要修改的偏移,因此还需进一步改进。请大神们轻喷,不对的地方,请指正,大神们有好的方法欢迎分享!

HHOOK g_hMouse = NULL;// 鼠标钩子句柄
HHOOK g_hLowlevelMouse = NULL; // 底层鼠标钩子句柄
HHOOK g_hKeyboard = NULL;// 键盘钩子句柄
HHOOK g_hLowlevelKeyboard = NULL;// 底层键盘钩子句柄
#pragma data_seg("SharedSec")// 设置共享节
HWND g_hWnd = NULL;// 传递调用进程的主窗口句柄
#pragma data_seg()

钩子DLL中导出函数:

extern "C" _declspec(dllexport) BOOL __stdcall SetKeymsHook(HWND hwnd)
{
	g_hWnd = hwnd;
	HMODULE hModule = GetModuleHandle(_T("KeymsLockHook.dll")); //获取动态链接库KeymsLockHook.dll模块句柄
	g_hMouse = SetWindowsHookEx(WH_MOUSE, MouseProc, hModule, 0);
	if (NULL == g_hMouse)
	{
		MessageBox(NULL, _T("安装鼠标钩子出错1!"), _T("error"), 0);
		return FALSE;
	}
	g_hLowlevelMouse=SetWindowsHookEx(WH_MOUSE_LL,LowLevelMouseProc, hModule, 0);
	if (NULL == g_hLowlevelMouse)
	{
		MessageBox(NULL, _T("安装鼠标钩子出错2!"), _T("error"), 0);
		return FALSE;
	}
	g_hKeyboard=SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hModule, 0);
	if (NULL == g_hKeyboard)
	{
		MessageBox(NULL, _T("安装键盘钩子出错1!"), _T("error"), 0);
		return FALSE;
	}
	g_hLowlevelKeyboard = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hModule, 0);
	if (NULL == g_hLowlevelKeyboard)
	{
		MessageBox(NULL, _T("安装键盘钩子出错2!"), _T("error"), 0);
		return FALSE;
	}	
	return TRUE;
}
钩子过程函数体
extern "C" _declspec(dllexport) BOOL __stdcall SetKeymsHook(HWND hwnd)
{
	g_hWnd = hwnd;
	HMODULE hModule = GetModuleHandle(_T("KeymsLockHook.dll")); //获取动态链接库KeymsLockHook.dll模块句柄
	g_hMouse = SetWindowsHookEx(WH_MOUSE, MouseProc, hModule, 0);
	if (NULL == g_hMouse)
	{
		MessageBox(NULL, _T("安装鼠标钩子出错1!"), _T("error"), 0);
		return FALSE;
	}
	g_hLowlevelMouse=SetWindowsHookEx(WH_MOUSE_LL,LowLevelMouseProc, hModule, 0);
	if (NULL == g_hLowlevelMouse)
	{
		MessageBox(NULL, _T("安装鼠标钩子出错2!"), _T("error"), 0);
		return FALSE;
	}
	g_hKeyboard=SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hModule, 0);
	if (NULL == g_hKeyboard)
	{
		MessageBox(NULL, _T("安装键盘钩子出错1!"), _T("error"), 0);
		return FALSE;
	}
	g_hLowlevelKeyboard = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hModule, 0);
	if (NULL == g_hLowlevelKeyboard)
	{
		MessageBox(NULL, _T("安装键盘钩子出错2!"), _T("error"), 0);
		return FALSE;
	}	
	return TRUE;
}
钩子过程函数体
LRESULT CALLBACK MouseProc(
	int code,       // hook code
	WPARAM wParam,  // virtual-key code
	LPARAM lParam   // keystroke-message information
) 
{
	return 1;
}
LRESULT CALLBACK LowLevelMouseProc(
	int nCode,
	WPARAM wParam,
	LPARAM lParam
) 
{
	return 1;
}
LRESULT CALLBACK KeyboardProc(
	int code,       // hook code
	WPARAM wParam,  // virtual-key code
	LPARAM lParam   // keystroke-message information
)
{
	return 1;
}
LRESULT CALLBACK LowLevelKeyboardProc(
	int nCode,     // hook code
	WPARAM wParam, // message identifier
	LPARAM lParam  // pointer to structure with message data
)
{
	PKBDLLHOOKSTRUCT pKey;
	pKey = (PKBDLLHOOKSTRUCT)lParam;
	// 屏蔽WIN CTRL ESC WIN+Tab Ctrl+ESC Ctrl+Shift+Esc Ctrl+Alt+Tab Ctrl+WIN+Tab WIN+U WIN+P WIN+X WIN+D WIN+E等键
	if (pKey->vkCode == VK_LWIN || pKey->vkCode == VK_RWIN ||	(GetAsyncKeyState(VK_CONTROL) & 0x8000) || (GetAsyncKeyState(VK_ESCAPE) & 0x8000))// 屏蔽WIN键,Ctrl+ESC组合键
	{
		return 1;
	}
	// 屏蔽Alt相关键 Alt+Tab 
	if (pKey->flags & LLKHF_ALTDOWN) // Alt按下
	{
		if ('Q' == pKey->vkCode) // Alt+Q退出
		{
			UnhookWindowsHookEx(g_hMouse);
			UnhookWindowsHookEx(g_hLowlevelMouse);
			UnhookWindowsHookEx(g_hKeyboard);
			UnhookWindowsHookEx(g_hLowlevelKeyboard);
			SendMessage(g_hWnd, WM_CLOSE, 0, 0);
		}
		return 1;
	}
	return CallNextHookEx(g_hLowlevelKeyboard, nCode, wParam, lParam);
}

在调用主进程中,通过动态加载,调用以上DLL导出的函数SetKeymsHook安装全局钩子,创建互斥对象,仅允许主程序运行一个实例,调用程序主要代码实现:

LRESULT CALLBACK MouseProc(
	int code,       // hook code
	WPARAM wParam,  // virtual-key code
	LPARAM lParam   // keystroke-message information
) 
{
	return 1;
}
LRESULT CALLBACK LowLevelMouseProc(
	int nCode,
	WPARAM wParam,
	LPARAM lParam
) 
{
	return 1;
}
LRESULT CALLBACK KeyboardProc(
	int code,       // hook code
	WPARAM wParam,  // virtual-key code
	LPARAM lParam   // keystroke-message information
)
{
	return 1;
}
LRESULT CALLBACK LowLevelKeyboardProc(
	int nCode,     // hook code
	WPARAM wParam, // message identifier
	LPARAM lParam  // pointer to structure with message data
)
{
	PKBDLLHOOKSTRUCT pKey;
	pKey = (PKBDLLHOOKSTRUCT)lParam;
	// 屏蔽WIN CTRL ESC WIN+Tab Ctrl+ESC Ctrl+Shift+Esc Ctrl+Alt+Tab Ctrl+WIN+Tab WIN+U WIN+P WIN+X WIN+D WIN+E等键
	if (pKey->vkCode == VK_LWIN || pKey->vkCode == VK_RWIN ||	(GetAsyncKeyState(VK_CONTROL) & 0x8000) || (GetAsyncKeyState(VK_ESCAPE) & 0x8000))// 屏蔽WIN键,Ctrl+ESC组合键
	{
		return 1;
	}
	// 屏蔽Alt相关键 Alt+Tab 
	if (pKey->flags & LLKHF_ALTDOWN) // Alt按下
	{
		if ('Q' == pKey->vkCode) // Alt+Q退出
		{
			UnhookWindowsHookEx(g_hMouse);
			UnhookWindowsHookEx(g_hLowlevelMouse);
			UnhookWindowsHookEx(g_hKeyboard);
			UnhookWindowsHookEx(g_hLowlevelKeyboard);
			SendMessage(g_hWnd, WM_CLOSE, 0, 0);
		}
		return 1;
	}
	return CallNextHookEx(g_hLowlevelKeyboard, nCode, wParam, lParam);
}

在调用主进程中,通过动态加载,调用以上DLL导出的函数SetKeymsHook安装全局钩子,创建互斥对象,仅允许主程序运行一个实例,调用程序主要代码实现:

typedef BOOL(__stdcall *HookFun)(HWND hwnd);//定义函数指针

HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, 0, 0, nullptr, nullptr, hInstance, nullptr);
HANDLE hMutex = CreateMutex(NULL, TRUE, _T("KeymsLock")); //只允许运行一个实例
if (hMutex)
{
if (ERROR_ALREADY_EXISTS == GetLastError())
{
return FALSE;
	}
}
HookFun hookfun = 0;
HMODULE hDll = LoadLibrary(_T("KeymsLockHook.dll"));
if (hDll)
{
hookfun = (HookFun)GetProcAddress(hDll, "SetKeymsHook");
if (!hookfun)
{
MessageBox(hWnd, _T("获取模块地址失败!"), _T("提示"), 0);
return FALSE;
}
}
else
{
	MessageBox(hWnd, _T("加载Dll失败!"), _T("提示"), 0);
	return FALSE;
}
if (!hookfun(hWnd))	return FALSE; // - 安装鼠标键盘钩子

       至此,除了Ctrl+Alt+Del、Win+L组合键之外,其他能想到的都屏蔽了,对于这两个组合键的屏蔽,论坛中有位前辈很早之前就写了一篇文章,但是不知道为什么帖子被删了,还好有幸找到了:

https://blog.csdn.net/linfei2707/article/details/25237671

文章提到四种想法,其中第四种方法堪称完美,好像这也是不用驱动实现屏蔽这两个组合键的最佳方法了。若想看具体原理和调试过程方法,请看该前辈的帖子,笔者win7 64位系统winlogon.exe中主要部分如下:

; Win+L的ID为5、Ctrl+Shift+Esc的ID为4、Ctrl+Alt+Del的ID为0
.text:000000010001484C    83 FB 04                 cmp     ebx, 4
.text:000000010001484F    0F 84 18 2C 00 00          jz      loc_10001746D
.text:0000000100014855    83 FB 05                  cmp     ebx, 5
.text:0000000100014858    0F 84 60 2C 00 00          jz      loc_1000174BE
.text:000000010001485E    83 FB 06                  cmp     ebx, 6
.text:0000000100014861    0F 84 87 2C 00 00          jz      loc_1000174EE
.text:0000000100014867    83 FB 07                  cmp     ebx, 7
.text:000000010001486A    0F 84 B9 2C 00 00          jz      loc_100017529
.text:0000000100014870    83 FB 08                  cmp     ebx, 8
.text:0000000100014873    0F 84 DE 2C 00 00          jz      loc_100017557
.text:0000000100014879    83 FB 09                  cmp     ebx, 9
.text:000000010001487C    0F 84 03 2D 00 00          jz      loc_100017585
.text:0000000100014882    85 DB                    test    ebx, ebx
;  3B DB  ====>  cmp ebx, ebx
.text:0000000100014884    75 45                     jnz     short loc_1000148CB

其中,Win+L很好屏蔽,将cmp ebx,5中的立即数改为其他比较大的值即可实现;Ctrl+Alt+Del有两个语句

test ebx,ebx                           ;85 DB
jnz shrort loc_1000148CB               ;75 45

按下Ctrl+Alt+Del时,ebx=0;所以可以通过85改为3B,75改为74改动两个字节即可,按下Alt+Q退出时可以还原。

cmp ebx,ebx                            ;3B DB
jz shrort loc_1000148CB	               ;74 45

具体实现笔者用远线程注入到winlogon.exe中进行修改,远线程注入DLL中代码如下:

BOOL SetHotkeyStatus(BOOL bFlag) // TRUE => 恢复CAD WL为可用状态; FALSE => 禁用CAD WL
{
	const BYTE btWLOri = 0x5; // Win+L 的ID为5
	const BYTE btCADJnzOri = 0x75;
	const BYTE btWLMod = 0x55;
	const BYTE btCADJnzMod = 0x74;
	const BYTE btCADTstOri = 0x85;
	const BYTE btCADTstMod = 0x3b;

	HMODULE hWlg = GetModuleHandle(0);
	LPVOID lpAddrWL = (LPVOID)((LPSTR)hWlg + 0x14857);
	LPVOID lpAddrCadTst = (LPVOID)((LPSTR)hWlg + 0x14882);
	LPVOID lpAddrCadJnz = (LPVOID)((LPSTR)hWlg + 0x14884);

	BYTE btReadWL = *(BYTE*)lpAddrWL;
	BYTE btReadCadTst = *(BYTE*)lpAddrCadTst;
	BYTE btReadCadJnz = *(BYTE*)lpAddrCadJnz;

	DWORD dwOldProtect = 0;
	if (bFlag)
	{
		if (btWLMod == btReadWL && btCADJnzMod == btReadCadJnz && btCADTstMod==btReadCadTst) // - 将CAD WL置为可用状态
		{
			VirtualProtect(lpAddrWL, 1, PAGE_EXECUTE_READWRITE, &dwOldProtect);
			*(BYTE*)lpAddrWL = btWLOri;
			VirtualProtect(lpAddrWL, 1, dwOldProtect, &dwOldProtect);

			VirtualProtect(lpAddrCadTst, 3, PAGE_EXECUTE_READWRITE, &dwOldProtect);
			*(BYTE*)lpAddrCadTst = btCADTstOri;
			*(BYTE*)lpAddrCadJnz = btCADJnzOri;
			VirtualProtect(lpAddrCadTst, 3, dwOldProtect, &dwOldProtect);

			return TRUE;
		}
	}
	else
	{
		if (btWLOri == btReadWL && btCADJnzOri == btReadCadJnz && btCADTstOri==btReadCadTst) // - 将CAD WL置为禁用状态
		{
			VirtualProtect(lpAddrWL, 1, PAGE_EXECUTE_READWRITE, &dwOldProtect);
			*(BYTE*)lpAddrWL = btWLMod;
			VirtualProtect(lpAddrWL, 1, dwOldProtect, &dwOldProtect);

			VirtualProtect(lpAddrCadTst, 3, PAGE_EXECUTE_READWRITE, &dwOldProtect);
			*(BYTE*)lpAddrCadTst = btCADTstMod;
			*(BYTE*)lpAddrCadJnz = btCADJnzMod;
			VirtualProtect(lpAddrCadTst, 3, dwOldProtect, &dwOldProtect);

			return TRUE;
		}
	}
	return FALSE;
}

BOOL WINAPI DllMain(HMODULE hModule,
	DWORD  dwReason,
	LPVOID lpReserved
)
{
	g_hInst = hModule;
	switch (dwReason)
	{
		case DLL_PROCESS_ATTACH:
		{
			if (SetHotkeyStatus(FALSE))
			{
				MessageBeep(MB_ICONWARNING);
			}
			return TRUE;
		}
		case DLL_THREAD_ATTACH:
			return FALSE;
		case DLL_THREAD_DETACH:
			return FALSE;
		case DLL_PROCESS_DETACH:
		{
			if (SetHotkeyStatus(TRUE))
			{
				MessageBeep(MB_ICONINFORMATION);
			}
		}
		return FALSE;
	}
	return FALSE;
}
调用主程序中,远线程注入和卸载部分主要参考《Windows核心编程》相关,实现代码如下:
typedef BOOL(__stdcall *HookFun)(HWND hwnd);//定义函数指针

HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, 0, 0, nullptr, nullptr, hInstance, nullptr);
HANDLE hMutex = CreateMutex(NULL, TRUE, _T("KeymsLock")); //只允许运行一个实例
if (hMutex)
{
if (ERROR_ALREADY_EXISTS == GetLastError())
{
return FALSE;
	}
}
HookFun hookfun = 0;
HMODULE hDll = LoadLibrary(_T("KeymsLockHook.dll"));
if (hDll)
{
hookfun = (HookFun)GetProcAddress(hDll, "SetKeymsHook");
if (!hookfun)
{
MessageBox(hWnd, _T("获取模块地址失败!"), _T("提示"), 0);
return FALSE;
}
}
else
{
	MessageBox(hWnd, _T("加载Dll失败!"), _T("提示"), 0);
	return FALSE;
}
if (!hookfun(hWnd))	return FALSE; // - 安装鼠标键盘钩子

       至此,除了Ctrl+Alt+Del、Win+L组合键之外,其他能想到的都屏蔽了,对于这两个组合键的屏蔽,论坛中有位前辈很早之前就写了一篇文章,但是不知道为什么帖子被删了,还好有幸找到了:

https://blog.csdn.net/linfei2707/article/details/25237671

文章提到四种想法,其中第四种方法堪称完美,好像这也是不用驱动实现屏蔽这两个组合键的最佳方法了。若想看具体原理和调试过程方法,请看该前辈的帖子,笔者win7 64位系统winlogon.exe中主要部分如下:

; Win+L的ID为5、Ctrl+Shift+Esc的ID为4、Ctrl+Alt+Del的ID为0
.text:000000010001484C    83 FB 04                 cmp     ebx, 4
.text:000000010001484F    0F 84 18 2C 00 00          jz      loc_10001746D
.text:0000000100014855    83 FB 05                  cmp     ebx, 5
.text:0000000100014858    0F 84 60 2C 00 00          jz      loc_1000174BE
.text:000000010001485E    83 FB 06                  cmp     ebx, 6
.text:0000000100014861    0F 84 87 2C 00 00          jz      loc_1000174EE
.text:0000000100014867    83 FB 07                  cmp     ebx, 7
.text:000000010001486A    0F 84 B9 2C 00 00          jz      loc_100017529
.text:0000000100014870    83 FB 08                  cmp     ebx, 8
.text:0000000100014873    0F 84 DE 2C 00 00          jz      loc_100017557
.text:0000000100014879    83 FB 09                  cmp     ebx, 9
.text:000000010001487C    0F 84 03 2D 00 00          jz      loc_100017585
.text:0000000100014882    85 DB                    test    ebx, ebx
;  3B DB  ====>  cmp ebx, ebx
.text:0000000100014884    75 45                     jnz     short loc_1000148CB

其中,Win+L很好屏蔽,将cmp ebx,5中的立即数改为其他比较大的值即可实现;Ctrl+Alt+Del有两个语句

test ebx,ebx                           ;85 DB
jnz shrort loc_1000148CB               ;75 45

按下Ctrl+Alt+Del时,ebx=0;所以可以通过85改为3B,75改为74改动两个字节即可,按下Alt+Q退出时可以还原。

cmp ebx,ebx                            ;3B DB
jz shrort loc_1000148CB	               ;74 45

具体实现笔者用远线程注入到winlogon.exe中进行修改,远线程注入DLL中代码如下:

BOOL SetHotkeyStatus(BOOL bFlag) // TRUE => 恢复CAD WL为可用状态; FALSE => 禁用CAD WL
{
	const BYTE btWLOri = 0x5; // Win+L 的ID为5
	const BYTE btCADJnzOri = 0x75;
	const BYTE btWLMod = 0x55;
	const BYTE btCADJnzMod = 0x74;
	const BYTE btCADTstOri = 0x85;
	const BYTE btCADTstMod = 0x3b;

	HMODULE hWlg = GetModuleHandle(0);
	LPVOID lpAddrWL = (LPVOID)((LPSTR)hWlg + 0x14857);
	LPVOID lpAddrCadTst = (LPVOID)((LPSTR)hWlg + 0x14882);
	LPVOID lpAddrCadJnz = (LPVOID)((LPSTR)hWlg + 0x14884);

	BYTE btReadWL = *(BYTE*)lpAddrWL;
	BYTE btReadCadTst = *(BYTE*)lpAddrCadTst;
	BYTE btReadCadJnz = *(BYTE*)lpAddrCadJnz;

	DWORD dwOldProtect = 0;
	if (bFlag)
	{
		if (btWLMod == btReadWL && btCADJnzMod == btReadCadJnz && btCADTstMod==btReadCadTst) // - 将CAD WL置为可用状态
		{
			VirtualProtect(lpAddrWL, 1, PAGE_EXECUTE_READWRITE, &dwOldProtect);
			*(BYTE*)lpAddrWL = btWLOri;
			VirtualProtect(lpAddrWL, 1, dwOldProtect, &dwOldProtect);

			VirtualProtect(lpAddrCadTst, 3, PAGE_EXECUTE_READWRITE, &dwOldProtect);
			*(BYTE*)lpAddrCadTst = btCADTstOri;
			*(BYTE*)lpAddrCadJnz = btCADJnzOri;
			VirtualProtect(lpAddrCadTst, 3, dwOldProtect, &dwOldProtect);

			return TRUE;
		}
	}
	else
	{
		if (btWLOri == btReadWL && btCADJnzOri == btReadCadJnz && btCADTstOri==btReadCadTst) // - 将CAD WL置为禁用状态
		{
			VirtualProtect(lpAddrWL, 1, PAGE_EXECUTE_READWRITE, &dwOldProtect);
			*(BYTE*)lpAddrWL = btWLMod;
			VirtualProtect(lpAddrWL, 1, dwOldProtect, &dwOldProtect);

			VirtualProtect(lpAddrCadTst, 3, PAGE_EXECUTE_READWRITE, &dwOldProtect);
			*(BYTE*)lpAddrCadTst = btCADTstMod;
			*(BYTE*)lpAddrCadJnz = btCADJnzMod;
			VirtualProtect(lpAddrCadTst, 3, dwOldProtect, &dwOldProtect);

			return TRUE;
		}
	}
	return FALSE;
}

BOOL WINAPI DllMain(HMODULE hModule,
	DWORD  dwReason,
	LPVOID lpReserved
)
{
	g_hInst = hModule;
	switch (dwReason)
	{
		case DLL_PROCESS_ATTACH:
		{
			if (SetHotkeyStatus(FALSE))
			{
				MessageBeep(MB_ICONWARNING);
			}
			return TRUE;
		}
		case DLL_THREAD_ATTACH:
			return FALSE;
		case DLL_THREAD_DETACH:
			return FALSE;
		case DLL_PROCESS_DETACH:
		{
			if (SetHotkeyStatus(TRUE))
			{
				MessageBeep(MB_ICONINFORMATION);
			}
		}
		return FALSE;
	}
	return FALSE;
}
调用主程序中,远线程注入和卸载部分主要参考《Windows核心编程》相关,实现代码如下:
; Win+L的ID为5、Ctrl+Shift+Esc的ID为4、Ctrl+Alt+Del的ID为0
.text:000000010001484C    83 FB 04                 cmp     ebx, 4
.text:000000010001484F    0F 84 18 2C 00 00          jz      loc_10001746D
.text:0000000100014855    83 FB 05                  cmp     ebx, 5
.text:0000000100014858    0F 84 60 2C 00 00          jz      loc_1000174BE
.text:000000010001485E    83 FB 06                  cmp     ebx, 6
.text:0000000100014861    0F 84 87 2C 00 00          jz      loc_1000174EE
.text:0000000100014867    83 FB 07                  cmp     ebx, 7
.text:000000010001486A    0F 84 B9 2C 00 00          jz      loc_100017529
.text:0000000100014870    83 FB 08                  cmp     ebx, 8
.text:0000000100014873    0F 84 DE 2C 00 00          jz      loc_100017557
.text:0000000100014879    83 FB 09                  cmp     ebx, 9
.text:000000010001487C    0F 84 03 2D 00 00          jz      loc_100017585
.text:0000000100014882    85 DB                    test    ebx, ebx
;  3B DB  ====>  cmp ebx, ebx
.text:0000000100014884    75 45                     jnz     short loc_1000148CB

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 1
支持
分享
最新回复 (12)
雪    币: 193
活跃值: (1212)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
支持
2018-6-17 10:22
0
雪    币: 2194
活跃值: (1001)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
如果可以的话,整个工程把代码放github。
2018-6-17 10:44
0
雪    币: 6
活跃值: (35)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
很可惜不能截获Ctrl+Alt+Del
2018-6-19 20:06
0
雪    币: 1573
活跃值: (198)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
5
彪哥大大 很可惜不能截获Ctrl+Alt+Del
。。。。。仔细看!!!
最后于 2018-6-19 20:12 被Thvoifar编辑 ,原因:
2018-6-19 20:10
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
mark.
2018-10-12 22:06
0
雪    币: 135
活跃值: (76)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
但是这种方法有个问题,即系统不同,需要修改的字节在winlogon中的偏移也会有所不同,所以如果要写个具有普遍性的程序还需搜索找到要修改的偏移.
这个应该可以通过特征码搜索winlogon.exe的内存来动态获取要修改的内存地址吧.
2018-10-27 17:05
0
雪    币: 9
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
这个Hook不到DirectInput把
2018-10-29 18:33
0
雪    币: 1036
活跃值: (1311)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
9
用键盘过滤驱动啊 
2018-10-29 19:10
0
雪    币: 9072
活跃值: (1615)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
10
很高深,学习了
2018-10-30 07:09
0
雪    币: 47
活跃值: (110)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
内存地址那里不应该是固定的吧。。
2018-10-31 17:43
0
雪    币: 1573
活跃值: (198)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
12
wkaka 但是这种方法有个问题,即系统不同,需要修改的字节在winlogon中的偏移也会有所不同,所以如果要写个具有普遍性的程序还需搜索找到要修改的偏移. 这个应该可以通过特征码搜索winlogon.exe的 ...
是的,这也是个缺陷
2019-1-1 13:25
0
雪    币: 1573
活跃值: (198)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
13
MarvelousD 内存地址那里不应该是固定的吧。。
对,不是固定的,应该想办法找到这个地址,有好方法可以分享出来!
2019-1-1 13:26
0
游客
登录 | 注册 方可回帖
返回
//