Ловля «шпионов» при помощи JAWS

Дата публикации:2005
Twitter Facebook Vkontakte

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

В последнее время одной из распространённых форм несанкционированного проникновения на компьютер стали рекламно-шпионские модули. Разумеется, что без специальных мер защиты и специализированных программ, предназначенных для борьбы с такими «шпионами», не обойтись и JAWS их не заменит. Тем не менее, средствами JAWS можно осуществить своего рода проверку, позволяющую отследить активность вредоносных программ. Именно такая проверка позволила в свое время «поймать» остатки рекламного шпиона smartadware (saw.exe), который находясь в памяти, не позволял удалить из реестра запись о его автозапуске. Кроме того, приводимый ниже исходный код скриптов может быть полезен для изучения работающих приложений.

В основе предлагаемого способа наблюдения за активностью приложений лежит тот факт, что подавляющее большинство программ, работающих в операционной системе Windows, создают хотя бы одно окно приложения. Для того чтобы пользователь не заметил работу некоторых программ, окно может быть скрытым. Кроме скрытых окон, для незрячих и слабовидящих могут быть недоступны окна тех приложений, с которыми некорректно работает JAWS. Стоит заметить, что некоторые программы предпринимают действия для того, чтобы их невозможно было отобразить в списке выполняющихся приложений и работающих процессов, однако работать в Windows без создания окна они не могут и тем самым оставляют возможность для отслеживания их активности. Исходя из этого, можно сказать, что в отличие от пользователя, который не всегда в курсе того, что происходит на его компьютере, операционная система всё-таки располагает информацией о выполняющихся приложениях. Поэтому логичным будет обратиться к средствам самой операционной системы для наблюдения за активностью программ. Язык сценариев JAWS предоставляет такую возможность посредством функции EnumChieldWindows (). В качестве первого параметра этой функции передается дескриптор окна, в котором будут перебраны все дочерние окна. Для того чтобы осуществить перебор окон самого верхнего уровня, значение первого параметра должно быть 0. В качестве второго параметра передается заключенное в двойные кавычки имя функции. Эта функция относится к классу callback-функций и будет выполняться для каждого из дочерних окон. Вызов callback-функции производится функцией EnumChieldWindows без участия программиста, при этом callback-функция получает в качестве параметра дескриптор очередного дочернего окна. Если callback-функция возвратит FALSE, то перебор окон будет прерван и функция EnumChieldWindows завершит свою работу. Если callback-функция возвратит TRUE, то перебор окон будет продолжен и функция EnumChieldWindows будет переходить к следующему дочернему окну, пока не обойдет все имеющиеся окна.

Однако простой перебор окон практически бесполезен - необходимо ещё получить информацию о приложении (процессе), которому это окно принадлежит. Для этой цели воспользуемся функциями:

Информация, собранная таким образом, сохраняется в глобальную переменную sBuf, а количество найденных окон - в переменной nNumChields. Эти глобальные переменные можно не помещать в самое начало файла default.jss, а объявить непосредственно перед скриптом. После того как перебор окон будет закончен, информация копируется в буфер обмена, откуда ее можно вставить в текстовый редактор и прочитать. Будьте готовы обнаружить на своем Рабочем столе не один десяток окон.

Перейдём к практике. Необходимо средствами Диспетчера скриптов (Script Manager) открыть файл default.jss (комбинация клавиш Control+Shift+D) и создать в этом файле приведенные ниже скрипт и функцию. Работоспособность этого исходного кода проверялась под JAWS 4.51 и 5.00.

globals
String sBuf,
Int nNumChields

Script DesktopChieldsInfo ()
Var
Handle hCurWin

let hCurWin = GetCurrentWindow ()
let sBuf = ""
let nNumChields = 0
; приступаем к перебору окон
EnumerateChildWindows (0, "DesktopChields")
; сохраняем информацию в буфер обмена
CopyToClipboard(sBuf)
Say("Обнаружено окон: " + IntToString (nNumChields) +". Данные помещены в буфер обмена.", OT_MESSAGE)
; возвращаемся в исходное окно
SetFocus (hCurWin)
EndScript

Int Function DesktopChields (handle hwnd)
Var
String str,
String sPath
SetFocus (hwnd)
let nNumChields = nNumChields + 1
let str =GetWindowName (hwnd)+ "\r\n"
let sPath = GetAppFilePath () 
let str = str +sPath +"\r\n"
; не все нижеследующие данные информативны, поэтому часть строк можно закомментировать
let str= str + "Comment: " + GetVersionInfoString (sPath, "Comment")+"\r\n"
let str = str + "Company: " + GetVersionInfoString (sPath, "CompanyName")+ "\r\n"
let str = str + "File Description: " + GetVersionInfoString (sPath, "FileDescription")+ "\r\n"
let str = str + "File Version: " + GetVersionInfoString (sPath, "FileVersion")+ "\r\n"
let str = str + "Internal Name: " + GetVersionInfoString (sPath, "InternalName")+ "\r\n"
let str = str + "Copyright: " + GetVersionInfoString (sPath, "LegalCopyright")+ "\r\n"
let str = str + "Trademark: " + GetVersionInfoString (sPath, "LegalTrademarks")+ "\r\n"
let str = str + "Original Filename: " + GetVersionInfoString (sPath, "OriginalFilename")+ "\r\n"
let str = str + "Private Build: " +GetVersionInfoString (sPath, "PrivateBuild")+ "\r\n"
let str = str + "Product Name: " + GetVersionInfoString (sPath, "ProductName")+ "\r\n"
let str = str + "Product Version: " + GetVersionInfoString (sPath, "ProductVersion")+ "\r\n"
let str = str + "Special Build: " + GetVersionInfoString (sPath, "SpecialBuild")+ "\r\n"
let str = str + "* -- *\r\n"
let sBuf = sBuf + str
return TRUE
EndFunction


Распространение материалов сайта означает, что распространитель принимает условия лицензионного соглашения.
Идея и реализация: © Владимир Довыденков и Анатолий Камынин,  2004-2017
Rambler's Top100