첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

■ 후킹을 사용해 화면 잠그기

----------------------------------------------------------------------------------------------------


TestProject.zip


MainForm.cs

 

 

using Microsoft.Win32;

using System;

using System.Diagnostics;

using System.Drawing;

using System.Runtime.InteropServices;

using System.Windows.Forms;

 

namespace TestProject

{

    /// <summary>

    /// 메인 폼

    /// </summary>

    public partial class MainForm : Form

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Structure

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 키보드 저수준 후킹 구조체 - KBDLLHOOKSTRUCT

 

        /// <summary>

        /// 키보드 저수준 후킹 구조체

        /// </summary>

        public struct KBDLLHOOKSTRUCT

        {

            //////////////////////////////////////////////////////////////////////////////////////////////////// Field

            ////////////////////////////////////////////////////////////////////////////////////////// Public

 

            #region Field

 

            /// <summary>

            /// 가상 키 코드

            /// </summary>

            public int VirtualKeyCode;

 

            /// <summary>

            /// 스캔 코드

            /// </summary>

            public int ScanCode;

 

            /// <summary>

            /// 플래그

            /// </summary>

            public int Flags;

 

            /// <summary>

            /// 시간

            /// </summary>

            public int Time;

 

            /// <summary>

            /// 부가 정보

            /// </summary>

            public int ExtraInfo;

 

            #endregion

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Delegate

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region 키보드 후킹 처리 대리자 - ProcessKeyboardHookDelegate(code, wordParameter, longParameter)

 

        /// <summary>

        /// 키보드 후킹 처리 대리자

        /// </summary>

        /// <param name="code">코드</param>

        /// <param name="wordParameter">WORD 매개 변수</param>

        /// <param name="longParameter">LONG 매개 변수</param>

        /// <returns>처리 결과</returns>

        private delegate int ProcessKeyboardHookDelegate(int code, int wordParameter, ref KBDLLHOOKSTRUCT longParameter);

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Import

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Private

 

        #region 윈도우 후킹 설정하기 - SetWindowsHookEx(hookID, processKeyboardHookDelegate, moduleHandle, threadID)

 

        /// <summary>

        /// 윈도우 후킹 설정하기

        /// </summary>

        /// <param name="hookID">후킹 ID</param>

        /// <param name="processKeyboardHookDelegate">키보드 후킹 처리 대리자</param>

        /// <param name="moduleHandle">모듈 핸들</param>

        /// <param name="threadID">스레드 ID</param>

        /// <returns>처리 결과</returns>

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]

        private static extern int SetWindowsHookEx(int hookID, ProcessKeyboardHookDelegate processKeyboardHookDelegate,

            IntPtr moduleHandle, uint threadID);

 

        #endregion

        #region 윈도우 후킹 해제하기 - UnhookWindowsHookEx(hookHandle)

 

        /// <summary>

        /// 윈도우 후킹 해제하기

        /// </summary>

        /// <param name="hookHandle">후킹 핸들</param>

        /// <returns>처리 결과</returns>

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]

        [return: MarshalAs(UnmanagedType.Bool)]

        private static extern bool UnhookWindowsHookEx(int hookHandle);

 

        #endregion

        #region 다음 후킹 호출하기 - CallNextHookEx(hookHandle, code, wordParameter, longParameter)

 

        /// <summary>

        /// 다음 후킹 호출하기

        /// </summary>

        /// <param name="hookHandle">후킹 핸들</param>

        /// <param name="code">코드</param>

        /// <param name="wordParameter">WORD 매개 변수</param>

        /// <param name="longParameter">LONG 매개 변수</param>

        /// <returns>처리 결과</returns>

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]

        private static extern int CallNextHookEx(int hookHandle, int code, int wordParameter, ref KBDLLHOOKSTRUCT longParameter);

 

        #endregion

        #region 모듈 핸들 구하기 - GetModuleHandle(modulName)

 

        /// <summary>

        /// 모듈 핸들 구하기

        /// </summary>

        /// <param name="modulName">모듈명</param>

        /// <returns>모듈 핸들</returns>

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]

        private static extern IntPtr GetModuleHandle(string modulName);

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Private

 

        #region Field

 

        /// <summary>

        /// 키보드 후킹 처리 대리자

        /// </summary>

        private static ProcessKeyboardHookDelegate _processKeyboardHookDelegate = ProcessKeyboardHook;

 

        /// <summary>

        /// 후킹 ID

        /// </summary>

        private static int _hookID = 0;

 

        #endregion

 

        ////////////////////////////////////////////////////////////////////////////////////////// Instance

        //////////////////////////////////////////////////////////////////////////////// Private

 

        #region Field

 

        /// <summary>

        /// WH_KEYBOARD_LL

        /// </summary>

        private const int WH_KEYBOARD_LL = 13;

 

        /// <summary>

        /// WM_KEYDOWN

        /// </summary>

        private const int WM_KEYDOWN = 0x0100;

 

        /// <summary>

        /// WM_KEYUP

        /// </summary>

        private const int WM_KEYUP = 0x0101;

 

        /// <summary>

        /// WM_SYSKEYDOWN

        /// </summary>

        private const int WM_SYSKEYDOWN = 0x0104;

 

        /// <summary>

        /// WM_SYSKEYUP

        /// </summary>

        private const int WM_SYSKEYUP = 0x0105;

 

 

        /// <summary>

        /// 화면 사각형

        /// </summary>

        private Rectangle screenRectangle = Screen.PrimaryScreen.Bounds;

 

        /// <summary>

        /// 마우스 X 좌표

        /// </summary>

        private int mouseX = 0;

 

        /// <summary>

        /// 마우스 Y 좌표

        /// </summary>

        private int mouseY = 0;

 

        /// <summary>

        /// 스크린 세이버 중단 가능 여부

        /// </summary>

        private bool canStopScreenSaver = true;

 

        /// <summary>

        /// 난수 발생기

        /// </summary>

        private Random random = new Random();

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - MainForm()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public MainForm()  

        {

            InitializeComponent();

 

            Load                += Form_Load;

            Click               += Form_Click;

            MouseDown           += Form_MouseDown;

            MouseMove           += Form_MouseMove;

            MouseClick          += Form_MouseClick;

            this.timer.Tick     += timer_Tick;

            this.lockTimer.Tick += lockTimer_Tick;

        }

 

        #endregion

                

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Private

        ////////////////////////////////////////////////////////////////////// Function

 

        #region 키보드 후킹 처리하기 - ProcessKeyboardHook(code, wordParameter, longParameter)

 

        /// <summary>

        /// 키보드 후킹 처리하기

        /// </summary>

        /// <param name="code">코드</param>

        /// <param name="wordParameter">WORD 매개 변수</param>

        /// <param name="longParameter">LONG 매개 변수</param>

        /// <returns>처리 결과</returns>

        private static int ProcessKeyboardHook(int code, int wordParameter, ref KBDLLHOOKSTRUCT longParameter)

        {

            bool result = false;

 

            switch(wordParameter)

            {

                case WM_KEYDOWN    :

                case WM_KEYUP      :

                case WM_SYSKEYDOWN :

                case WM_SYSKEYUP   :

 

                    result = ((longParameter.VirtualKeyCode == 0x09) && (longParameter.Flags == 0x20)) || // Alt + Tab

                             ((longParameter.VirtualKeyCode == 0x1B) && (longParameter.Flags == 0x20)) || // Alt + Esc

                             ((longParameter.VirtualKeyCode == 0x1B) && (longParameter.Flags == 0x00)) || // Ctrl + Esc

                             ((longParameter.VirtualKeyCode == 0x5B) && (longParameter.Flags == 0x01)) || // Left Windows Key

                             ((longParameter.VirtualKeyCode == 0x5C) && (longParameter.Flags == 0x01)) || // Right Windows Key

                             ((longParameter.VirtualKeyCode == 0x73) && (longParameter.Flags == 0x20));   // Alt + F4

 

                    break;

            }

 

            if(result == true)

            {

                return 1;

            }

            else

            {

                return CallNextHookEx(0, code, wordParameter, ref longParameter);

            }

        }

 

        #endregion

 

        ////////////////////////////////////////////////////////////////////////////////////////// Instance

        //////////////////////////////////////////////////////////////////////////////// Private

        ////////////////////////////////////////////////////////////////////// Event

 

        #region 폼 로드시 처리하기 - Form_Load(sender, e)

 

        /// <summary>

        /// 폼 로드시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void Form_Load(object sender, EventArgs e)

        {

            this.timer.Enabled     = true;

            this.lockTimer.Enabled = true;

 

            this.canStopScreenSaver = true;

 

            Cursor.Hide();

 

            DisableTaskManager();

 

            _hookID = SetHook(_processKeyboardHookDelegate);

        }

 

        #endregion

        #region 폼 클릭시 처리하기 - Form_Click(sender, e)

 

        /// <summary>

        /// 폼 클릭시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void Form_Click(object sender, EventArgs e)

        {

            StopScreenSaver();

        }

 

        #endregion

        #region 폼 마우스 DOWN 처리하기 - Form_MouseDown(sender, e)

 

        /// <summary>

        /// 폼 마우스 DOWN 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void Form_MouseDown(object sender, MouseEventArgs e)

        {

            StopScreenSaver();

        }

 

        #endregion

        #region 폼 마우스 이동시 처리하기 - Form_MouseMove(sender, e)

 

        /// <summary>

        /// 폼 마우스 이동시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void Form_MouseMove(object sender, MouseEventArgs e)

        {

            if((this.mouseX == 0) && (this.mouseY == 0))

            {

                this.mouseX = e.X;

                this.mouseY = e.Y;

 

                return;

            }

            else if((e.X != this.mouseX) || (e.Y != this.mouseY))

            {

                StopScreenSaver();

            }

        }

 

        #endregion

        #region 폼 마우스 클릭시 처리하기 - Form_MouseClick(sender, e)

 

        /// <summary>

        /// 폼 마우스 클릭시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void Form_MouseClick(object sender, MouseEventArgs e)

        {

             StopScreenSaver();

        }

 

        #endregion

 

        #region 타이머 틱 처리하기 - timer_Tick(sender, e)

 

        /// <summary>

        /// 타이머 틱 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void timer_Tick(object sender, EventArgs e)

        {

            int x = this.random.Next(0, this.screenRectangle.Width  - 50);

            int y = this.random.Next(0, this.screenRectangle.Height - 50);

 

            using(Graphics graphics = CreateGraphics())

            {

                Pen pen = new Pen(Color.Yellow, 10);

 

                Rectangle rectangle = new Rectangle(x, y, 100, 100);

 

                graphics.DrawArc(pen, rectangle, 0, 365);

            }

        }

 

        #endregion

        #region 잠금 타이머 틱 처리하기 - lockTimer_Tick(sender, e)

 

        /// <summary>

        /// 잠금 타이머 틱 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void lockTimer_Tick(object sender, EventArgs e)

        {

            this.canStopScreenSaver = false;

 

            this.lockTimer.Enabled = false;

        }

 

        #endregion

 

        ////////////////////////////////////////////////////////////////////// Function

 

        #region 태스크 관리자 비활성화 하기 - DisableTaskManager()

 

        /// <summary>

        /// 태스크 관리자 비활성화 하기

        /// </summary>

        /// <remarks>Ctrl + Alt + Delete 키 입력을 거부한다.</remarks>

        public static void DisableTaskManager()

        {

            RegistryKey registryKey;

            string      keyValue = "1";

            string      subKey   = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";

 

            try

            {

                registryKey = Registry.CurrentUser.CreateSubKey(subKey);

 

                registryKey.SetValue("DisableTaskMgr", keyValue);

 

                registryKey.Close();

            }

            catch(Exception exception)

            {

                MessageBox.Show(exception.Message);

            }

        }

 

        #endregion

        #region 태스크 관리자 활성화 하기 - EnableTaskManager()

 

        /// <summary>

        /// 태스크 관리자 활성화 하기

        /// </summary>

        /// <remarks>Ctrl + Alt + Delete 키 입력을 허용한다.</remarks>

        public static void EnableTaskManager()

        {

            try

            {

                RegistryKey currentUserRegistryKey = Registry.CurrentUser;

                string      subKey                 = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";

                RegistryKey registryKey            = currentUserRegistryKey.OpenSubKey(subKey);

 

                if(registryKey != null)

                {

                    currentUserRegistryKey.DeleteSubKeyTree(subKey);

                }

            }

            catch(Exception exception)

            {

                MessageBox.Show(exception.Message);

            }

        }

 

        #endregion

        #region 후킹 설정하기 - SetHook(processKeyboardHookDelegate)

 

        /// <summary>

        /// 후킹 설정하기

        /// </summary>

        /// <param name="processKeyboardHookDelegate">키보드 후킹 처리 대리자</param>

        /// <returns>처리 결과</returns>

        private static int SetHook(ProcessKeyboardHookDelegate processKeyboardHookDelegate)

        {

            using(Process process = Process.GetCurrentProcess())

            {

                using(ProcessModule processModule = process.MainModule)

                {

                    return SetWindowsHookEx(WH_KEYBOARD_LL, processKeyboardHookDelegate, GetModuleHandle(processModule.ModuleName), 0);

                }

            }

        }

 

        #endregion

        #region 스크린 세이버 중단하기 - StopScreenSaver()

 

        /// <summary>

        /// 스크린 세이버 중단하기

        /// </summary>

        private void StopScreenSaver()

        {

            if(this.canStopScreenSaver == true)

            {

                Cursor.Show();

 

                this.timer.Enabled = false;

 

                UnhookWindowsHookEx(_hookID);

 

                EnableTaskManager();

 

                Application.Exit();

            }

            else

            {

                Cursor.Show();

 

                InputPasswordForm popup = new InputPasswordForm();

 

                if(popup.ShowDialog() == DialogResult.OK)

                {

                    UnhookWindowsHookEx(_hookID);

 

                    EnableTaskManager();

 

                    Application.ExitThread();

                }

                else

                {

                    Cursor.Hide();

 

                    this.mouseX = 0;

                    this.mouseY = 0;

                }

            }

        }

 

        #endregion

    }

}

 

----------------------------------------------------------------------------------------------------

Posted by 사용자 icodebroker
TAG

댓글을 달아 주세요