Затронутые продукты: Microsoft Word 97, Microsoft Word 2000 SR-1. В Microsoft
Word XP этот баг пофиксен.
При обработке документа Microsoft Word, содержащего макросы, может произойти
переполнение буфера в стеке. Анализ недокументированной структуры макроса в
документе, осуществляемый процессом winword.exe, выполняется некорректно. Эта
структура в частности содержит полные внешнее и внутреннее имена макроса в
формате UNICODE. Общеизвестно, что первые два байта любой строки UNICODE
содержат ее длину. В коде winword.exe не содержится проверки на максимальный
размер этих строк, хотя в стеке под подобную строку winword.exe выделяет 512
байт (это соответствует 256 символам UNICODE). Ниже приводится часть кода из
процесса winword.exe, поясняющая все вышесказанное:
в регистре esi содержится число символов строки
3019460B lea eax, [esi+esi]
в регистре eax теперь содержится кол-во байт строки
3019460E add [ebp+var_4], eax
30194611 mov ecx, [ebp+var_4]
30194614 cmp ecx, [ebp+var_14]
проверяем, не вышли ли мы за пределы мини-потока
30194617 jg loc_30194B2B
3019461D push 0
3019461F push eax
в регистре eax кол-во байт копируемых в переполняемый буфер
30194620 lea eax, [ebp+var_44A]
в регистре eax содержится указатель на переполняемый буфер
30194626 jmp short loc_30194640
30194628 loc_30194628:
30194628 add [ebp+var_4], esi
3019462B mov eax, [ebp+var_4]
3019462E cmp eax, [ebp+var_14]
30194631 jg loc_30194B2B
30194637 push 0
30194639 push esi
3019463A lea eax, [ebp+var_133]
30194640 loc_30194640:
30194640 push eax
30194641 push [ebp+arg_24]
30194644 push [ebp+arg_0]
30194647 call sub_30193323
^^^^^^^^^^^^
Эта функция применяется очень и очень часто ;), но в данном случае осуществляет
копирование полного имени макроса из мини-потока в этот переполняемый буфер.
Следует отметить, что <копирование> подразумевает не только rep movsd или что-то
подобное, а более сложный процесс, обусловленный особой структурой документа.
Чтобы опробовать это на практике, необходимо создать документ. Далее, например,
через меню <Сервис> - <Макрос> - <Начать запись>, создать макрос, назвав его
spamcoder. Не забудьте указать, что макрос доступен именно для вашего документа,
а не для всех. Само собой сохранитесь, и закройте этот документ, чтобы открыть
его теперь в любом шестнадцатеричном редакторе (я пользуюсь BIEW Written by Nick
Kurshev, отличный редактор и что самое главное БЕСПЛАТНЫЙ). Попробуйте найти
нижеследующее:
000013C8: 10 FF FF 01 00 02 00 00 03 50 00 72 00 6F 00 6A ЪЪ P r o j
000013D8: 00 65 00 63 00 74 00 2E 00 4E 00 65 00 77 00 4D e c t . N e w M
000013E8: 00 61 00 63 00 72 00 6F 00 73 00 2E 00 73 00 70 a c r o s . s p
000013F8: 00 61 00 6D 00 63 00 6F 00 64 00 65 00 72 00 01 a m c o d e r
00001408: 00 11 01 00 0A 00 1B 00 50 00 52 00 4F 00 4A 00 P R O J
00001418: 45 00 43 00 54 00 2E 00 4E 00 45 00 57 00 4D 00 E C T . N E W M
00001428: 41 00 43 00 52 00 4F 00 53 00 2E 00 53 00 50 00 A C R O S . S P
00001438: 41 00 4D 00 43 00 4F 00 44 00 45 00 52 00 00 00 A M C O D E R
00001448: 40 00 80 01 00 06 00 00 00 06 00 00 00 8C 24 AD @ Ђ Њ$
Обратите внимание на первую строку:
10 FF FF 01 00 02 00 25 02 50 00 72 00 6F 00 6A
^^^^^^
Подчеркнутое и есть количество символов в строке, в данном случае 0225h(549). В
вашем случае оно будет значительно меньше, исправьте его на что-нибудь более
подходящее. Но помните - размер буфера 512 байт, поэтому прописывать значение
меньшее 256 не имеет смысла. Размер кадра стека - 1100 байт, поэтому если
хочется <взять> управление в свои руки, следует указать значение не меньшее 549.
Хотя я из этого <пользы> вытянуть не смог, возможно, это получится у вас, тогда
напишите об этом: мне.
Ранее, я указывал на тот факт, что функция, осуществляющая переполнение буфера,
применяется довольно часто, поэтому не стоит зацикливаться на названии статьи.
Почти наверняка ;-) переполнение происходит и при других обстоятельствах.
(c) SpAmC0der //PRiZM 1998-2003