Прямой доступ к макросам в документах MS WORD - Как найти упакованный исходник внутри потока

ОГЛАВЛЕНИЕ

4. Как найти упакованный исходник внутри потока

Упакованные исходные тексты макросов хранятся в потоках с сигнатурой 01 16h 01. В начале потока расположен заголовок, после него лежит блок p-code, а конец потока занимает s-code макроса. Довольно часто (примерно в 80% случаев) в заголовке по смещению 0Dh располагается 2-байтовый адрес в потоке для s-code. Но в 20% случаев в этом поле заголовка находится значение -1 (FF FF), и это означает, что s-code придется искать по-другому.

Есть "правильный" метод поиска, но он довольно зануден, поэтому я предлагаю более простой подход. Он основан на том, что s-code лежит во второй половине потока и организован в виде нескольких фрагментов упакованных данных (так называемых "чунков" - chunks). Первый из них имеет в начале сигнатуру, которую можно найти по маске 01 yz Bx, где xyz представляет собой 12-битовую длину чунка минус 3. 

Например, макрос вируса Macro.Word97.TNT имеет по смещению 15В9h три байта 01 63h B6h. Это означает начало упакованного чунка длиной 663h+3=666h байтов.

Вот пример процедуры, находящей внутри потока начало упакованного s-code:

// Поиск упакованного макроса в потоке. (с) DrMad
ULONG search_chunk( char *Buf, ULONG streamlen)
{
 ULONG ch_pos; // Позиция чунка внутри потока

 if ((Buf[0]==1)&&(Buf[1]==0x16)&&(Buf[2]==1))
  {
   ch_pos = streamlen/2;
   while ((ch_pos<(streamlen-3)) && ((Buf[ch_pos]!=1)||
                           ((Buf[ch_pos+2]&0xF0)!=0xB0))) ch_pos++;
   if (ch_pos < (streamlen-3)) return ch_pos;
  }
  return 0;
}