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

ОГЛАВЛЕНИЕ

5. Как распаковать текст

Как уже отмечалось, s-code упакован алгоритмом LZNT1. Это вариант классического алгоритма LZ77 (самого первого из алгоритмов, придуманных Лемпелом и Зивом), отличающийся от своих многочисленных собратьев лишь способом кодировки выходного потока. (Кстати, алгоритм, примененный фирмой Microsoft в утилитах COMPRESS/EXPAND и в библиотеках LZEXPAND/ LZ32, реализует похожий, но чуть-чуть другой вариант LZ77).

Разобравшись в алгоритме (кстати, это очень интересно и поучительно!), можно написать собственный распаковщик, но мы в данной статье воспользуемся недокументированной функцией RtlDecompressBuffer(), живущей в библиотеке NTDLL.DLL из-под Windows NT/2000/XP.

Вот пример процедуры, распаковывающей исходный текст макроса и выводящей его на экран:

typedef UINT (WINAPI* RTLD)(ULONG, PVOID, ULONG, PVOID, ULONG, PULONG);

// Распаковка и показ макроса. (с) DrMad
view_src( char *StreamName, char *Buf, ULONG ch_pos)
{
 HMODULE h;                // Хэндл библиотеки NTDLL.DLL
 RTLD RtlDecompressBuffer; // Указатель на функцию
 ULONG ulen;               // Длина распакованного фрагмента
 int i;

 LoadLibrary("ntdll.dll");
 h = GetModuleHandle("ntdll.dll");
 RtlDecompressBuffer = (RTLD) GetProcAddress(h, "RtlDecompressBuffer");
 if (RtlDecompressBuffer)
  {
   RtlDecompressBuffer(0x2, SBuf, MAXBUF, &(Buf[ch_pos+1]), MAXBUF-ch_pos, &ulen);
   cout << "-------------------" << StreamName << "-------------------" << endl;
   i=0; while (SBuf[i]) cout << SBuf[i++];
  }
}

Недостаток метода: невозможность работы в Windows 95/98/ME.