HOOk 系统热键屏蔽

Ctr+Alt+Del是Winlogon的热键,WinlogoN是SYSTEM的进程,它不在当前用户的会话中,机制不一样的啦。


消息循环很简单
MSG msg;
while(GetMessageW(&msg,0,0,0)!=-1)DispatchMessageW(&msg);
它们没加是因为它们的界面就有消息循环

不是全局钩子都要在dll中,WH_MOUSE_LL就不需要,调用SetWindowsHookEx的线程需要有一个消息循环才能得到钩子被触发的通知,然后调用钩子过程,WH_MOUSE_LL的钩子过程是由调用SetWindowsHookEx的线程执行的 

[我感觉是错的]



在编写程序的过程中,我们有时需要实现屏蔽操作系统一些热键的功能,如(ctrl+delete+alt,ctrl+shift+esc等)。网络上有很多关于这方面的资料,总结了一下,一般有如下两个方法:

    1. 通过加载低级键盘钩子(WH_KEYBOARD_LL)截获大部分的系统热键,并屏蔽它。这个方法比较简单,但有个缺陷,那就是对ctrl+alt+delete没有办法。

    2. 通过远程注入dll到winlogon进程,修改winlogon桌面下SAS窗口的回调函数,从而捕获该窗口的WM_HOTKEY消息,并屏蔽它,可以实现屏蔽ctrl+delete+alt。这个方法相对复杂,可以解决第一点中存在的问题,但是也有缺陷,那就是除了ctrl+delete+alt外,大多数的其它系统热键,(包括alt+tab,ctrl+esc及左右两个windows键)都无法屏蔽。

    所以如果我们的程序需要屏蔽大量的系统热键,就应当将以上两个方法结合起来使用。dll注入有很多好处,包括可以实现对我们所运行进程的隐藏,这非常有用。当我们的进程运行后,屏蔽掉了系统热键,当然不想用户随便在进程管理器里面就kill掉,因此将以上两个方法结合的办法就是把代码通通写到dll里面,然后再一起注入到winlogon进程中。

    对于上面所讲的第二点,注入到winlogon进程,没问题,可以很好的完成功能(网上有很多相关的文章及代码)。但对于第一点,如果在一个GUI程序中加载钩子,也没有问题。但现在加载的对象是winlogin进程,这个进程很特殊,它不是GUI进程,也不在系统应用程序所处的Default桌面下,因此在这个进程中加载钩子,需要注意以下几点:

    1. 在需要注入的dll代码中的DLL_PROCESS_ATTACH后面开启一个新线程,并在该线程中实现修改SAS窗口回调函数的代码以及设置低级键盘钩子。

    2. 由于钩子所在的线程为非GUI线程,因此,必须在该线程成功设置钩子以后主动接收并分发收到的消息,否则钩子将不会钩到任何消息:
       
 MSG msg;
        while(GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

    3. 由于该线程创建时默认与winlogon同属一个桌面(winlogon桌面),而其它包括explorer.exe在内的GUI程序都处在Default桌面,在windows中规定程序只能获得针对同一桌面上创建的窗口消息。所以,要让该线程能接收到用户在Default桌面下操作所产生的消息,必须在该线程中使用如下代码将它的桌面设置为Default桌面:

        HDESK hDesk = OpenDesktop("Default",0,FALSE,MAXIMUM_ALLOWED);
        SetThreadDesktop(hDesk);
        CloseHandle(hDesk);

    我的程序在解决了以上问题之后,能正确将所编写的dll注入到winlogon进程,并在dll加载的时候开启线程,设置钩子,替换SAS窗口回调函数。从而实现屏蔽了我所能想到的所有系统热键。

    附:DLL的完整源码(注入该DLL到winlogon进程的源码大家可以在网上找到)

#define _WIN32_WINNT 0x0500 //Use WH_KEYBOARD_LL

#include <windows.h>
#include <stdio.h>

//SAS window句柄
HWND hSASWnd = NULL;
//原有SAS window回调函数地址
FARPROC FOldProc = NULL;
//起屏蔽作用的新SAS window回调函数
LRESULT CALLBACK SASWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
//枚举所有窗体句柄的回调函数
BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam);

//Dll所创建线程的句柄
HANDLE hThread = NULL;
//Dll所创建线程的ID
DWORD dwThreadId = 0;
//Dll所创建线程的线程函数
DWORD WINAPI ThreadFunc();

//_H钩子句柄
HHOOK hHook = NULL;
//_H低级键盘钩子回调函数
LRESULT CALLBACK KeyboardProc(int,WPARAM,LPARAM);

//对外输出字符串
char szOutput[36];

BOOL APIENTRY DllMain(HANDLE hMoudle, DWORD dwReason, LPVOID lpReserved)
{
    switch(dwReason)
 {
        case DLL_PROCESS_ATTACH:
   sprintf(szOutput,"Dll成功加载于 %d 号进程。",GetCurrentProcessId());
   OutputDebugString(szOutput);

   //创建更替SAS window回调函数的线程
   if(FOldProc == NULL)
    hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc,NULL,0,&dwThreadId);
   break;
        case DLL_PROCESS_DETACH:
   sprintf(szOutput,"Dll成功卸载。",GetCurrentProcessId());
   //MessageBox(NULL, szOutput, "ZZ", MB_ICONINFORMATION | MB_OK);
   OutputDebugString(szOutput);

   //恢复原有SAS window的回调函数
   if(FOldProc != NULL)
                SetWindowLong(hSASWnd,GWL_WNDPROC,long(FOldProc));
            
   //_H卸载低级键盘钩子
   if(hHook != NULL)
   {
    if(!UnhookWindowsHookEx(hHook))
    {
     OutputDebugString("Unhook failed..");
     //__leave;
     break;
    }
    OutputDebugString("键盘钩子成功取消");
   }
   TerminateThread(hThread,1);
   CloseHandle(hThread);

   break;
        case DLL_THREAD_ATTACH:
   break;
        case DLL_THREAD_DETACH:
   break;
    }
    return TRUE;
}

//Dll所创建线程的线程函数
DWORD WINAPI ThreadFunc()
{
    //打开Winlogon桌面
    HDESK hDesk = OpenDesktop("Winlogon",0,FALSE,MAXIMUM_ALLOWED);

 //枚举桌面所有窗体
    EnumDesktopWindows(hDesk,(WNDENUMPROC)EnumWindowsProc,0);
 //修改SAS window的回调函数
    if(hSASWnd != NULL)
    {
        FOldProc = (FARPROC)SetWindowLong(hSASWnd,GWL_WNDPROC,long(SASWindowProc));
    }
    CloseHandle(hDesk);

 //_H同一桌面上进程之间只能发送窗口消息。无法跨进程与其他桌面发送它们。 
 //_H同样,Windows消息是限制应用程序定义挂钩。
 //_H特定桌面中运行的进程挂钩过程将〈〈只获得针对同一桌面上创建窗口消息。〉〉
 //_H详见
http://support.microsoft.com/kb/171890/zh-cn
 //_H所以,这里必须设置钩子所在线程的桌面为Default桌面
 //_H才能使得钩子所在线程能接收到Default桌面的消息
 hDesk = OpenDesktop("Default",0,FALSE,MAXIMUM_ALLOWED);
 SetThreadDesktop(hDesk);
 CloseHandle(hDesk);

 //_H设置低级键盘钩子,屏蔽非SAS window的热键
 //_H需要#define _WIN32_WINNT 0x0500
 hHook = SetWindowsHookEx(WH_KEYBOARD_LL,KeyboardProc,GetModuleHandle(NULL),0);
 if (hHook == NULL)
 {
  OutputDebugString("Set hook failed..");
  //__leave;
  return 1;
 }
 OutputDebugString("键盘钩子成功设置");

 //_H在非GUI线程中使用消息钩子必须主动接收并分发收到的消息
 MSG msg;
 while(GetMessage(&msg, NULL, 0, 0))
 {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
 }

 return 1;
}

//枚举所有窗体句柄的回调函数
BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam)
{
    char ClassBuf[128];
 //获得当前窗体的显示文本
    GetWindowText(hwnd,ClassBuf,sizeof(ClassBuf));

    //在"Winlogon"桌面中查询窗口"SAS window"。
 if(strstr(ClassBuf,"SAS window")!=NULL)
 {
        //返回SAS window句柄
  hSASWnd = hwnd;
        return FALSE;
    }
    return TRUE;
}

//起屏蔽作用的新SAS window回调函数
LRESULT CALLBACK SASWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
    if(uMsg == WM_HOTKEY)
    {
  //屏蔽所有WM_HOTKEY消息
  OutputDebugString("All SAS window's hotkeys are disabled");
  return 1;

        WORD wKey = HIWORD(lParam);
        WORD wModifier = LOWORD(lParam);
        bool IsCtrlDown = ((wModifier & VK_CONTROL) != 0);
        bool IsAltDown = ((wModifier & VK_MENU) != 0);
        bool IsShiftDown = ((wModifier & VK_SHIFT) != 0);

        //Ctrl + Alt + Del组合键
        if(IsCtrlDown && IsAltDown && wKey == VK_DELETE)
        {
   return 1; //屏蔽
        }
        //Ctrl + Shift + Esc组合键,这个组合键将显示任务管理器,可根据需要是否屏蔽。
        else if(IsCtrlDown && IsShiftDown && wKey == VK_ESCAPE)
        {
            // Do nothing
        }
    }

    return CallWindowProc((WNDPROC)FOldProc,hwnd,uMsg,wParam,lParam);
}

//_H低级键盘钩子回调函数
LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)
{
 if (nCode == HC_ACTION)
 {
        switch (wParam)
  {
   case WM_KEYDOWN:  case WM_SYSKEYDOWN:
   //case WM_KEYUP:    case WM_SYSKEYUP:
   PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) lParam;

   if (p->vkCode == VK_F12)
   {
    //实现模拟按键代码
    MessageBox(GetForegroundWindow(),"I'm in position..","ZZ",MB_OK);
   }
   //屏蔽ALT+TAB
   else if ((p->vkCode == VK_TAB) && ((p->flags & LLKHF_ALTDOWN) != 0))
   {
    OutputDebugString("ALT+TAB is disabled");
    return 1;
   }
   //屏蔽ALT+ESC
   else if ((p->vkCode == VK_ESCAPE) && ((p->flags & LLKHF_ALTDOWN) != 0))
   {
    OutputDebugString("ALT+ESC is disabled");
    return 1;
   }
   //屏蔽CTRL+ESC
   else if ((p->vkCode == VK_ESCAPE) && ((GetKeyState(VK_CONTROL) & 0x8000) != 0))
   {
    OutputDebugString("CTRL+ESC is disabled");
    return 1;
   }
   //屏蔽CTRL+SHIFT+ESC,(SAS window中也已屏蔽)
   else if ((p->vkCode == VK_ESCAPE) &&
    ((GetKeyState(VK_CONTROL) & 0x8000) != 0) &&
    ((GetKeyState(VK_SHIFT) & 0x8000) != 0))
   {
    OutputDebugString("CTRL+SHIFT+ESC is disabled");
    return 1;
   }
   //屏蔽左右windows键
   else if (p->vkCode == VK_LWIN || p->vkCode == VK_RWIN)
   {
    OutputDebugString("windows key is disabled");
    return 1;
   }
   //此处无法屏蔽CTRL+ALT+DEL,已在SAS window中屏蔽
   else if ((p->vkCode == VK_DELETE) &&
     ((GetKeyState(VK_CONTROL) & 0x8000) != 0) &&
     ((GetKeyState(VK_MENU) & 0x8000) != 0 ))
    return 1;

   break;
  }
 }

 return CallNextHookEx(hHook,nCode,wParam,lParam);
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MICROSOFT FOUNDATION CLASS LIBRARY : ShieldPower AppWizard has created this ShieldPower application for you. This application not only demonstrates the basics of using the Microsoft Foundation classes but is also a starting point for writing your application. This file contains a summary of what you will find in each of the files that make up your ShieldPower application. ShieldPower.dsp This file (the project file) contains information at the project level and is used to build a single project or subproject. Other users can share the project (.dsp) file, but they should export the makefiles locally. ShieldPower.h This is the main header file for the application. It includes other project specific headers (including Resource.h) and declares the CShieldPowerApp application class. ShieldPower.cpp This is the main application source file that contains the application class CShieldPowerApp. ShieldPower.rc This is a listing of all of the Microsoft Windows resources that the program uses. It includes the icons, bitmaps, and cursors that are stored in the RES subdirectory. This file can be directly edited in Microsoft Visual C++. ShieldPower.clw This file contains information used by ClassWizard to edit existing classes or add new classes. ClassWizard also uses this file to store information needed to create and edit message maps and dialog data maps and to create prototype member functions. res\ShieldPower.ico This is an icon file, which is used as the application's icon. This icon is included by the main resource file ShieldPower.rc. res\ShieldPower.rc2 This file contains resources that are not edited by Microsoft Visual C++. You should place all resources not editable by the resource editor in this file. ///////////////////////////////////////////////////////////////////////////// AppWizard creates one dialog class: ShieldPowerDlg.h, ShieldPowerDlg.cpp - the dialog These files contain your CShieldPowerDlg class. This class defines the behavior of your application's main dialog. The dialog's template is in ShieldPower.rc, which can be edited in Microsoft Visual C++. ///////////////////////////////////////////////////////////////////////////// Other standard files: StdAfx.h, StdAfx.cpp These files are used to build a precompiled header (PCH) file named ShieldPower.pch and a precompiled types file named StdAfx.obj. Resource.h This is the standard header file, which defines new resource IDs. Microsoft Visual C++ reads and updates this file. ///////////////////////////////////////////////////////////////////////////// Other notes: AppWizard uses "TODO:" to indicate parts of the source code you should add to or customize. If your application uses MFC in a shared DLL, and your application is in a language other than the operating system's current language, you will need to copy the corresponding localized resources MFC42XXX.DLL from the Microsoft Visual C++ CD-ROM onto the system or system32 directory, and rename it to be MFCLOC.DLL. ("XXX" stands for the language abbreviation. For example, MFC42DEU.DLL contains resources translated to German.) If you don't do this, some of the UI elements of your application will remain in the language of the operating system. /////////////////////////////////////////////////////////////////////////////
### 回答1: Linux Hook 系统调用是指在 Linux 操作系统中,通过修改系统调用表来拦截和修改系统调用的行为。这种技术可以用于实现各种功能,如监控系统调用、实现安全策略、实现虚拟化等。Hook 系统调用的实现方式有多种,如使用内核模块、使用 LD_PRELOAD 环境变量、使用 ptrace 等。但是,Hook 系统调用也可能会带来一些安全风险,因此需要谨慎使用。 ### 回答2: Linux系统中的hook是一种通过修改系统内核来实现对系统或应用程序行为的改变的技术手段。hook技术的实现方式有很多种,比如LD_PRELOAD,在程序运行前拦截系统调用,重定向到用户编写的函数中,实现对系统调用进行Hook;也可以修改内核源代码,在内核中添加对指定系统调用的Hook函数,并重新编译部署内核。 在Linux系统中,Hook技术被广泛运用于安全防护、性能优化、监控记录等领域。安全防护方面,通过Hook技术可以拦截进程的系统调用,实现对安全攻击的检测和防范;在性能优化方面,Hook技术可以记录系统资源使用情况,进行优化分析;在监控记录方面,Hook技术可以通过修改系统调用返回值,实现对应用程序的状态监控和记录等功能。 Hook技术的实现需要一定的计算机专业知识和技能,同时也需要了解目标系统的内部运行机制和系统调用的使用方法。在使用时需要注意,Hook技术对系统稳定性和性能会产生影响,需要谨慎使用和调试。同时,在使用Hook技术时需要考虑到实现方式的兼容性、对日后维护的影响等问题,从而保证Hook技术的稳健性和长期有效性。 综上所述,在Linux系统中,Hook技术是一种应用广泛、有效性高的技术手段,可以实现对系统和应用程序行为的灵活定制和改变,通过对系统调用的拦截和修改,实现安全防护、性能优化、监控记录等多种功能。不过,在使用时需要注意风险和影响,选择合适的实现方式,从而确保Hook技术的有效性和稳健性。 ### 回答3: Linux 系统调用是操作系统的一个重要组成部分,它提供了应用程序与操作系统之间通信的桥梁,使得应用程序可以利用操作系统的功能进行各种操作。然而,在某些情况下,用户可能需要修改某些系统调用的行为或者监控它们的使用情况,这就需要使用 Linux hook 系统调用。 Linux hook 系统调用,也称为系统调用钩子,是一种在系统调用进行时拦截和修改系统调用的技术。其主要作用是通过程序实现拦截和修改系统调用的行为,以达到特定的目的。比如,通过修改文件访问系统调用的行为,可以对文件进行加密、解密和防止恶意软件操作等。 Linux hook 系统调用的实现方式有很多种,其中最常见的方式就是使用内核模块实现。内核模块是一种动态加载到内核中的代码,可以通过内核提供的对模块的管理函数进行加载、卸载和修改等操作。利用内核模块,可以实现对指定系统调用的拦截与修改,具体实现方法是通过在模块中添加指定系统调用的替代函数来实现。 除此之外,还可以使用 LD_PRELOAD 环境变量或者 ptrace 系统调用来实现 Linux hook 系统调用。其中,LD_PRELOAD 环境变量是一种可以动态加载库文件的方法,通过在 LD_PRELOAD 中指定某个库文件,可以在程序运行时优先加载该库文件,从而实现对系统调用的拦截;而 ptrace 系统调用则是一种常用的系统调用监控方法,可以用来检测系统调用的调用次数、参数和返回结果等信息。 总体来说,Linux hook 系统调用是一种非常实用的技术,可以用来实现各种监控和安全保障功能。但是,在使用时需要注意保证系统的稳定性和安全性,避免出现非预期的系统崩溃或安全漏洞。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值