Программирование на C++ глазами хакера

         

Использование буфера обмена


Шутить можно над чем угодно, и буфер обмена тут не исключение. Вроде безобидная вещь, а может стать очень мощным инструментом в руках хакера. Главное — творческий подход.

Итак, буфер используется для того, чтобы пользователь мог переносить данные из программы в программу или копировать несколько раз одинаковый текст. Что ожидает пользователь? Вставляемые данные должны соответствовать скопированным. Вот тут мы можем сделать неожиданный ход.

В Windows есть функция и события, с помощью которых можно отслеживать состояние системного буфера. Это необходимо, чтобы кнопка Вставить из буфера обмена была доступна, только когда в буфере есть данные необходимого формата. Можно воспользоваться этими возможностями в своих целях.

Давайте создадим программу, которая будет следить за буфером, а при его изменении — портить содержимое. Создайте новое MFC-приложение (можно на основе диалогового окна) с именем ClipboardChange.

Добавим два новых события, которые должна будет обрабатывать наша программа, чтобы следить за состоянием буфера: ON_WM_CHANGECBCHAIN и ON_WM_DRAWCLIPBOARD. Для этого откройте файл ClipboardChangeDlg.cpp, найдите карту сообщений и добавьте туда названия необходимых нам событий:

BEGIN_MESSAGE_MAP(CClipboardChangeDlg, CDialog) ON_WM_CHANGECBCHAIN() ON_WM_DRAWCLIPBOARD() ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP END_MESSAGE_MAP()

Теперь откройте файл ClipboardChangeDlg.h и добавьте в него описания функций, которые будут вызываться в ответ на события буфера обмена. Их нужно объявить в разделе protected нашего класса следующим образом:

afx_msg void OnChangeCbChain(HWND hWndRemove, HWND hWndAfter);
afx_msg void OnDrawClipboard();

Нам также понадобится переменная типа HWND, в которой будет храниться указатель на окно-просмотрщик буфера. Назовите ее ClipboardViewer.

Снова вернитесь в файл ClipboardChangeDlg.cpp, где нужно добавить код этих функций. Но они не будут вызываться, пока мы не сделаем нашу программу наблюдателем за буфером обмена. Для этого в функции OnInitDialog добавьте строку:


CiipboardViewer = SetClipboardViewer();

Вот теперь можно перейти к рассмотрению двух функций, которые вызываются на события буфера. Код обеих функций приведен в листинге 3.10.



Листинг 3.10. Функции наблюдения за буфером
void CClipboardChangeDlg::OnChangeCbChain(HWND hWndRemove, HWND hWndAfter) { if ( ClipboardViewer== hWndRemove ) ClipboardViewer = hWndAfter;

if ( NULL != ClipboardViewer ) { ::SendMessage ( ClipboardViewer, WM_CHANGECBCHAIN, (WPARAM) hWndRemove, (LPARAM) hWndAfter ); }

CClipboardChangeDlg::OnChangeCbChain(hWndRemove, hWndAfter); }

void CClipboardChangeDlg::OnDrawClipboard() { if (!OpenClipboard()) { MessageBox("The clipboard is temporarily unavailable"); return; } if (!EmptyClipboard()) { CloseClipboard(); MessageBox("The clipboard cannot be emptied"); return; }

CString Text="You are hacked"; HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, Text.GetLength()+1);

if (!hGlobal) { CloseClipboard(); MessageBox(CString("Memory allocation error")); return; }

strcpy((char *)GlobalLock(hGlobal), Text); GlobalUnlock(hGlobal); if (!SetClipboardData(CF_TEXT, hGlobal)) { MessageBox("Error setting clipboard"); } CloseClipboard(); }

Самое интересное происходит в функции OnDrawClipboard, которая вызывается каждый раз, когда в буфер попадают новые данные. По этому событию надо очищать содержимое буфера обмена и помещать туда свои данные, т.е. пользователь не сможет воспользоваться операцией копирования.

Прежде чем работать с буфером, его необходимо открыть. Для этого используется функция OpenClipboard. Если открытие прошло успешно, то она возвращает TRUE.

После этого очищается буфер обмена с помощью функции EmptyClipboard. Если функция отработала успешно, то она возвращает TRUE, иначе буфер закрывается, и выводится сообщение об ошибке. Для закрытия используется функция CloseClipboard.

Теперь можно копировать свои данные в буфер обмена. Для этого нужно в глобальной области вьщелить память необходимого объема и скопировать туда нужный текст. Я поместил туда сообщение "You are hacked". После этого переносим данные из памяти в буфер с помощью функции SetClipboardData, у которой есть два параметра:



константа, определяющая тип данных — CF_TEXT, соответствует текстовым данным;

указатель на данные, которые должны быть помещены в буфер обмена.

После работы следует обязательно закрыть буфер с помощью функции CloseClipboard.

Вот таким простым способом, благодаря нашему воображению, абсолютно безобидный буфер обмена превратился в интересную шутку.

Попробуйте запустить программу и скопировать что-нибудь в буфер обмена. После вставки вместо скопированных данных вы увидите текст " You are hacked".

Примечание
Исходный код программы, описанной в этом разделе, вы можете найти на компакт - диске в каталоге \Demo\Chapter3\ClipboardChange.

Содержание раздела