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:
Что можно сделать с этим дескриптором?
Можно, например, получить дескриптор его дочернего объекта:
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());
}
} |
Давайте проверим:
Правда, этот текст, нам ни о чем не говорит, так что давайте
попробуем другой пример:
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());
}
}
} |
Этот пример должен обратиться к своему же окну:
Или попробуем вот такой текст:
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());
}
}
} |
Тогда мы увидим вот такой результат:
Таким образом, возможно найти окно по заголовку, обратиться к его дочерним
элементам и даже посылать им сообщения Windows. Кроме
сообщения GW_HWNDNEXT (получить текст) можно посылать и любые другие сообщения
виндоуз, например, щелчки мышкой, перемещение указателя курсора, нажатия на
клавишу клавиатуры и так далее. Но об этом мы будем говорить в будущих
уроках.
|