Страница 4 из 5
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. |