Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #72, НОЯБРЬ 2006 г.

убийство часового

КРИС КАСПЕРСКИ, АКА МЫЩЪХ

Спецвыпуск: Хакер, номер #072, стр. 072-072-7


Листинг 5. Код функции PgCreateBlockChecksumSubContext, рассчитывающий контрольную сумму заданного блока

PPATCHGUARD_SUB_CONTEXT PgCreateBlockChecksumSubContext(

IN PPATCHGUARD_CONTEXT Context,

IN ULONG Unknown,

IN PVOID BlockAddress,

IN ULONG BlockSize,

IN ULONG SubContextSize,

OUT PBLOCK_CHECKSUM_STATE ChecksumState OPTIONAL)

{

ULONG64 Checksum = Context->RandomHashXorSeed;

ULONG Checksum32;

// Checksum 64-bit blocks

while (BlockSize >= sizeof(ULONG64))

{

Checksum ^= *(PULONG64)BaseAddress;

Checksum = RotateLeft(Checksum, Context->RandomHashRotateBits);

BlockSize -= sizeof(ULONG64);

BaseAddress += sizeof(ULONG64);

}

// Checksum aligned blocks

while (BlockSize-- > 0)

{

Checksum ^= *(PUCHAR)BaseAddress;

Checksum = RotateLeft(Checksum, Context->RandomHashRotateBits);

BaseAddress++;

}

Checksum32 = (ULONG)Checksum;

Checksum >>= 31;

do

{

Checksum32 ^= (ULONG)Checksum;

Checksum >>= 31;

} while (Checksum);

}

Как можно заметить, на выходе функции PgCreateBlockChecksumSubContext мы получаем 32-битный Checksum, записываемый в структуру BLOCK_CHECKSUM_STATE вместе с базовым адресом и размером контролируемого блока (кстати говоря, префикс «Pg» определенно означает Patch-Guard, позволяя нам легко и быстро отделять принадлежащие к Patch-Guard'у функции ото всех остальных функций ядра):

Листинг 6. Структура, хранящая 32-битный CRC вместе с другими данными

typedef struct BLOCK_CHECKSUM_STATE

{

ULONG Unknown;

ULONG64 BaseAddress;

ULONG BlockSize;

ULONG Checksum;

} BLOCK_CHECKSUM_STATE, *PBLOCK_CHECKSUM_STATE;

Информационная емкость 32-битной контрольной суммы составляет всего 4 байта, которые элементарно рассчитываются даже без всякого перебора. Подробнее об этом можно прочитать в моей статье «Как подделывают CRC16/32» (валяющейся на ftp://nezumi.org,ru), а так же в замечательном хакерском руководстве, ориентированном на астматиков и доходчиво рассказывающим, как вычисляется и подделывается CRC32 путем дописывания 4-х корректирующих байт в конец контролируемого блока: http://foff.astalavista.ms/tutorialz/Crc.htm, добротный перевод которой на русский лежит на: www.pilorama.r2.ru/library/pdf/crcrevrs.pdf.

Учитывая, что Microsoft в любой момент может пересмотреть свои позиции, расширив контрольную сумму до 8-байт (что на 64-разрядных процессорах очень легко сделать), нелишним будет заблаговременное ознакомление с базовыми принципами алгоритма CRC64, описание которого припрятано на: www.pdl.cmu.edu/mailinglists/ips/mail/msg02982.html.

Аналогичным образом осуществляется и модификация GDT/IDT – в них полно незадействованных полей и выкроить четыре байта не будет проблемой. А вот с SSDT дела обстоят похуже, поскольку Patch-Guard сверяет «рабочую» копию с ее «оригиналом», хранящимся внутри образа NTOSKRNL.EXE по адресу nt!KeServiceDescriptorTable. Кажется, что ситуация - финиш, но нет! Ведь мы уже умеем безболезненно модифицировать образ ядра, следовательно, нам ничего не будет стоить синхронно произвести изменения в обеих таблицах, и Patch-Guard снова ничего не заметит.

Назад на стр. 072-072-6  Содержание  Вперед на стр. 072-072-8