Использование буфера обмена
Шутить можно над чем угодно, и буфер обмена тут не исключение. Вроде безобидная вещь, а может стать очень мощным инструментом в руках хакера. Главное — творческий подход.
Итак, буфер используется для того, чтобы пользователь мог переносить данные из программы в программу или копировать несколько раз одинаковый текст. Что ожидает пользователь? Вставляемые данные должны соответствовать скопированным. Вот тут мы можем сделать неожиданный ход.
В 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. Функции наблюдения за буфером |
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. |
![]() |
![]() |