.
C# Глазами хакера. Урок 2. Использование WinAPI
Автор megabax   
19.04.2014 г.
New Page 1

C# Глазами хакера. Урок 2. Использование WinAPI

Сегодня мы будем изучать WinAPI, в плане того, как их могут использовать хакеры. Напоминаю, что цель данного цикла изучить образ мысли хакеров что бы потом защититься от них. Я категорически не рекомендую использовать полученные в этих статьях знания для реальных хакерских атак, так как эти деяния являются уголовно наказуемыми.

И так, для начала рассмотрим несколько функций, WinAPI, при помощи которых можно манипулировать окнами. Начнем с функции FindWindow - найти окно. Но, для начала нам надо создать некую обертку, при помощи которой мы будем вызывать эти функции, WinAPI находиться у нас в user32.dll. Что бы получить эти функции, библиотеку необходимо импортировать при помощи команды DllImport, которая находиться в пространстве имен using System.Runtime.InteropServices. А вот и наша обертка, в которой мы предусмотрели пока только вызов одной функции FindWindow:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Runtime.InteropServices;

 

namespace WindowsFormsApplication1

{

    /// <summary>

    /// Класс обертка для WinAPI

    /// </summary>

    public static class WinAPI

    {

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

        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    }

}

Простейший пример вызова:

        private void btnStart_Click(object sender, EventArgs e)

        {

            IntPtr ptr = WinAPI.FindWindow(null, "Документ1 - Microsoft Word");

            MessageBox.Show(ptr.ToString());

        }

Если мы запустим эту программу и у нас открыто окно с заголовком "Документ1 - Microsoft Word", то программа выдаст еще дескриптор, иначе 0:

C# Глазами хакера. Урок 2. Использование WinAPI

Что можно сделать с этим дескриптором? Можно, например, получить дескриптор его дочернего объекта:

        private void btnStart_Click(object sender, EventArgs e)

        {

            IntPtr ptr = WinAPI.FindWindow(null, "Документ1 - Microsoft Word");

           

            //Если окно найдено, то отбращаемся к его дочерним объектам

            if (ptr.ToInt32() != 0)

            {

                IntPtr child = WinAPI.GetWindow(ptr, WinAPI.GetWindow_Cmd.GW_CHILD);

                MessageBox.Show(child.ToString());

            }

        }

Естественно, надо предварительно включить функцию GetWindow в нашу обертку WinAPI:

    /// <summary>

    /// Класс обертка для WinAPI

    /// </summary>

    public static class WinAPI

    {

        /// <summary>

        /// Найти окно

        /// </summary>

        /// <param name="lpClassName">Имя класса окна</param>

        /// <param name="lpWindowName">Имя окна</param>

        /// <returns></returns>

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

        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

 

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

        public static extern IntPtr GetWindow(IntPtr HWnd, GetWindow_Cmd cmd);

 

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

        public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, [Out] StringBuilder lParam);

 

        public enum GetWindow_Cmd : uint

        {

            GW_HWNDFIRST = 0,

            GW_HWNDLAST = 1,

            GW_HWNDNEXT = 2,

            GW_HWNDPREV = 3,

            GW_OWNER = 4,

            GW_CHILD = 5,

            GW_ENABLEDPOPUP = 6,

            WM_GETTEXT = 0x000D

        }

    }

Получили мы дескриптор, и что дальше? А дальше, например, можно получить текст окна:

        private void btnStart_Click(object sender, EventArgs e)

        {

            IntPtr ptr = WinAPI.FindWindow(null, "Документ1 - Microsoft Word");

           

            //Если окно найдено, то обращаемся к его дочерним объектам

            if (ptr.ToInt32() != 0)

            {

                IntPtr child = WinAPI.GetWindow(ptr, WinAPI.GetWindow_Cmd.GW_CHILD);

                StringBuilder title = new StringBuilder();

                WinAPI.SendMessage(child, Convert.ToInt32(WinAPI.GetWindow_Cmd.WM_GETTEXT), (IntPtr)20, title);

                MessageBox.Show(title.ToString());

            }

        }

Давайте проверим:

C# Глазами хакера. Урок 2. Использование WinAPI

Правда, этот текст, нам ни о чем не говорит, так что давайте попробуем другой пример:

        private void btnStart2_Click(object sender, EventArgs e)

        {

            IntPtr ptr = WinAPI.FindWindow(null, "Form1");

 

            //Если окно найдено, то обращаемся к его дочерним объектам

            if (ptr.ToInt32() != 0)

            {

                IntPtr[] child = new IntPtr[15];

                child[0] = WinAPI.GetWindow(ptr, WinAPI.GetWindow_Cmd.GW_CHILD);

                StringBuilder title = new StringBuilder();

                for (int i = 1; i <= 5; i++)

                {

                    child[i] = WinAPI.GetWindow(ptr, WinAPI.GetWindow_Cmd.GW_HWNDNEXT);

                    WinAPI.SendMessage(child[i-1], Convert.ToInt32(WinAPI.GetWindow_Cmd.WM_GETTEXT), (IntPtr)20, title);

                    lbWindows.Items.Add(title.ToString());

                }

              

            }

        }

Этот пример должен обратиться к своему же окну:

C# Глазами хакера. Урок 2. Использование WinAPI

Или попробуем вот такой текст:

        private void btnStart3_Click(object sender, EventArgs e)

        {

            IntPtr ptr = WinAPI.FindWindow(null, "Form1");

 

            //Если окно найдено, то отбращаемся к его дочерним объектам

            if (ptr.ToInt32() != 0)

            {

                IntPtr[] child = new IntPtr[15];

                child[0] = WinAPI.GetWindow(ptr, WinAPI.GetWindow_Cmd.GW_CHILD);

                StringBuilder title = new StringBuilder();

                for (int i = 1; i <= 5; i++)

                {

                    child[i] = WinAPI.GetWindow(child[i - 1], WinAPI.GetWindow_Cmd.GW_HWNDNEXT);

                    WinAPI.SendMessage(child[i - 1], Convert.ToInt32(WinAPI.GetWindow_Cmd.WM_GETTEXT), (IntPtr)20, title);

                    lbWindows.Items.Add(title.ToString());

                }

            }

        }

Тогда мы увидим вот такой результат:

C# Глазами хакера. Урок 2. Использование WinAPI

Таким образом, возможно найти окно по заголовку, обратиться к его дочерним элементам и даже посылать им сообщения Windows. Кроме сообщения GW_HWNDNEXT (получить текст) можно посылать и любые другие сообщения виндоуз, например, щелчки мышкой, перемещение указателя курсора, нажатия на клавишу клавиатуры и так далее.  Но об этом мы будем говорить в будущих уроках.

Последнее обновление ( 19.04.2014 г. )