информационная безопасность
без паники и всерьез
 подробно о проекте
Rambler's Top100За кого нас держат?Все любят медСетевые кракеры и правда о деле Левина
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Бэкдор в xz/liblzma, предназначенный... 
 Три миллиона электронных замков... 
 Doom на газонокосилках 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / библиотека / программирование
БИБЛИОТЕКА
вход в библиотеку
книги
безопасность
программирование
криптография
internals
www
телефония
underground
беллетристика
разное
обзор: избранное
конкурс
рейтинг статей
обсуждение




Подписка:
BuqTraq: Обзор
RSN
БСК
Закон есть закон




Защита, использующая хасп-ключ
Chingachguk /HI-TECH
Опубликовано: dl, 18.02.04 19:34

Что собираемся делать ?

  Объект исследования: программа, использующая для защиты hasp-key

  Инструменты: Soft-Ice (под '98), hiew

  Цель: изучение win32-программ, обладающих защитой в нулевом кольце и hasp

  Документация/источники: статья "Програмная эмуляция HASP ключей By exefoliator, 2000", утилита haspgrab

  Примечание: это есть поверхностный анализ защиты такого типа, приношу свои извинения знатокам hasp'ов за возможно "наивные" рассуждения :)

Состав защиты

  Программа включает в себя следующие компоненты: рабочий модуль prog.exe, возможно частично зашифрованный, два VxD драйвера: haspbig.vxd, весом полмегабайта, статический (загружаемый системой при старте) и hasplit.vxd, небольшой и динамический (загружаемый программой prog.exe при запуске). В порт компьютера LPT воткнут hasp-ключ.

Первая попытка. Soft-Ice

  Первое, что я попробовал сделать - это посмотреть, как защита работает с hasp. Воспользовавшись командой Soft-Ice мониторинга портов:

  bpio 0378
  bpio 0379
  ...

  я ожидал получить break по доступу к портам ввода-вывода и сделать какие-нибудь предварительные выводы. Запускаем программу... нет. Нет никаких break'ов.

  Почему ? Проверяю работу ice на тестовых (своих) программах и обнаруживаю: 0) обращение из дос-задачи перехватывается; 1) из vxd-драйвера не перехватывается. В случае 1 не помогают sti и т.п.

  Получается, ice не перехватывает работу с портами с нулевого кольца (в 98 есть только два уровня: 0-ой, в котором находятся все vxd-драйвера и 3-ый: win32-приложения. Не считая, конечно, V86 для дос-программ и BIOS).

Вторая попытка. Сервисы перехвата VMM

  Обнаружив в списке функций главного VxD системы функции перехвата обращений к портам типа:

  VMMCall Enable_Global_Trapping
  VMMCall Disable_Global_Trapping
  ...

  пытаюсь применить их для вышеуказанной задачи. Эффект тот же, что и в ice: перехватываются обращения все, кроме как из нулевого кольца.

Третья попытка. Битовая карта ввода-вывода

  При организации работы в защищенном режиме есть такая вещь: если программист использует задачи (task), то в описателе задачи (на который необходимо выполнить переключение командами jmp или call) содержится так называемая битовая карта запрещения ввода-вывода. Если текущий CPL задачи не соответсвует IOPL и в этой карте установлен бит запрещения доступа к порту, то процессор генерирует исключение. Эта удобная вещь используется дос-менеджерами типа emm386 для предоставления сервиса trapping'а (возможность установить ловушку и эмулировать работу устройства). Например, программа PCDOSEMU.COM ("PC3000AT HASP/ISA board emulator") использует эту возможность для эмуляции второго hdd.

  Однако поверхностное вскрытие win показало, что она совсем не использует механизм переключения задач (бит NT - nested task - в регистре EFLAGS сброшен). К тому же не совсем ясно, как настроить CPL (текущий уровень привелегий задачи) для VxD, ибо по умолчанию он у него наивысший.

Четвертая попытка. Регистры DRx

  Однако никаких принципиальных ограничений написать свой собственный мониторинг портов аналогично ice не существует. Для этого я воспользовался интерфейсом процессора для отладки программ - регистрами отладки DRx.

  Для настройки отладки необходимо загрузить в регистр DR7 флаги-описатели типа ловушки: по доступу на чтение/запись/исполнение, размер точки (байт/слово/dword) и т.п. (далее будет подробнее про форматы DRx). Адреса портов ввода-вывода (или памяти) необходимо записать в регистры DR0-DR3. При выполнении условия отладочного прерывания процессор выполнит исключение #1 - debug interrupt. Таким образом можно иметь 4 точки останова по доступу к портам - как раз то, что нужно. Минусом является невозможность работать бок о бок с sice в этом случае: он и такой перехватчик не смогут разделить общий ресурс - int 01h.

  Сказано - сделано. Написав динамический vxd-драйвер, обладающий подобным перехватом портов:

.586p
; Необходимые инклюды для сборки VxD
include vmm.inc 
include vwin32.inc
...
;
; Обрабатываем только сообщение w32_DeviceIoControl
;
Begin_control_dispatch SER
	Control_Dispatch w32_DeviceIoControl, OnDeviceIoControl
End_control_dispatch SER
...
;
; Секция данных
;
include log.inc
VxD_LOCKED_DATA_SEG
  Port equ 0378h
ttrap  struc
  offs1  dw  0   ; [0]
  sel    dw  28h ; [2]
  rsrv   db  0   ; [4]
  attr_  db  8fh ; [5]
  offs_h dw  0   ; [6]
ttrap  ends
trap        ttrap <>
old_trap_01 ttrap <> ; Старый описатель ловушки #01
old_trap_UD ttrap <>
tidt_descr struc
  idt_size dw ? ; размер idt
  lin_addr dd ? ; линейный адрес начала idt
tidt_descr ends
idt_descr tidt_descr <>
old_trapUD    dd 0 ; Адрес старого обработчика исключения #06
old_Jump_Addr dd 0 ; Адрес команд перехода на инсталлятор #06
; Буфер лога
LogPtr        dd 0 ; Указатель лог-буфера-его размер
LogPackets    db (MAX_LOG_RECORDS * sizeof(tLogPacket)) dup (?)
;
; Инсталлятор обработчика исключения #1
;
  mov  dword ptr LogPtr,0                                                    
  mov  dword ptr LastLogPtr,0                                                

; Установка обработчика #1 - debug

; Создание дескриптора ловушки в idt
  mov  eax,offset32 TrapPort
  mov  trap.offs1,ax
  shr  eax,16
  mov  trap.offs_h,ax
  
; Загрузка в idt
; Получить текущий idt_base
  sidt fword ptr idt_descr
  mov  ebx,dword ptr idt_descr.lin_addr
; Получить начало описателя #1 - debug
  add  ebx,8

; Установить ловушку #1, сохранив старую

  mov  eax,dword ptr trap
  xchg [ebx],eax
  mov  dword ptr old_trap_01,eax
  mov  eax,dword ptr trap+4
  xchg [ebx+4],eax
  mov  dword ptr old_trap_01+4,eax

; Set trap to ports i/o
; Enable DE flag
  mov  eax,cr4
  or   eax,01000b
  mov  cr4,eax

; Ports set
  xor  ebx,ebx
  mov  bx,Port
  mov  dr0,ebx
  add  ebx,2
  mov  dr1,ebx
  add  ebx,2
  mov  dr2,ebx
  add  ebx,2
  mov  dr3,ebx

; Включение ловушек
  ;        FEDCBA9876543210FEDCBA9876543210
  mov  eax,01100110011001100010011111111111b
  mov  dr7,eax
 ...
;
; Обработчик исключения #1
;
TrapPort proc
  push ebp
  mov  ebp,esp
  push eax 
  pushad
  push ds
  push es
  pushfd
  mov  ax,ss
  mov  ds,ax

; Адрес возврата EIP
  mov  ecx,[ebp+4]
; Адрес возврата CS->ES
  mov  es,word ptr [ebp+8]

  ...

  popfd
  pop  es
  pop  ds
  popad
  pop  eax
  pop  ebp
  iretd
TrapPort endp

  Немного пояснений по вышеприведенному коду. Загруженному драйверу VxD система (VMM) посылает различные сообщения, которые он по своему желанию может обработать. Например, при нажатии кнопки "Пуск" всем VxD придет сообщение THREAD_INIT (~ создана новая нить и драйвер может что-то встроить в нее). Наш VxD обрабатывает из всего набора сообщений (~ 15 шт) одно: w32_DeviceIoControl. Это сообщение будет послано при загрузке с подфункцией DIOC_Open:

BeginProc OnDeviceIoControl
  assume esi:ptr DIOCParams                                                  
.if [esi].dwIoControlCode==DIOC_Open ; Контрольное сообщение ?!              
  ...

  Я имею в виду, что мы через esi добираемся до параметра при сообщении w32_DeviceIoControl. Такое сообщение система будет посылать нам всякий раз, когда win32-приложение будет вызвать нас через апи DeviceIoControl, но тогда параметр будет тем, который уже это приложение нам передаст (второй аргумент):

  invoke DeviceIoControl,hVxD,1,addr InBuffer,sizeof InBuffer,NULL,NULL,NULL,NULL

  Инсталляция заключается в установке обработчика исключения #1 и инициализации отладочных регистров DRx. Для установки обработчика необходимо встроить дескриптор собственной ловушки в idt - interrupt table. Эта таблица состоит из элементов типа ttrap (выше) (не только - могут быть hardware прерывания, но нам это сейчас не важно). Адрес таблицы idt можно получит так: выгружаем текущий дескриптор idt командой sidt, из него получаем начальный адрес таблицы idt. Далее индексируемся на описатель 1 в ней и меняем его так, чтобы управление передавалось на нашу подпрограмму TrapPort. Загрузка регистра DR7 требует некоторого пояснения (лучше прочесть более детально в книге Зубкова С.В.):

; Включение ловушек
  ;        FEDCBA9876543210FEDCBA9876543210
  mov  eax,01100110011001100010011111111111b
  mov  dr7,eax

  Биты 31-30: 01 - размер точки останова: 2 байта
  Биты 29-28: 10 - тип точки: доступ к портам i/o
  Биты 27-16: аналогичны предидущим - другие точки останова тоже на i/o
  Биты 15-14: 00
  бит 13: бит GD - включает режим, в котором любое обращение к 
                   любому отладочному регистру, даже из кольца защиты 0,
                   вызывает исключение #DB
  биты 12 - 10: 001
  бит 9: бит GE - если этот бит 0, точка останова по обращению к
                   данным может не сработать или сработать на несколько
                   команд позже, так что лучше всегда сохранять его равным 1
  бит 7: бит G3 - точка останова 3 включена
  ...

  Теперь обработчик исключения #1 может получить управление и, например, записать в лог обмен приложения с портами ввода-вывода.

  Тестирование на собственных "кошках": OK

  Тестирование на защищенном приложении: нет перехвата !

  Но почему ?! Почему я могу перехватить работу с портами из другого VxD, но не из защищенного ? Смотрим внимательнее на инициализацию DR7: никто не может помешать приложению (VxD защиты обладает ВСЕМИ правами) записать в DR7 ноль и никаких прерываний больше не будет. Достаем дизассемблер - hiew (точнее, hiew32) и открываем в нем hasplit.vxd:

; Если бит не 0, мусорим dr7 нулем
xx4C: 50             push        eax
xx4D: 2BC0           sub         eax,eax
xx4F: 0F23F8         mov         dr7,eax
xx52: 58             pop         eax

  Ага, нам мешают ловить прерывания :) Но отсюда сразу же вытекает следующая проверка:

  Найти все такие команды и забить nop'ами: bad result

  Так выяснилось, что hasplit контролирует собственную модификацию (видимо, динамические проверки crc и т.п.). Пока получается замкнутый овал: нельзя трейсить обращения к портам, пока нам мешает маленький драйвер, но сам его трогать нельзя дабы убрать сброс отладки.

DeviceIOControl

  Однако, тут я сделал паузу, но не скушал "твикс", а обратил внимание на то, что я пока был подобен солдату, бездумно кидающемуся на пулеметную точку вместо того, чтобы обойти ее сбоку и спокойно сделать head-shoot.

  Зачем пытаться имитировать отклик порта, если можно перехватить "сеанс связи" приложения (prog.exe) с драйвером (драйверами). Единственный способ общения приложения с загруженным им драйвером VxD - это апи DeviceIOControl и больше ничего. Ну если не извращаться и не патчить всякий раз статические данные VxD и запускать его несколько раз подряд.

  Перехват апи - это легко и приятно. По крайней мере, в сравнении с драйверами. На тему перехвата апи не буду распространяться, отошлю Вас к замечательной статье 90210 "техника перхвата апи". Скажу лишь, что я использовал метод, открытый Vecna (вызов первой экспортируемой kernel32.dll функции VxDCall0).

  Таким образом мне удалось перехватить обмен через DeviceIOControl с драйверами:

MsgDeviceIOControlHook:
hVxD:00000030 
SecParam: 9C402450 
InBufferLen: 00000006 
nOutBufferSize: 00000006 
lpOverlapped: 00000000
InBuffer: 00 00 00 00 00 00
OutBufbefore: 00 00 00 00 00 00
VxDAnswerEAX: 00000001
(BytesReturned: 00000000):
Out buffer changed !
VxDAnswerMsg: 00 00 FA FA 19 03


MsgDeviceIOControlHook:
hVxD:00000034 
SecParam: 00000003 
InBufferLen: 00000000 
nOutBufferSize: 000015E8 
lpOverlapped: 00000000
InBuffer:
OutBufbefore: 
C7 85 8F 17 00 00 00 00 00 00 8D 95 F1 18 00 00 8D BD 73 17
00 00 B8 07 00 00 40 66 8C CB 8B D2 B9 6F 01 00 00 66 8C CE
8B FF FE EF 00 01 02 03 04 05 8D 95 F1 18 00 00 8D BD 74 17
00 00 B8 07 00 00 40 66 8C CB 8B D2 B9 6F 01 00 00 66 8C CE
8B FF FE EF 00 01 02 03 04 05 8D 95 F1 18 00 00 8D BD 75 17
00 00 B8 07 00 00 40 66 8C CB 8B D2 B9 6F 01 00 00 66 8C CE
8B FF FE EF 00 01 02 03 04 05 8D 95 F1 18 00 00 8D BD 76 17
00 00 B8 07 00 00 40 66 8C CB 8B D2 B9 6F 01 00 00 66 8C CE
8B FF FE EF 00 01 02 03 04 05 8B 8D 73 17 00 00 8B 9D 8F 17
00 00 8B 9C 1D 77 17 00 00 02 D9 C1 CB 08 C1 C9 08 02 D9 C1
CB 08 C1 C9 08 02 D9 C1 CB 08 C1 C9 08 02 D9 C1 CB 08 C1 C9
08 03 DD FF E3 57 56 52 51 53 50 33 C9 33 FF 66 8B CB 66 83
F9 00 75 04 66 B9 E8 03 66 8B F0 FC 66 33 FF 66 47 02 FB 80
C3 05 22 C3 32 D0 E2 F3 8A CA 58 5B 59 5A 5E 5F 57 56 52 51
53 50 33 C9 33 FF 66 8B C9 66 83 F9 00 75 04 66 B9 E8 03 66
8B F3 FC 66 33 FF 66 47 02 FB 80 C3 05 22 C3 32 D0 E2 F3 8A
C2 58 5B 59 5A 5E 5F 8D 95 46 23 00 00 8D BD 46 23 00 00 B8
06 00 00 40 66 8C CB 8B D2 B9 9F 01 00 00 66 8C CE 8B FF FE
EF 00 01 02 03 04 05 21 9A AA AA AE CC 62 16 72 F3 7C 4B AA
AA 31 9F 8A AA AA 45 54 AA BA 8A 9A EA FA 92 F2 52 DB AA AA
EA 72 F3 AC 0B AA AA 72 71 9D DB AA AA 21 DA AA AA AE CC 62
16 12 87 31 74 BA AA AA CC 62 46 12 55 45 54 AA BA 8A 9A EA
FA 72 F3 AC 0B AA AA 72 71 ED DB AA AA 21 DA AA AA AE CC 62
16 12 87 31 74 BA AA AA CC 62 46 12 55 45 54 AA BA 8A 9A EA
FA 72 F3 AC 0B AA AA 72 71 FD DB AA AA 21 DA AA AA AE CC 62
16 12 87 31 74 BA AA AA CC 62 46 12 55 45 54 AA BA 8A 9A EA
FA 72 F3 AC 0B AA AA 72 71 CD DB AA AA 21 DA AA AA AE CC 62
16 12 87 31 74 BA AA AA CC 62 46 12 55 45 54 AA BA 8A 9A EA
FA 12 72 9D DB AA AA 12 73 52 DB AA AA 12 63 7B DD DB AA AA
8A 37 B6 16 2A B6 36 2A 8A 37 B6 16 2A B6 36 2A 8A 37 B6 16
2A B6 36 2A 8A 37 B6 16 2A B6 36 2A 9A 77 55 94 DF CF 8F BF
9F AF 99 36 99 55 CC 12 16 CC 92 35 AA FD EA CC 31 24 9A CC
12 A5 65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02
06 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC 12 36
CC 92 35 AA FD EA CC 31 24 9A CC 12 95 65 CC 99 55 CC DE 8A
15 A2 96 FA 88 96 89 A7 84 95 02 86 2F 1F 3F 0F 4F 5F DF CF
8F BF 9F AF 99 36 99 55 CC 12 26 CC 92 35 AA FD EA CC 31 24
9A CC 12 B5 65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84
95 02 07 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC
12 16 CC 92 35 AA FD EA CC 31 24 9A CC 12 A5 65 CC 99 55 CC
DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 04 2F 1F 3F 0F 4F 5F
72 F3 A6 A8 AA AA 72 71 A6 A8 AA AA 21 CA AA AA AE CC 62 16
12 87 31 C2 8A AA AA CC 62 46 12 55 45 54 AA BA 8A 9A EA FA
21 9A AA AA AE CC 62 16 72 F3 A6 A8 AA AA 31 C2 8A AA AA 45
54 AA BA 8A 9A EA FA 92 F2 52 DB AA AA EA 72 F3 7E 6B AA AA
72 71 9D DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 A8 8A AA
AA CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3 7E 6B AA AA
72 71 ED DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 A8 8A AA
AA CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3 7E 6B AA AA
72 71 FD DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 A8 8A AA
AA CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3 7E 6B AA AA
72 71 CD DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 A8 8A AA
AA CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 12 72 9D DB AA AA
12 73 52 DB AA AA 12 63 7B DD DB AA AA 8A 37 B6 16 2A B6 36
2A 8A 37 B6 16 2A B6 36 2A 8A 37 B6 16 2A B6 36 2A 8A 37 B6
16 2A B6 36 2A 9A 77 55 94 DF CF 8F BF 9F AF 99 36 99 55 CC
12 16 CC 92 35 AA FD EA CC 31 24 9A CC 12 A5 65 CC 99 55 CC
DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 06 2F 1F 3F 0F 4F 5F
DF CF 8F BF 9F AF 99 36 99 55 CC 12 36 CC 92 35 AA FD EA CC
31 24 9A CC 12 95 65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89
A7 84 95 02 86 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99 36 99
55 CC 12 26 CC 92 35 AA FD EA CC 31 24 9A CC 12 B5 65 CC 99
55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 07 2F 1F 3F 0F
4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC 12 16 CC 92 35 AA FD
EA CC 31 24 9A CC 12 A5 65 CC 99 55 CC DE 8A 15 A2 96 FA 88
96 89 A7 84 95 02 04 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99
36 99 55 CC 12 36 CC 92 35 AA FD EA CC 31 24 9A CC 12 95 65
CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 84 2F 1F
3F 0F 4F 5F 72 F3 F4 E8 AA AA 72 71 F4 E8 AA AA 21 CA AA AA
AE CC 62 16 12 87 31 21 3A AA AA CC 62 46 12 55 45 54 AA BA
8A 9A EA FA 21 9A AA AA AE CC 62 16 72 F3 CE 98 AA AA 31 53
BA AA AA 45 54 AA BA 8A 9A EA FA 92 F2 52 DB AA AA EA 72 F3
7C 4B AA AA 72 71 9D DB AA AA 21 DA AA AA AE CC 62 16 12 87
31 9F 8A AA AA CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3
7C 4B AA AA 72 71 ED DB AA AA 21 DA AA AA AE CC 62 16 12 87
31 9F 8A AA AA CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3
7C 4B AA AA 72 71 FD DB AA AA 21 DA AA AA AE CC 62 16 12 87
31 9F 8A AA AA CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3
7C 4B AA AA 72 71 CD DB AA AA 21 DA AA AA AE CC 62 16 12 87
31 9F 8A AA AA CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 12 72
9D DB AA AA 12 73 52 DB AA AA 12 63 7B DD DB AA AA 8A 37 B6
16 2A B6 36 2A 8A 37 B6 16 2A B6 36 2A 8A 37 B6 16 2A B6 36
2A 8A 37 B6 16 2A B6 36 2A 9A 77 55 94 DF CF 8F BF 9F AF 99
36 99 55 CC 12 16 CC 92 35 AA FD EA CC 31 24 9A CC 12 A5 65
CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 06 2F 1F
3F 0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC 12 36 CC 92 35
AA FD EA CC 31 24 9A CC 12 95 65 CC 99 55 CC DE 8A 15 A2 96
FA 88 96 89 A7 84 95 02 86 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F
AF 99 36 99 55 CC 12 26 CC 92 35 AA FD EA CC 31 24 9A CC 12
B5 65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 07
2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC 12 16 CC
92 35 AA FD EA CC 31 24 9A CC 12 A5 65 CC 99 55 CC DE 8A 15
A2 96 FA 88 96 89 A7 84 95 02 04 2F 1F 3F 0F 4F 5F DF CF 8F
BF 9F AF 99 36 99 55 CC 12 36 CC 92 35 AA FD EA CC 31 24 9A
CC 12 95 65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95
02 84 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC 12
26 CC 92 35 AA FD EA CC 31 24 9A CC 12 B5 65 CC 99 55 CC DE
8A 15 A2 96 FA 88 96 89 A7 84 95 02 05 2F 1F 3F 0F 4F 5F 72
F3 AC 0B AA AA 72 71 AC 0B AA AA 21 CA AA AA AE CC 62 16 12
87 31 74 BA AA AA CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 92
F2 52 DB AA AA EA 21 9A AA AA AE CC 62 16 72 F3 AC 0B AA AA
31 74 BA AA AA 45 54 AA BA 8A 9A EA FA 72 F3 A6 A8 AA AA 72
71 9D DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 C2 8A AA AA
CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3 A6 A8 AA AA 72
71 ED DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 C2 8A AA AA
CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3 A6 A8 AA AA 72
71 FD DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 C2 8A AA AA
CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3 A6 A8 AA AA 72
71 CD DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 C2 8A AA AA
CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 12 72 9D DB AA AA 12
73 52 DB AA AA 12 63 7B DD DB AA AA 8A 37 B6 16 2A B6 36 2A
8A 37 B6 16 2A B6 36 2A 8A 37 B6 16 2A B6 36 2A 8A 37 B6 16
2A B6 36 2A 9A 77 55 94 DF CF 8F BF 9F AF 99 36 99 55 CC 12
16 CC 92 35 AA FD EA CC 31 24 9A CC 12 A5 65 CC 99 55 CC DE
8A 15 A2 96 FA 88 96 89 A7 84 95 02 06 2F 1F 3F 0F 4F 5F DF
CF 8F BF 9F AF 99 36 99 55 CC 12 36 CC 92 35 AA FD EA CC 31
24 9A CC 12 95 65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7
84 95 02 86 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55
CC 12 26 CC 92 35 AA FD EA CC 31 24 9A CC 12 B5 65 CC 99 55
CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 07 2F 1F 3F 0F 4F
5F DF CF 8F BF 9F AF 99 36 99 55 CC 12 16 CC 92 35 AA FD EA
CC 31 24 9A CC 12 A5 65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96
89 A7 84 95 02 04 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99 36
99 55 CC 12 36 CC 92 35 AA FD EA CC 31 24 9A CC 12 95 65 CC
99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 84 2F 1F 3F
0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC 12 26 CC 92 35 AA
FD EA CC 31 24 9A CC 12 B5 65 CC 99 55 CC DE 8A 15 A2 96 FA
88 96 89 A7 84 95 02 05 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF
99 36 99 55 CC 12 16 CC 92 35 AA FD EA CC 31 24 9A CC 12 B5
65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 84 2F
1F 3F 0F 4F 5F 72 F3 7E 6B AA AA 72 71 7E 6B AA AA 21 CA AA
AA AE CC 62 16 12 87 31 A8 8A AA AA CC 62 46 12 55 45 54 AA
BA 8A 9A EA FA 92 F2 52 DB AA AA EA 72 F3 CE 98 AA AA 72 71
9D DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 53 BA AA AA CC
62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3 CE 98 AA AA 72 71
ED DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 53 BA AA AA CC
62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3 CE 98 AA AA 72 71
FD DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 53 BA AA AA CC
62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3 CE 98 AA AA 72 71
CD DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 53 BA AA AA CC
62 46 12 55 45 54 AA BA 8A 9A EA FA 12 72 9D DB AA AA 12 73
52 DB AA AA 12 63 7B DD DB AA AA 8A 37 B6 16 2A B6 36 2A 8A
37 B6 16 2A B6 36 2A 8A 37 B6 16 2A B6 36 2A 8A 37 B6 16 2A
B6 36 2A 9A 77 55 94 DF CF 8F BF 9F AF 99 36 99 55 CC 12 16
CC 92 35 AA FD EA CC 31 24 9A CC 12 A5 65 CC 99 55 CC DE 8A
15 A2 96 FA 88 96 89 A7 84 95 02 06 2F 1F 3F 0F 4F 5F DF CF
8F BF 9F AF 99 36 99 55 CC 12 36 CC 92 35 AA FD EA CC 31 24
9A CC 12 95 65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84
95 02 86 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC
12 26 CC 92 35 AA FD EA CC 31 24 9A CC 12 B5 65 CC 99 55 CC
DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 07 2F 1F 3F 0F 4F 5F
72 F3 7C 4B AA AA 72 71 7C 4B AA AA 21 CA AA AA AE CC 62 16
12 87 31 9F 8A AA AA CC 62 46 12 55 45 54 AA BA 8A 9A EA FA
21 BA AA AA AE 45 54 AA BA 8A 9A EA FA 21 9A AA AA AE CC 62
16 72 F3 7E 6B AA AA 31 A8 8A AA AA 45 54 AA BA 8A 9A EA FA
BC FF CF DF CC 12 F1 EF 8A AA AA CC 12 71 8F 8A AA AA CC 12
72 B5 BA AA AA CC 12 73 B7 BA AA AA 02 35 CC 12 F3 8A 8A AA
AA CC 12 72 AA 8A AA AA CC B2 71 B5 BA AA AA A5 AA 5A E2 97
FA AA AA D6 F2 7F 6A AA AA BA AA AA AA D6 F2 BC 6A AA AA BA
AA AA AA AF CF 72 F1 77 BA AA AA 12 CA 32 F2 FC 6A AA AA 4F
2F D6 F2 3C 6A AA AA 2E AA AA AA D6 F2 7C 6A AA AA 28 AA AA
AA 21 85 DB AA AA CC 32 F2 BD 6A AA AA 22 71 9D 6A AA AA CC
12 F2 64 BA AA AA 32 F2 FD 6A AA AA 22 73 3D 6A AA AA 32 72
7D 6A AA AA 32 F3 B2 6A AA AA 32 71 F2 6A AA AA 32 F1 32 6A
AA AA 12 F2 50 6A AA AA 32 F2 73 6A AA AA CC D6 F2 90 6A AA
AA EA AA CC 92 71 B5 BA AA AA 28 8D 5F CC 92 71 B5 BA AA AA
A9 CD 8F CC 92 71 B5 BA AA AA F9 ED 2E CC 92 71 B5 BA AA AA
E9 ED 49 CC 92 71 B5 BA AA AA FF ED E9 CC 92 71 B5 BA AA AA
AC ED 08 CC 92 71 B5 BA AA AA EC ED A8 CC 92 71 B5 BA AA AA
2D ED CB CC 92 71 B5 BA AA AA 3D ED 6A CC 92 71 B5 BA AA AA
7D ED 8A 14 9A 25 14 BA 35 9D 8A 14 AA 92 7D 57 0A ED 1A 92
7D 57 1A ED FA 34 E2 9A AA AA CC 12 73 B5 BA AA AA A2 15 99
ED 8E A2 15 89 5A E2 67 AA AA AA A2 15 F9 ED E9 A2 15 E9 5A
E2 46 AA AA AA A2 15 AC ED C8 A2 15 FF ED B8 A2 15 6E ED 6B
A2 15 7E 5A E2 C1 AA AA AA A2 15 29 ED 4A A2 15 D9 5A E2 20
AA AA AA 34 E6 BA AA AA 12 F2 32 6A AA AA 32 F2 33 6A AA AA
12 F2 73 6A AA AA 12 A5 51 0E 2A AA AA 9A 75 CC 92 71 B5 BA
AA AA 28 8D 5F CC 92 71 B5 BA AA AA A9 CD 8F CC 92 71 B5 BA
AA AA F9 ED 2E CC 92 71 B5 BA AA AA E9 ED 49 CC 92 71 B5 BA
AA AA FF ED E9 CC 92 71 B5 BA AA AA AC ED 08 CC 92 71 B5 BA
AA AA EC ED A8 CC 92 71 B5 BA AA AA 2D ED CB CC 92 71 B5 BA
AA AA 3D ED 6A CC 92 71 B5 BA AA AA 7D ED 8A 14 9A 25 14 BA
35 9D 8A 14 AA 92 D6 8A 12 72 33 6A AA AA 21 8A AA AA AA CC
D5 B4 12 26 95 E0 34 C2 AA AA AA 12 F2 32 6A AA AA 32 F2 33
6A AA AA 51 0E 2A AA AA 9A 75 CC 92 71 B5 BA AA AA 28 8D 5F
CC 92 71 B5 BA AA AA A9 CD 8F CC 92 71 B5 BA AA AA F9 ED 2E
CC 92 71 B5 BA AA AA E9 ED 49 CC 92 71 B5 BA AA AA FF ED E9
CC 92 71 B5 BA AA AA AC ED 08 CC 92 71 B5 BA AA AA EC ED A8
CC 92 71 B5 BA AA AA 2D ED CB CC 92 71 B5 BA AA AA 3D ED 6A
CC 92 71 B5 BA AA AA 7D ED 8A 14 9A 25 14 BA 35 9D 8A 14 AA
34 21 AA AA AA CC 92 71 B5 BA AA AA 28 8D 5F CC 92 71 B5 BA
AA AA A9 CD 8F CC 92 71 B5 BA AA AA F9 ED 2E CC 92 71 B5 BA
AA AA E9 ED 49 CC 92 71 B5 BA AA AA FF ED E9 CC 92 71 B5 BA
AA AA AC ED 08 CC 92 71 B5 BA AA AA EC ED A8 CC 92 71 B5 BA
AA AA 2D ED CB CC 92 71 B5 BA AA AA 3D ED 6A CC 92 71 B5 BA
AA AA 7D ED 8A 14 9A 25 14 BA 35 9D 8A 14 AA CC 12 73 EF 8A
AA AA B2 94 55 55 AA AA 9E CC 55 F1 35 8A AA AA 21 8A AA AA
AA CC D5 94 CC 32 F2 35 8A AA AA CC 52 F2 35 8A AA AA 14 7B
D6 F2 33 6A AA AA AA AA AA AA D6 F2 73 6A AA AA AA AA AA AA
CC D6 F2 B0 6A AA AA AA AA D6 F2 DF 55 55 55 2E AA AA AA CC
92 71 B5 BA AA AA 28 8D 5F CC 92 71 B5 BA AA AA A9 CD 8F CC
92 71 B5 BA AA AA F9 ED 2E CC 92 71 B5 BA AA AA E9 ED 49 CC
92 71 B5 BA AA AA FF ED E9 CC 92 71 B5 BA AA AA AC ED 08 CC
92 71 B5 BA AA AA EC ED A8 CC 92 71 B5 BA AA AA 2D ED CB CC
92 71 B5 BA AA AA 3D ED 6A CC 92 71 B5 BA AA AA 7D ED 8A 14
9A 25 14 BA 35 5A 82 17 AA AA AA 72 71 7F 6A AA AA AC 92 D6
EB 72 F1 56 38 AA AA 32 F1 94 BA AA AA 21 EA AA AA AE CC 62
17 12 D7 31 28 AA AA AA CC 62 46 12 71 94 BA AA AA 45 54 AA
BA 8A 9A EA FA DF CF 8F BF 9F AF 99 36 99 55 CC 12 26 CC 92
35 AA FD EA CC 31 24 9A CC 12 95 65 CC 99 55 CC DE 8A 15 A2
96 FA 88 96 89 A7 84 95 02 06 2F 1F 3F 0F 4F 5F DF CF 8F BF
9F AF 99 36 99 55 CC 12 26 CC 92 35 AA FD EA CC 31 24 9A CC
12 B5 65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02
86 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC 12 36
CC 92 35 AA FD EA CC 31 24 9A CC 12 A5 65 CC 99 55 CC DE 8A
15 A2 96 FA 88 96 89 A7 84 95 02 07 2F 1F 3F 0F 4F 5F BC 72
F2 7F 6A AA AA 34 6F BA AA AA CC 12 73 B5 BA AA AA A2 15 99
ED 99 A2 15 89 ED 48 A2 15 F9 ED 38 A2 15 E9 ED E8 A2 15 AC
ED 5B A2 15 FF ED 0B D1 BA A2 15 6E ED 9B A2 15 7E ED 4A D1
AA A2 15 29 ED DA A2 15 D9 ED 8A 14 6B 12 F3 73 6A AA AA 99
36 CC 12 72 EF 8A AA AA A2 55 BA ED 8A 9A 36 55 F3 5A 55 55
55 72 71 7F 6A AA AA AC 72 F3 7F 6A AA AA 31 2E AA AA AA 55
F3 5A 55 55 55 92 D6 EB 72 F1 CB 18 AA AA 32 F1 94 BA AA AA
21 EA AA AA AE CC 62 17 12 D7 31 28 AA AA AA CC 62 46 12 71
94 BA AA AA 45 54 AA BA 8A 9A EA FA DF CF 8F BF 9F AF 99 36
99 55 CC 12 26 CC 92 35 AA FD EA CC 31 24 9A CC 12 95 65 CC
99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 06 2F 1F 3F
0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC 12 26 CC 92 35 AA
FD EA CC 31 24 9A CC 12 B5 65 CC 99 55 CC DE 8A 15 A2 96 FA
88 96 89 A7 84 95 02 86 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF
99 36 99 55 CC 12 36 CC 92 35 AA FD EA CC 31 24 9A CC 12 A5
65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 07 2F
1F 3F 0F 4F 5F BC 72 F2 7F 6A AA AA 14 2B FF 55 F3 D7 45 55
55 7F D6 F2 DF 55 55 55 EA AA AA AA 72 F2 F0 6A AA AA 32 FE
17 FF 55 FF E5 7F CC 12 73 B5 BA AA AA A2 15 99 ED 99 A2 15
89 ED 48 A2 15 F9 ED 38 A2 15 E9 ED E8 A2 15 AC ED 5B A2 15
FF ED 0B D1 BA A2 15 6E ED 9B A2 15 7E ED 4A D1 AA A2 15 29
ED DA A2 15 D9 ED 8A 14 08 12 F2 50 6A AA AA 32 F2 73 6A AA
AA 99 A6 12 F3 73 6A AA AA 99 36 CC 12 72 EF 8A AA AA A2 55
BA ED 8A 9A 36 55 F3 1A 55 55 55 CC D6 F2 2E 2A AA AA AA AA
92 25 AA ED 7A 12 26 99 A6 99 17 99 87 34 D7 8A AA AA 92 7D
57 0A ED 1A 92 7D 57 1A ED FA 34 FE BA AA AA CC 92 71 B5 BA
AA AA 28 8D 5F CC 92 71 B5 BA AA AA A9 CD 8F CC 92 71 B5 BA
AA AA F9 ED 2E CC 92 71 B5 BA AA AA E9 ED 49 CC 92 71 B5 BA
AA AA FF ED E9 CC 92 71 B5 BA AA AA AC ED 08 CC 92 71 B5 BA
AA AA EC ED A8 CC 92 71 B5 BA AA AA 2D ED CB CC 92 71 B5 BA
AA AA 3D ED 6A CC 92 71 B5 BA AA AA 7D ED 8A 14 9A 25 14 BA
35 5A 82 F7 AA AA AA 72 71 7F 6A AA AA AC 92 D6 EB 72 F1 9B
78 AA AA 32 F1 94 BA AA AA 21 CA AA AA AE CC 62 17 12 D7 31
28 AA AA AA CC 62 46 12 71 94 BA AA AA 45 54 AA BA 8A 9A EA
FA DF CF 8F BF 9F AF 99 36 99 55 CC 12 26 CC 92 35 AA FD EA
CC 31 24 9A CC 12 95 65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96
89 A7 84 95 02 06 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99 36
99 55 CC 12 26 CC 92 35 AA FD EA CC 31 24 9A CC 12 B5 65 CC
99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 86 2F 1F 3F
0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC 12 36 CC 92 35 AA
FD EA CC 31 24 9A CC 12 A5 65 CC 99 55 CC DE 8A 15 A2 96 FA
88 96 89 A7 84 95 02 07 2F 1F 3F 0F 4F 5F BC 34 B4 AA AA AA
72 71 7F 6A AA AA AC 92 D6 EB 72 F1 24 78 AA AA 32 F1 94 BA
AA AA 21 CA AA AA AE CC 62 17 12 D7 31 28 AA AA AA CC 62 46
12 71 94 BA AA AA 45 54 AA BA 8A 9A EA FA DF CF 8F BF 9F AF
99 36 99 55 CC 12 26 CC 92 35 AA FD EA CC 31 24 9A CC 12 95
65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 06 2F
1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC 12 26 CC 92
35 AA FD EA CC 31 24 9A CC 12 B5 65 CC 99 55 CC DE 8A 15 A2
96 FA 88 96 89 A7 84 95 02 86 2F 1F 3F 0F 4F 5F DF CF 8F BF
9F AF 99 36 99 55 CC 12 36 CC 92 35 AA FD EA CC 31 24 9A CC
12 A5 65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02
07 2F 1F 3F 0F 4F 5F 72 F3 7F 6A AA AA 31 2E AA AA AA 55 F3
1A 55 55 55 BC 92 7D 57 0A ED 2A 92 7D 57 1A ED 8A 14 0D CC
12 73 B5 BA AA AA 14 BD A2 15 89 ED BB A2 15 E9 ED 6A A2 15
7E ED DA A2 15 D9 ED 8A 14 1F 51 0E 2A AA AA 9A 75 CC 12 73
EF 8A AA AA B2 94 55 55 AA AA 9E CC 55 F1 35 8A AA AA 21 8A
AA AA AA CC D5 94 CC 32 F2 35 8A AA AA CC 52 F2 35 8A AA AA
12 71 50 6A AA AA 41 0E 2A AA AA 9A F5 92 C6 8A CC 12 72 EF
8A AA AA B2 B4 55 55 AA AA 21 8A AA AA AA CC D5 B4 12 26 95
E0 12 F2 F2 6A AA AA 12 73 32 6A AA AA 12 72 72 6A AA AA 12
F3 B3 6A AA AA 5F 4F 7F 60 B8 02 00 00 40 FE EF 00 01 02 03
04 05 B8 03 00 00 40 66 8C CB 8D 95 E5 24 00 00 B9 B8 09 00
00 FE EF 00 01 02 03 04 05 8D 95 F1 18 00 00 B9 E8 15 00 00
FF 95 0B FF FF FF 61 C3
VxDAnswerEAX: 00000001
(BytesReturned: 00000000):
VxDAnswerMsg: 
C7 85 8F 17 00 00 00 00 00 00 8D 95 F1 18 00 00 8D BD 73 17
00 00 B8 07 00 00 40 66 8C CB 8B D2 B9 6F 01 00 00 66 8C CE
8B FF FE EF 00 01 02 03 04 05 8D 95 F1 18 00 00 8D BD 74 17
00 00 B8 07 00 00 40 66 8C CB 8B D2 B9 6F 01 00 00 66 8C CE
8B FF FE EF 00 01 02 03 04 05 8D 95 F1 18 00 00 8D BD 75 17
00 00 B8 07 00 00 40 66 8C CB 8B D2 B9 6F 01 00 00 66 8C CE
8B FF FE EF 00 01 02 03 04 05 8D 95 F1 18 00 00 8D BD 76 17
00 00 B8 07 00 00 40 66 8C CB 8B D2 B9 6F 01 00 00 66 8C CE
8B FF FE EF 00 01 02 03 04 05 8B 8D 73 17 00 00 8B 9D 8F 17
00 00 8B 9C 1D 77 17 00 00 02 D9 C1 CB 08 C1 C9 08 02 D9 C1
CB 08 C1 C9 08 02 D9 C1 CB 08 C1 C9 08 02 D9 C1 CB 08 C1 C9
08 03 DD FF E3 57 56 52 51 53 50 33 C9 33 FF 66 8B CB 66 83
F9 00 75 04 66 B9 E8 03 66 8B F0 FC 66 33 FF 66 47 02 FB 80
C3 05 22 C3 32 D0 E2 F3 8A CA 58 5B 59 5A 5E 5F 57 56 52 51
53 50 33 C9 33 FF 66 8B C9 66 83 F9 00 75 04 66 B9 E8 03 66
8B F3 FC 66 33 FF 66 47 02 FB 80 C3 05 22 C3 32 D0 E2 F3 8A
C2 58 5B 59 5A 5E 5F 8D 95 46 23 00 00 8D BD 46 23 00 00 B8
06 00 00 40 66 8C CB 8B D2 B9 9F 01 00 00 66 8C CE 8B FF FE
EF 00 01 02 03 04 05 21 9A AA AA AE CC 62 16 72 F3 7C 4B AA
AA 31 9F 8A AA AA 45 54 AA BA 8A 9A EA FA 92 F2 52 DB AA AA
EA 72 F3 AC 0B AA AA 72 71 9D DB AA AA 21 DA AA AA AE CC 62
16 12 87 31 74 BA AA AA CC 62 46 12 55 45 54 AA BA 8A 9A EA
FA 72 F3 AC 0B AA AA 72 71 ED DB AA AA 21 DA AA AA AE CC 62
16 12 87 31 74 BA AA AA CC 62 46 12 55 45 54 AA BA 8A 9A EA
FA 72 F3 AC 0B AA AA 72 71 FD DB AA AA 21 DA AA AA AE CC 62
16 12 87 31 74 BA AA AA CC 62 46 12 55 45 54 AA BA 8A 9A EA
FA 72 F3 AC 0B AA AA 72 71 CD DB AA AA 21 DA AA AA AE CC 62
16 12 87 31 74 BA AA AA CC 62 46 12 55 45 54 AA BA 8A 9A EA
FA 12 72 9D DB AA AA 12 73 52 DB AA AA 12 63 7B DD DB AA AA
8A 37 B6 16 2A B6 36 2A 8A 37 B6 16 2A B6 36 2A 8A 37 B6 16
2A B6 36 2A 8A 37 B6 16 2A B6 36 2A 9A 77 55 94 DF CF 8F BF
9F AF 99 36 99 55 CC 12 16 CC 92 35 AA FD EA CC 31 24 9A CC
12 A5 65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02
06 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC 12 36
CC 92 35 AA FD EA CC 31 24 9A CC 12 95 65 CC 99 55 CC DE 8A
15 A2 96 FA 88 96 89 A7 84 95 02 86 2F 1F 3F 0F 4F 5F DF CF
8F BF 9F AF 99 36 99 55 CC 12 26 CC 92 35 AA FD EA CC 31 24
9A CC 12 B5 65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84
95 02 07 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC
12 16 CC 92 35 AA FD EA CC 31 24 9A CC 12 A5 65 CC 99 55 CC
DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 04 2F 1F 3F 0F 4F 5F
72 F3 A6 A8 AA AA 72 71 A6 A8 AA AA 21 CA AA AA AE CC 62 16
12 87 31 C2 8A AA AA CC 62 46 12 55 45 54 AA BA 8A 9A EA FA
21 9A AA AA AE CC 62 16 72 F3 A6 A8 AA AA 31 C2 8A AA AA 45
54 AA BA 8A 9A EA FA 92 F2 52 DB AA AA EA 72 F3 7E 6B AA AA
72 71 9D DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 A8 8A AA
AA CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3 7E 6B AA AA
72 71 ED DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 A8 8A AA
AA CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3 7E 6B AA AA
72 71 FD DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 A8 8A AA
AA CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3 7E 6B AA AA
72 71 CD DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 A8 8A AA
AA CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 12 72 9D DB AA AA
12 73 52 DB AA AA 12 63 7B DD DB AA AA 8A 37 B6 16 2A B6 36
2A 8A 37 B6 16 2A B6 36 2A 8A 37 B6 16 2A B6 36 2A 8A 37 B6
16 2A B6 36 2A 9A 77 55 94 DF CF 8F BF 9F AF 99 36 99 55 CC
12 16 CC 92 35 AA FD EA CC 31 24 9A CC 12 A5 65 CC 99 55 CC
DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 06 2F 1F 3F 0F 4F 5F
DF CF 8F BF 9F AF 99 36 99 55 CC 12 36 CC 92 35 AA FD EA CC
31 24 9A CC 12 95 65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89
A7 84 95 02 86 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99 36 99
55 CC 12 26 CC 92 35 AA FD EA CC 31 24 9A CC 12 B5 65 CC 99
55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 07 2F 1F 3F 0F
4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC 12 16 CC 92 35 AA FD
EA CC 31 24 9A CC 12 A5 65 CC 99 55 CC DE 8A 15 A2 96 FA 88
96 89 A7 84 95 02 04 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99
36 99 55 CC 12 36 CC 92 35 AA FD EA CC 31 24 9A CC 12 95 65
CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 84 2F 1F
3F 0F 4F 5F 72 F3 F4 E8 AA AA 72 71 F4 E8 AA AA 21 CA AA AA
AE CC 62 16 12 87 31 21 3A AA AA CC 62 46 12 55 45 54 AA BA
8A 9A EA FA 21 9A AA AA AE CC 62 16 72 F3 CE 98 AA AA 31 53
BA AA AA 45 54 AA BA 8A 9A EA FA 92 F2 52 DB AA AA EA 72 F3
7C 4B AA AA 72 71 9D DB AA AA 21 DA AA AA AE CC 62 16 12 87
31 9F 8A AA AA CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3
7C 4B AA AA 72 71 ED DB AA AA 21 DA AA AA AE CC 62 16 12 87
31 9F 8A AA AA CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3
7C 4B AA AA 72 71 FD DB AA AA 21 DA AA AA AE CC 62 16 12 87
31 9F 8A AA AA CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3
7C 4B AA AA 72 71 CD DB AA AA 21 DA AA AA AE CC 62 16 12 87
31 9F 8A AA AA CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 12 72
9D DB AA AA 12 73 52 DB AA AA 12 63 7B DD DB AA AA 8A 37 B6
16 2A B6 36 2A 8A 37 B6 16 2A B6 36 2A 8A 37 B6 16 2A B6 36
2A 8A 37 B6 16 2A B6 36 2A 9A 77 55 94 DF CF 8F BF 9F AF 99
36 99 55 CC 12 16 CC 92 35 AA FD EA CC 31 24 9A CC 12 A5 65
CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 06 2F 1F
3F 0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC 12 36 CC 92 35
AA FD EA CC 31 24 9A CC 12 95 65 CC 99 55 CC DE 8A 15 A2 96
FA 88 96 89 A7 84 95 02 86 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F
AF 99 36 99 55 CC 12 26 CC 92 35 AA FD EA CC 31 24 9A CC 12
B5 65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 07
2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC 12 16 CC
92 35 AA FD EA CC 31 24 9A CC 12 A5 65 CC 99 55 CC DE 8A 15
A2 96 FA 88 96 89 A7 84 95 02 04 2F 1F 3F 0F 4F 5F DF CF 8F
BF 9F AF 99 36 99 55 CC 12 36 CC 92 35 AA FD EA CC 31 24 9A
CC 12 95 65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95
02 84 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC 12
26 CC 92 35 AA FD EA CC 31 24 9A CC 12 B5 65 CC 99 55 CC DE
8A 15 A2 96 FA 88 96 89 A7 84 95 02 05 2F 1F 3F 0F 4F 5F 72
F3 AC 0B AA AA 72 71 AC 0B AA AA 21 CA AA AA AE CC 62 16 12
87 31 74 BA AA AA CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 92
F2 52 DB AA AA EA 21 9A AA AA AE CC 62 16 72 F3 AC 0B AA AA
31 74 BA AA AA 45 54 AA BA 8A 9A EA FA 72 F3 A6 A8 AA AA 72
71 9D DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 C2 8A AA AA
CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3 A6 A8 AA AA 72
71 ED DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 C2 8A AA AA
CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3 A6 A8 AA AA 72
71 FD DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 C2 8A AA AA
CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3 A6 A8 AA AA 72
71 CD DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 C2 8A AA AA
CC 62 46 12 55 45 54 AA BA 8A 9A EA FA 12 72 9D DB AA AA 12
73 52 DB AA AA 12 63 7B DD DB AA AA 8A 37 B6 16 2A B6 36 2A
8A 37 B6 16 2A B6 36 2A 8A 37 B6 16 2A B6 36 2A 8A 37 B6 16
2A B6 36 2A 9A 77 55 94 DF CF 8F BF 9F AF 99 36 99 55 CC 12
16 CC 92 35 AA FD EA CC 31 24 9A CC 12 A5 65 CC 99 55 CC DE
8A 15 A2 96 FA 88 96 89 A7 84 95 02 06 2F 1F 3F 0F 4F 5F DF
CF 8F BF 9F AF 99 36 99 55 CC 12 36 CC 92 35 AA FD EA CC 31
24 9A CC 12 95 65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7
84 95 02 86 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55
CC 12 26 CC 92 35 AA FD EA CC 31 24 9A CC 12 B5 65 CC 99 55
CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 07 2F 1F 3F 0F 4F
5F DF CF 8F BF 9F AF 99 36 99 55 CC 12 16 CC 92 35 AA FD EA
CC 31 24 9A CC 12 A5 65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96
89 A7 84 95 02 04 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99 36
99 55 CC 12 36 CC 92 35 AA FD EA CC 31 24 9A CC 12 95 65 CC
99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 84 2F 1F 3F
0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC 12 26 CC 92 35 AA
FD EA CC 31 24 9A CC 12 B5 65 CC 99 55 CC DE 8A 15 A2 96 FA
88 96 89 A7 84 95 02 05 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF
99 36 99 55 CC 12 16 CC 92 35 AA FD EA CC 31 24 9A CC 12 B5
65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 84 2F
1F 3F 0F 4F 5F 72 F3 7E 6B AA AA 72 71 7E 6B AA AA 21 CA AA
AA AE CC 62 16 12 87 31 A8 8A AA AA CC 62 46 12 55 45 54 AA
BA 8A 9A EA FA 92 F2 52 DB AA AA EA 72 F3 CE 98 AA AA 72 71
9D DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 53 BA AA AA CC
62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3 CE 98 AA AA 72 71
ED DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 53 BA AA AA CC
62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3 CE 98 AA AA 72 71
FD DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 53 BA AA AA CC
62 46 12 55 45 54 AA BA 8A 9A EA FA 72 F3 CE 98 AA AA 72 71
CD DB AA AA 21 DA AA AA AE CC 62 16 12 87 31 53 BA AA AA CC
62 46 12 55 45 54 AA BA 8A 9A EA FA 12 72 9D DB AA AA 12 73
52 DB AA AA 12 63 7B DD DB AA AA 8A 37 B6 16 2A B6 36 2A 8A
37 B6 16 2A B6 36 2A 8A 37 B6 16 2A B6 36 2A 8A 37 B6 16 2A
B6 36 2A 9A 77 55 94 DF CF 8F BF 9F AF 99 36 99 55 CC 12 16
CC 92 35 AA FD EA CC 31 24 9A CC 12 A5 65 CC 99 55 CC DE 8A
15 A2 96 FA 88 96 89 A7 84 95 02 06 2F 1F 3F 0F 4F 5F DF CF
8F BF 9F AF 99 36 99 55 CC 12 36 CC 92 35 AA FD EA CC 31 24
9A CC 12 95 65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84
95 02 86 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC
12 26 CC 92 35 AA FD EA CC 31 24 9A CC 12 B5 65 CC 99 55 CC
DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 07 2F 1F 3F 0F 4F 5F
72 F3 7C 4B AA AA 72 71 7C 4B AA AA 21 CA AA AA AE CC 62 16
12 87 31 9F 8A AA AA CC 62 46 12 55 45 54 AA BA 8A 9A EA FA
21 BA AA AA AE 45 54 AA BA 8A 9A EA FA 21 9A AA AA AE CC 62
16 72 F3 7E 6B AA AA 31 A8 8A AA AA 45 54 AA BA 8A 9A EA FA
BC FF CF DF CC 12 F1 EF 8A AA AA CC 12 71 8F 8A AA AA CC 12
72 B5 BA AA AA CC 12 73 B7 BA AA AA 02 35 CC 12 F3 8A 8A AA
AA CC 12 72 AA 8A AA AA CC B2 71 B5 BA AA AA A5 AA 5A E2 97
FA AA AA D6 F2 7F 6A AA AA BA AA AA AA D6 F2 BC 6A AA AA BA
AA AA AA AF CF 72 F1 77 BA AA AA 12 CA 32 F2 FC 6A AA AA 4F
2F D6 F2 3C 6A AA AA 2E AA AA AA D6 F2 7C 6A AA AA 28 AA AA
AA 21 85 DB AA AA CC 32 F2 BD 6A AA AA 22 71 9D 6A AA AA CC
12 F2 64 BA AA AA 32 F2 FD 6A AA AA 22 73 3D 6A AA AA 32 72
7D 6A AA AA 32 F3 B2 6A AA AA 32 71 F2 6A AA AA 32 F1 32 6A
AA AA 12 F2 50 6A AA AA 32 F2 73 6A AA AA CC D6 F2 90 6A AA
AA EA AA CC 92 71 B5 BA AA AA 28 8D 5F CC 92 71 B5 BA AA AA
A9 CD 8F CC 92 71 B5 BA AA AA F9 ED 2E CC 92 71 B5 BA AA AA
E9 ED 49 CC 92 71 B5 BA AA AA FF ED E9 CC 92 71 B5 BA AA AA
AC ED 08 CC 92 71 B5 BA AA AA EC ED A8 CC 92 71 B5 BA AA AA
2D ED CB CC 92 71 B5 BA AA AA 3D ED 6A CC 92 71 B5 BA AA AA
7D ED 8A 14 9A 25 14 BA 35 9D 8A 14 AA 92 7D 57 0A ED 1A 92
7D 57 1A ED FA 34 E2 9A AA AA CC 12 73 B5 BA AA AA A2 15 99
ED 8E A2 15 89 5A E2 67 AA AA AA A2 15 F9 ED E9 A2 15 E9 5A
E2 46 AA AA AA A2 15 AC ED C8 A2 15 FF ED B8 A2 15 6E ED 6B
A2 15 7E 5A E2 C1 AA AA AA A2 15 29 ED 4A A2 15 D9 5A E2 20
AA AA AA 34 E6 BA AA AA 12 F2 32 6A AA AA 32 F2 33 6A AA AA
12 F2 73 6A AA AA 12 A5 51 0E 2A AA AA 9A 75 CC 92 71 B5 BA
AA AA 28 8D 5F CC 92 71 B5 BA AA AA A9 CD 8F CC 92 71 B5 BA
AA AA F9 ED 2E CC 92 71 B5 BA AA AA E9 ED 49 CC 92 71 B5 BA
AA AA FF ED E9 CC 92 71 B5 BA AA AA AC ED 08 CC 92 71 B5 BA
AA AA EC ED A8 CC 92 71 B5 BA AA AA 2D ED CB CC 92 71 B5 BA
AA AA 3D ED 6A CC 92 71 B5 BA AA AA 7D ED 8A 14 9A 25 14 BA
35 9D 8A 14 AA 92 D6 8A 12 72 33 6A AA AA 21 8A AA AA AA CC
D5 B4 12 26 95 E0 34 C2 AA AA AA 12 F2 32 6A AA AA 32 F2 33
6A AA AA 51 0E 2A AA AA 9A 75 CC 92 71 B5 BA AA AA 28 8D 5F
CC 92 71 B5 BA AA AA A9 CD 8F CC 92 71 B5 BA AA AA F9 ED 2E
CC 92 71 B5 BA AA AA E9 ED 49 CC 92 71 B5 BA AA AA FF ED E9
CC 92 71 B5 BA AA AA AC ED 08 CC 92 71 B5 BA AA AA EC ED A8
CC 92 71 B5 BA AA AA 2D ED CB CC 92 71 B5 BA AA AA 3D ED 6A
CC 92 71 B5 BA AA AA 7D ED 8A 14 9A 25 14 BA 35 9D 8A 14 AA
34 21 AA AA AA CC 92 71 B5 BA AA AA 28 8D 5F CC 92 71 B5 BA
AA AA A9 CD 8F CC 92 71 B5 BA AA AA F9 ED 2E CC 92 71 B5 BA
AA AA E9 ED 49 CC 92 71 B5 BA AA AA FF ED E9 CC 92 71 B5 BA
AA AA AC ED 08 CC 92 71 B5 BA AA AA EC ED A8 CC 92 71 B5 BA
AA AA 2D ED CB CC 92 71 B5 BA AA AA 3D ED 6A CC 92 71 B5 BA
AA AA 7D ED 8A 14 9A 25 14 BA 35 9D 8A 14 AA CC 12 73 EF 8A
AA AA B2 94 55 55 AA AA 9E CC 55 F1 35 8A AA AA 21 8A AA AA
AA CC D5 94 CC 32 F2 35 8A AA AA CC 52 F2 35 8A AA AA 14 7B
D6 F2 33 6A AA AA AA AA AA AA D6 F2 73 6A AA AA AA AA AA AA
CC D6 F2 B0 6A AA AA AA AA D6 F2 DF 55 55 55 2E AA AA AA CC
92 71 B5 BA AA AA 28 8D 5F CC 92 71 B5 BA AA AA A9 CD 8F CC
92 71 B5 BA AA AA F9 ED 2E CC 92 71 B5 BA AA AA E9 ED 49 CC
92 71 B5 BA AA AA FF ED E9 CC 92 71 B5 BA AA AA AC ED 08 CC
92 71 B5 BA AA AA EC ED A8 CC 92 71 B5 BA AA AA 2D ED CB CC
92 71 B5 BA AA AA 3D ED 6A CC 92 71 B5 BA AA AA 7D ED 8A 14
9A 25 14 BA 35 5A 82 17 AA AA AA 72 71 7F 6A AA AA AC 92 D6
EB 72 F1 56 38 AA AA 32 F1 94 BA AA AA 21 EA AA AA AE CC 62
17 12 D7 31 28 AA AA AA CC 62 46 12 71 94 BA AA AA 45 54 AA
BA 8A 9A EA FA DF CF 8F BF 9F AF 99 36 99 55 CC 12 26 CC 92
35 AA FD EA CC 31 24 9A CC 12 95 65 CC 99 55 CC DE 8A 15 A2
96 FA 88 96 89 A7 84 95 02 06 2F 1F 3F 0F 4F 5F DF CF 8F BF
9F AF 99 36 99 55 CC 12 26 CC 92 35 AA FD EA CC 31 24 9A CC
12 B5 65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02
86 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC 12 36
CC 92 35 AA FD EA CC 31 24 9A CC 12 A5 65 CC 99 55 CC DE 8A
15 A2 96 FA 88 96 89 A7 84 95 02 07 2F 1F 3F 0F 4F 5F BC 72
F2 7F 6A AA AA 34 6F BA AA AA CC 12 73 B5 BA AA AA A2 15 99
ED 99 A2 15 89 ED 48 A2 15 F9 ED 38 A2 15 E9 ED E8 A2 15 AC
ED 5B A2 15 FF ED 0B D1 BA A2 15 6E ED 9B A2 15 7E ED 4A D1
AA A2 15 29 ED DA A2 15 D9 ED 8A 14 6B 12 F3 73 6A AA AA 99
36 CC 12 72 EF 8A AA AA A2 55 BA ED 8A 9A 36 55 F3 5A 55 55
55 72 71 7F 6A AA AA AC 72 F3 7F 6A AA AA 31 2E AA AA AA 55
F3 5A 55 55 55 92 D6 EB 72 F1 CB 18 AA AA 32 F1 94 BA AA AA
21 EA AA AA AE CC 62 17 12 D7 31 28 AA AA AA CC 62 46 12 71
94 BA AA AA 45 54 AA BA 8A 9A EA FA DF CF 8F BF 9F AF 99 36
99 55 CC 12 26 CC 92 35 AA FD EA CC 31 24 9A CC 12 95 65 CC
99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 06 2F 1F 3F
0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC 12 26 CC 92 35 AA
FD EA CC 31 24 9A CC 12 B5 65 CC 99 55 CC DE 8A 15 A2 96 FA
88 96 89 A7 84 95 02 86 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF
99 36 99 55 CC 12 36 CC 92 35 AA FD EA CC 31 24 9A CC 12 A5
65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 07 2F
1F 3F 0F 4F 5F BC 72 F2 7F 6A AA AA 14 2B FF 55 F3 D7 45 55
55 7F D6 F2 DF 55 55 55 EA AA AA AA 72 F2 F0 6A AA AA 32 FE
17 FF 55 FF E5 7F CC 12 73 B5 BA AA AA A2 15 99 ED 99 A2 15
89 ED 48 A2 15 F9 ED 38 A2 15 E9 ED E8 A2 15 AC ED 5B A2 15
FF ED 0B D1 BA A2 15 6E ED 9B A2 15 7E ED 4A D1 AA A2 15 29
ED DA A2 15 D9 ED 8A 14 08 12 F2 50 6A AA AA 32 F2 73 6A AA
AA 99 A6 12 F3 73 6A AA AA 99 36 CC 12 72 EF 8A AA AA A2 55
BA ED 8A 9A 36 55 F3 1A 55 55 55 CC D6 F2 2E 2A AA AA AA AA
92 25 AA ED 7A 12 26 99 A6 99 17 99 87 34 D7 8A AA AA 92 7D
57 0A ED 1A 92 7D 57 1A ED FA 34 FE BA AA AA CC 92 71 B5 BA
AA AA 28 8D 5F CC 92 71 B5 BA AA AA A9 CD 8F CC 92 71 B5 BA
AA AA F9 ED 2E CC 92 71 B5 BA AA AA E9 ED 49 CC 92 71 B5 BA
AA AA FF ED E9 CC 92 71 B5 BA AA AA AC ED 08 CC 92 71 B5 BA
AA AA EC ED A8 CC 92 71 B5 BA AA AA 2D ED CB CC 92 71 B5 BA
AA AA 3D ED 6A CC 92 71 B5 BA AA AA 7D ED 8A 14 9A 25 14 BA
35 5A 82 F7 AA AA AA 72 71 7F 6A AA AA AC 92 D6 EB 72 F1 9B
78 AA AA 32 F1 94 BA AA AA 21 CA AA AA AE CC 62 17 12 D7 31
28 AA AA AA CC 62 46 12 71 94 BA AA AA 45 54 AA BA 8A 9A EA
FA DF CF 8F BF 9F AF 99 36 99 55 CC 12 26 CC 92 35 AA FD EA
CC 31 24 9A CC 12 95 65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96
89 A7 84 95 02 06 2F 1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99 36
99 55 CC 12 26 CC 92 35 AA FD EA CC 31 24 9A CC 12 B5 65 CC
99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 86 2F 1F 3F
0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC 12 36 CC 92 35 AA
FD EA CC 31 24 9A CC 12 A5 65 CC 99 55 CC DE 8A 15 A2 96 FA
88 96 89 A7 84 95 02 07 2F 1F 3F 0F 4F 5F BC 34 B4 AA AA AA
72 71 7F 6A AA AA AC 92 D6 EB 72 F1 24 78 AA AA 32 F1 94 BA
AA AA 21 CA AA AA AE CC 62 17 12 D7 31 28 AA AA AA CC 62 46
12 71 94 BA AA AA 45 54 AA BA 8A 9A EA FA DF CF 8F BF 9F AF
99 36 99 55 CC 12 26 CC 92 35 AA FD EA CC 31 24 9A CC 12 95
65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02 06 2F
1F 3F 0F 4F 5F DF CF 8F BF 9F AF 99 36 99 55 CC 12 26 CC 92
35 AA FD EA CC 31 24 9A CC 12 B5 65 CC 99 55 CC DE 8A 15 A2
96 FA 88 96 89 A7 84 95 02 86 2F 1F 3F 0F 4F 5F DF CF 8F BF
9F AF 99 36 99 55 CC 12 36 CC 92 35 AA FD EA CC 31 24 9A CC
12 A5 65 CC 99 55 CC DE 8A 15 A2 96 FA 88 96 89 A7 84 95 02
07 2F 1F 3F 0F 4F 5F 72 F3 7F 6A AA AA 31 2E AA AA AA 55 F3
1A 55 55 55 BC 92 7D 57 0A ED 2A 92 7D 57 1A ED 8A 14 0D CC
12 73 B5 BA AA AA 14 BD A2 15 89 ED BB A2 15 E9 ED 6A A2 15
7E ED DA A2 15 D9 ED 8A 14 1F 51 0E 2A AA AA 9A 75 CC 12 73
EF 8A AA AA B2 94 55 55 AA AA 9E CC 55 F1 35 8A AA AA 21 8A
AA AA AA CC D5 94 CC 32 F2 35 8A AA AA CC 52 F2 35 8A AA AA
12 71 50 6A AA AA 41 0E 2A AA AA 9A F5 92 C6 8A CC 12 72 EF
8A AA AA B2 B4 55 55 AA AA 21 8A AA AA AA CC D5 B4 12 26 95
E0 12 F2 F2 6A AA AA 12 73 32 6A AA AA 12 72 72 6A AA AA 12
F3 B3 6A AA AA 5F 4F 7F 60 B8 02 00 00 40 FE EF 00 01 02 03
04 05 B8 03 00 00 40 66 8C CB 8D 95 E5 24 00 00 B9 B8 09 00
00 FE EF 00 01 02 03 04 05 8D 95 F1 18 00 00 B9 E8 15 00 00
FF 95 0B FF FF FF 61 C3


MsgDeviceIOControlHook:
hVxD:00000034 
SecParam: 00000003 
InBufferLen: 00000000 
nOutBufferSize: 00000048 
lpOverlapped: 00000000
InBuffer:
OutBufbefore: 
01 00 00 00 01 00 00 00 68 73 68 6C 48 00 00 00 28 00 00 00
F2 17 05 00 00 00 00 00 00 00 00 00 B5 1C 9A D6 AA 58 7C 81
00 00 43 00 00 00 44 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 02 1E 00 00 00 00 04 00
VxDAnswerEAX: 00000001
(BytesReturned: 00000000):
VxDAnswerMsg: 
01 00 00 00 01 00 00 00 68 73 68 6C 48 00 00 00 28 00 00 00
F2 17 05 00 00 00 00 00 00 00 00 00 B5 1C 9A D6 AA 58 7C 81
00 00 43 00 00 00 44 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 02 1E 00 00 00 00 04 00

...

  Не буду приводить весь лог. Скажу только то, что он оказался не очень большим. Я уже начал писать "заменитель" таких обращений, но вначале обратил внимание на то, что вызываемый драйвер меняет совсем немного данных, переданных ему. Только ради "прикола" я заменил все вызовы DeviceIOControl на ответы "все хорошо" и ожидал, естественно, что программа не обнаружит ключа hasp и не будет загружаться. Но ... приложение загрузилось как ни в чем не бывало !!!

  Вот именно - не понял. Как же так же ? Если приложение НИКАК не общается с драйвером, но тем не менее умудряется выполнять проверки на hasp, то как оно это делает ???

Шестая попытка. Опять регистры DRx

  Вот так. Предидущий непонятный момент я пока списал на сообщения, которые передает VMM VxD-драйверам или что еще. Вернемся на арену VxD, где пока была отложена схватка за DRx. Обращаем внимание на то, что в регистре DR7 есть бит 13:

; Включение ловушек
  ;        FEDCBA9876543210FEDCBA9876543210
  mov  eax,01100110011001100010011111111111b
  mov  dr7,eax

  бит 13: бит GD - включает режим, в котором любое обращение к 
                   любому отладочному регистру, даже из кольца защиты 0,
                   вызывает исключение #DB
  ...

  О. Вот то, что нам нужно. Эта фича поможет нам выполнить следующее: устанваливаем этот бит в 1, теперь все команды замусоривания регистров DRx автоматом перейдут к нам. Но мы тогда не будем их выполнять, а будем эмулировать:

; подпрограмма - ловушка #1 - debug
BD equ 0010000000000000b
B0 equ 0001b
B1 equ 0010b
B2 equ 0100b
B3 equ 1000b
CMD_IN_AL_DX equ 0ECh
;      FEDCBA9876543210       
TrapPort proc
  push ebp
  mov  ebp,esp

  ...

; Адрес возврата EIP
  mov  ecx,[ebp+4]
; Адрес возврата CS->ES
  mov  es,word ptr [ebp+8]

; Причина отладочного прерывания
  mov  eax,dr6
  test eax,BD
  jz   @@NotDebugRegs

; Запомнить байты инструкции
; Адрес возврата EIP
; Команды мусоренья не запоминаем
;;  mov  ecx,[ebp+4]
;;  call Store_LogRecord

; Очищаем бит BD в регистре dr6
  and  eax, not BD
  mov  dr6,eax

; Если это было обращение к DRx, не нужно выполнять эти команды
; Запоминаем адрес возврата и возвращаемся в наш код
  add  ecx,3

  jmp  @@AfterDebugRegs

@@NotDebugRegs:

  ...

; Причина отладочного прерывания в доступе к портам ?
  mov  eax,dr6
  test eax,B0
  jz   @@NotDR0
; Очищаем бит B0 в регистре dr6
  and  eax, not B0
@@NotDR0:
  test eax,B1
  jz   @@NotDR1
; Очищаем бит B1 в регистре dr6
  and  eax, not B1
@@NotDR1:

  ...

  mov  dr6,eax

@@AfterDebugRegs:

; Запоминаем адрес возврата и возвращаемся в наш код
  mov  dword ptr RetAddr_UD01_EIP,ecx
  mov  word ptr RetAddr_UD01_CS,es

  mov  [ebp+4],offset32 After_DebugRegisterUsed
  mov  word ptr [ebp+8],cs

  ...

After_DebugRegisterUsed proc
  pushad
  pushfd
; Enable DE flag
  mov  eax,cr4
  or   eax,01000b
  mov  cr4,eax
  ;        FEDCBA9876543210FEDCBA9876543210
  mov  eax,01100110011001100010011111111111b
  mov  dr7,eax
  popfd
  popad
  jmp  dword ptr RetAddr_UD01_EIP
After_DebugRegisterUsed endp

  Тут несколько сложновато написано, но смысл такой: всякий раз при выполнении такого исключения все биты в DR7 скидываются, и мы получаем в исключении #1 его "чистым". Попытка проинициализировать его внутри обработчика приведет к краху системы, а отдавть управление назад со сброшенным регистром DRx как-то неприлично. Для этого я возвращаюсь не в вызвавший исключение код, но в собственную подпрограммку After_DebugRegisterUsed.

  Запомнив адресок возврата, уже в этой программке делаю переинициализацию DR7 и возвращаюсь куда следует. Возможно, кто-то спросит меня, почему повторная инициализация DR7 внутри After_DebugRegisterUsed не приводит к вызову #1 - ? Ответ такой: не знаю. А если бы это было не так, то как вообще тогда установить DR7 ? :)

  Ну вот. Теперь мы в "памперсе" и мы защищены от порчи DR7. Как удачно, что DR0-DR3 никто не трогает, но с этим тоже легко справиться. А еще не менее удачно, что никто не переставляет int 01 ;)

  Но что это ? Запуск программы prog.exe опять не показал перехватов обращений к портам ! Точнее говоря, в логе видны только обращения к отладочным регистрам DRx и то, что мы их успешно "исправляем". Но нет, нет обращений к портам.

Обоюдоострое оружие от Intel

  Нам интел дал мощное средство против защиты в виде DRx, но "меч не той версии". Почему ? После некоторых копаний в той же книжке Зубкова С.В. находим следующее:

CR4: этот регистр (появился только в процессорах Pentium)
 управляет новыми возможностями процессоров. Все эти возможности
 необязательно присутствуют, и ...

бит 3: бит DE - запрещает отладочные прерывания по обращению к портам

  Упс. Но вот помешать защите сбросить этот бит никто не может, никакого обращения к нему процессор не контролирует.

  Получается, что Интел дал нам обоим по разному оружию, и у всего оружия есть свои слабости и достоинства. Как же быть >?

  Приходится опять лезть в вязкий (хоть и не очень большой) код малого hasplit в дизассемблере. И выяснять, как и насколько часто он портит уже и регситр CR4.

Попутно: как общается приложение с VxD

  Чуть выше я задал сам себе загадку: как общается код win32-приложения с VxD драйвером, если изоляция DeviceIOControl не помогает ?

  Так вот, при более детальном копании в недрах малого hasplit выясняется, что он делает следующие шаги: при получении сообщения от системной машины THREAD_INIT он проверяет, устанолен ли его собственный обработчик исключений #6 и #14. Исключение #6 - это исключение UD - undefined operation. Если проц наткнется на опкод, который не сможет опознать, то он зовет это исключение. Исключение #14 - это Page Fault - ошибка записи или чтения в защищенную страницу памяти (при включенной страничной адресациии). Для вызова этого исключения существует специальная команда mov eax,ds:[0]. Шутка :)

  Если обработчиков таких вот нет, то малый hasplit установит их на себя. Второй обработчик, видимо, не очень интересен: он проверяет, где эксепшен. Если внутри него же (внутри hasplit.vxd), то он "застрелится" из halt+cli, иначе передаст управление куда-то там дальше...

  Приложение же загружает драйвер, походу слегка проверяя, нету ли тут Soft-Ice. Это делается попыткой открыть файл "\\.\SICE" и, затем, "\\.\NTICE". Но это совсем не главное. Далее приложение сознательно передаст управление на недопустимый к выполнению код. А дальше уже управление получит VxD и начнет свою часть работы. Таких вызовов состоится около 8-ми сотен. При этом VxD активно сопротивляется попыткам его трейсить, видимо, выполняя сверки CRC.

Поиск очистки CR4 внутри hasplit.vxd

  В ходе трассировки hasplit'а как-то не встретилось таких команд, как mov cr4,eax со сброшенным битом DE. Попробуем поискать его в hiew - тоже нет. Да, кончено, hasplit активно противостоит даже просмотру в отладчике: распаковывает и выполняет свои функции в памяти и проч. Но все же странно...

  А что-то я давно не выслушивал "начальника транспротного цеха". Что-то мы подзабыли большой и здоровый haspbig.vxd. А в нем ? Может, в нем есть такие команды ?

  А что Вы думаете - есть ! Небольшая загадка: каким числом ? Правильно, один. Одна команда на полметра. Не может быть ! Быстро пишу nop, nop, nop..., кидаю его в SYSTEM, рестарт... работает ! Все. Теперь наш перехватчик чудесно все записывает - вот они, команды общения с портом LPT:

Total traps: 0000072366 See log file trap_01.log...
OpC=ee DX=0378 AL=80 (?) rep=0000
OpC=ee DX=0378 AL=c6 (?) rep=0000
OpC=ee DX=0378 AL=c7 (?) rep=0000
OpC=ee DX=0378 AL=c6 (?) rep=0000
OpC=ee DX=0378 AL=80 (?) rep=0000
OpC=ee DX=0378 AL=8a (?) rep=0000
OpC=ee DX=0378 AL=8b (?) rep=0000
OpC=ee DX=0378 AL=8a (?) rep=0000
OpC=ee DX=0378 AL=f8 (?) rep=0000
OpC=ee DX=0378 AL=f9 (?) rep=0000
OpC=ee DX=0378 AL=f8 (?) rep=0000

  В первой колонке - опкод команды исключения (используются только чтение in al,dx или запись out dx,al).

Подмена сценария

  Мы подходим к кульминации сюжета. Все бронежелеты заюзаны, осталось сердце защиты - hasp ключ. В него пишутся данные и получаются ответы. Эти ответы и нужно один раз записать и подставлять во всех остальных случаях.

  Делаем первый тест. Списываем лог (около 53 тысяч команд, но это опционально от версии и т.п.). Допустим, сессия обмена всегда постоянна. Тогда, подставив его, мы получим возможность работы без ключа. Но ... не проходит.

  Записываем несколько логов. Смотрим разницу. Ага, логи отличаются, но не сильно (примерно 10-50 команд чтения/записи на 53 тысячи). Это внушает оптимизм.

  На данном этапе придется лезть в формат обмена данными с hasp. Лучшее, что я нарыл - это "Програмная эмуляция HASP ключей" by exefoliator. Там упоминается, что hasp реализует всего три функции:

HASP-3 поддерживает только 3 основные функции: ISHASP (дает информацию
о подключении HASP ключа - т.е. подключени или нет), HASPSTATUS (Возвращает
тип ключа HASP) и HASPCODE (возвращает 64 битный код в зависимости от
входного (seed) 16 битного кода). Остальные ключи поддерживают эти 3
функции + функции для записи/чтения в память, получение ID кода и доступа
к таймеру.

  Далее говорится, что в коде обычно реализованы три функции вида:

Функции|      Параметры вызова| Возращаемое значение|
ISHASP        BH <- 1, BL <- LPT №.    AX = 0 (нету HASP) или 1 (HASP есть)

HASPCODE      BH <- 2, BL <- LPT №|.    AX = return code 1
              AX <- seed код           |BX = return code 2
              CX <- password1           |CX = return code 3
              DX <- password2           |DX = return code 4

HASPSTATUS    BH <- 5, BL <- LPT №.    |AX = размер памяти
              CX <- password1           |BX = тип HASP
              DX <- password2           |CX = LPT к которому подключено.

  И приводится пример программки - эмулятора таких вызовов. Но то ли я не дорюхал, то ли что, но этот путь оказался для меня тупиком. По двум причинам: 0) Я не смог подобрать 8-мь байт данных для имитации отклика хасп-ключа по совету exefoliator'а; 1) Вызов подобный тому, что приводится выше, действительно есть, но его никто не делает. То ли это забыли с давних времен win 3.11, то ли под XP заготовка.

  Однако изучить хасп может помочь замечательная утилитка haspgrab. Писана на паскале под дос и упакована, чудесно смотрится в отладчике. Все вызовы удобно идут подряд в main'е. Спасибо тому, кто ее сделал. Ниже в приложении 1, приводится выдержки из этой утилиты, которые я написал на том же паскале. А сейчас я приведу формат обмена с hasp-ключем, позволяющий получить Public Table ключа:

Out: 0C 80 C6 C7 C6 80 8A 8B 8A F8 F9 F8 DA DB DA BA BB BA 94 95 94
Out: C8 C9 C8 A8 A9 A8 80 81 80 92 93 92 D0 D1 D0 B0 B1 B0 8C 8D 8C
Out: 9E 9F 9E DC DD DC BC BD BC
Out: FE
In:  7F 
Out: FC
In:  7F
Out: FA
In:  5F
Out: F8
In:  5F
; Далее в упрощенном формате записано
Out=>F6 BIn=7F Bout=F4 BIn=7F Bout=F2 BIn=7F Bout=F0 BIn=5F Bout=EE BIn=7F
Bout=EC BIn=7F Bout=EA BIn=7F Bout=E8 BIn=7F Bout=E6 BIn=7F Bout=E4 BIn=7F
Bout=E2 BIn=7F Bout=E0 BIn=7F Bout=DE BIn=5F Bout=DC BIn=5F Bout=DA BIn=5F
Bout=D8 BIn=5F Bout=D6 BIn=7F Bout=D4 BIn=5F Bout=D2 BIn=7F Bout=D0 BIn=5F
Bout=CE BIn=7F Bout=CC BIn=7F Bout=CA BIn=7F Bout=C8 BIn=7F Bout=C6 BIn=7F
Bout=C4 BIn=7F Bout=C2 BIn=7F Bout=C0 BIn=7F Bout=BE BIn=7F Bout=BC BIn=7F
Bout=BA BIn=5F Bout=B8 BIn=5F Bout=B6 BIn=7F Bout=B4 BIn=7F Bout=B2 BIn=7F
Bout=B0 BIn=5F Bout=AE BIn=7F Bout=AC BIn=7F Bout=AA BIn=5F Bout=A8 BIn=5F
Bout=A6 BIn=7F Bout=A4 BIn=7F Bout=A2 BIn=7F Bout=A0 BIn=5F Bout=9E BIn=5F
Bout=9C BIn=5F Bout=9A BIn=5F Bout=98 BIn=5F Bout=96 BIn=7F Bout=94 BIn=5F
Bout=92 BIn=7F Bout=90 BIn=5F Bout=8E BIn=5F Bout=8C BIn=5F Bout=8A BIn=5F
Bout=88 BIn=5F Bout=86 BIn=7F Bout=84 BIn=5F Bout=82 BIn=7F Bout=80 BIn=5F

Public table :50 50 73 73 FF 50 FF 73

  Обащаю внимание на следующие особенности формата команд (это взгялд дилетанта :) ). Сначала всегда идет что-то типа сброса (инициализации) начала передачи - out base+2,0Сh, потом out base,80h, потом отсыл байта C6 в виде трех посылок: C6,C7,C6. Вообще ключевой момент формата команд - это посылка байтов тройками. Сначла посылается байт, потом байт or Bit, потом опять байт. Bit опционален и может быть и 5-м, и 6-м. В приведенном выше примере затем посылается байт 80h, а потом вот именно в формате троек вот такая строка:

$8A,$F8,$DA,$BA, $94,$C8,$A8,$80, $92,$D0,$B0,$8C, $9E,$DC,$BC

  Ответ на эту команду читается следующим образом: мы должны прочесть 64-е бита (помните статью exefoliator'а ?), но за одно чтение из порта можем читать один бит. Поэтому мы 64 раза отправляем в порт ( номер бита x 2 ) or 80h и читаем байт из base+1, бит данных окажется 5-м. Это также ключевой момент в формате обмена: данные всегда читаются один бит за одно чтение, все ответы могут быть 5F или 7F only.

  Переходим к анализу лога. Как я уже говорил, логи отличаются крайне незначитально. В первом приближении было видно, что отличия представляют собой два "пятна", один примерно в области строки ~33730 лога, другое - в области строки ~35660. Ниже приведены фрагменты 6-ти логов именно в области первого "пятна":

   lg1 lg2 lg3 lg4 lg5 lg6
ee =9e =9e =9e =9e =9e =9e
ee =be =be =be =be =be =be
ee =9e =9e =9e =9e =9e =9e
ee =de =de =de =de =de =de
ee =fe =fe =fe =fe =fe =fe
ee =de =de =de =de =de =de
ee =de =de =de =de =de =de
ee =fe =fe =fe =fe =fe =fe
ee =de =de =de =de =de =de
ee =9e =9e =9e =9e =9e =9e
ee =be =be =be =be =be =be
ee =9e =9e =9e =9e =9e =9e
ee =9e =9e =9e =9e =9e =9e
ee =be =be =be =be =be =be
ee =9e =9e =9e =9e =9e =9e
; diff started
ee =9e =9e =de =de =de =9e ; write 9e or de
ee =be =be =fe =fe =fe =be
ee =9e =9e =de =de =de =9e
; diff
ee =de =de =9e =9e =9e =de ; write 9e or de
ee =fe =fe =be =be =be =fe
ee =de =de =9e =9e =9e =de
; diff
ee =de =de =9e =9e =9e =de ; write 9e or de
ee =fe =fe =be =be =be =fe
ee =de =de =9e =9e =9e =de
; diff
ee =de =9e =9e =de =9e =de ; write 9e or de
ee =fe =be =be =fe =be =fe
ee =de =9e =9e =de =9e =de
; diff
ee =9e =de =9e =de =de =de ; write 9e or de
ee =be =fe =be =fe =fe =fe
ee =9e =de =9e =de =de =de
; begin read
ec =5f =5f =5f =5f =5f =5f
ee =be =fe =be =fe =fe =fe ; write be or fe
ee =9e =de =9e =de =de =de ; write 9e or de
ec =5f =5f =5f =5f =5f =5f
ee =be =fe =be =fe =fe =fe ; write be or fe
ee =9e =de =9e =de =de =de ; write 9e or de
ec =7f =7f =7f =7f =7f =7f
ee =be =fe =be =fe =fe =fe ; write be or fe
ee =9e =de =9e =de =de =de ; write 9e or de
ec =5f =5f =5f =5f =5f =5f
ee =be =fe =be =fe =fe =fe ; write be or fe
ee =9e =de =9e =de =de =de ; write 9e or de
ec =7f =7f =7f =7f =7f =7f
ee =be =fe =be =fe =fe =fe ; write be or fe
ee =9e =de =9e =de =de =de ; write 9e or de
ec =5f =5f =5f =5f =5f =5f
ee =be =fe =be =fe =fe =fe ; write be or fe
ee =9e =de =9e =de =de =de ; write 9e or de
ec =7f =7f =7f =7f =7f =7f
ee =be =fe =be =fe =fe =fe ; write be or fe
ee =9e =de =9e =de =de =de ; write 9e or de
ec =7f =7f =7f =7f =7f =7f
ee =be =fe =be =fe =fe =fe ; write be or fe
ee =9e =de =9e =de =de =de ; write 9e or de
ec =7f =7f =7f =7f =7f =7f
ee =be =fe =be =fe =fe =fe ; write be or fe
ee =9e =de =9e =de =de =de ; write 9e or de
ec =5f =5f =5f =5f =5f =5f
ee =be =fe =be =fe =fe =fe ; write be or fe
ee =9e =de =9e =de =de =de ; write 9e or de
ec =7f =7f =7f =5f =7f =7f ; read 7f or 5f
ee =be =fe =be =fe =fe =fe ; write be or fe
ee =9e =de =9e =de =de =de ; write 9e or de
ec =7f =7f =7f =7f =5f =7f ; read 7f or 5f
ee =be =fe =be =fe =fe =fe
ee =9e =de =9e =de =de =de
ec =5f =5f =7f =7f =7f =7f ; read 7f or 5f
ee =be =fe =be =fe =fe =fe
ee =9e =de =9e =de =de =de
ec =7f =7f =7f =7f =5f =7f ; read 7f or 5f
ee =be =fe =be =fe =fe =fe
ee =9e =de =9e =de =de =de
ec =7f =5f =5f =7f =7f =5f ; read 7f or 5f
ee =be =fe =be =fe =fe =fe
ee =9e =de =9e =de =de =de
ec =5f =5f =7f =5f =5f =5f ; read 7f or 5f
ee =be =fe =be =fe =fe =fe
ee =9e =de =9e =de =de =de
ec =5f =7f =5f =7f =5f =5f ; read 7f or 5f
ee =be =fe =be =fe =fe =fe ; write be or fe
ee =9e =de =9e =de =de =de ; write 9e or de
ee =9c =dc =9c =dc =dc =dc

  Начнем анализ с первых строк. Сначала во всех логах загружаются одинаковые байты (тройками):

9e,be,9e
de,fe,de
de,fe,de
9e,be,9e
...

  Но далее видно, что послдение пять загружаемых байт могут отличаться:

; diff started
ee =9e =9e =de =de =de =9e ; write 9e or de
ee =be =be =fe =fe =fe =be
ee =9e =9e =de =de =de =9e
; diff
ee =de =de =9e =9e =9e =de ; write 9e or de
ee =fe =fe =be =be =be =fe
ee =de =de =9e =9e =9e =de
; diff
ee =de =de =9e =9e =9e =de ; write 9e or de
ee =fe =fe =be =be =be =fe
ee =de =de =9e =9e =9e =de
; diff
ee =de =9e =9e =de =9e =de ; write 9e or de
ee =fe =be =be =fe =be =fe
ee =de =9e =9e =de =9e =de
; diff
ee =9e =de =9e =de =de =de ; write 9e or de
ee =be =fe =be =fe =fe =fe
ee =9e =de =9e =de =de =de
; begin read
ec =5f =5f =5f =5f =5f =5f

  И далее идет чтение отклика hasp-ключа именно тройками байт:

out be,93 ; Два байта записаны
in <- 5f  ; Один бит результата
...

  Во втором приближении приложение выполняет в потоке команд записи/ чтения откликов две команды где-то в середине сценария и при этом на вход подает различные данные: от этого и логи различаются. Но ! Эти данные отличаются лишь на ... 5-ть бит. Это 32 комбинации. Это немного. Это тоже можно эмулировать.

  Детальнее проанализируем эту часть лога. Посмотрим чуть выше, где начинается эта запись. Вот ее детальный формат:

;
  Data1: array[0..14] of byte= (
    $C2,$F0,$D2,$FA, $B4,$C0,$AC,$C0,
    $82,$C0,$F0,$84, $DE,$9C,$01); {$01-признак конца передачи}

; Эти десять байт передаем в вышеприведенном примере в логе 1 (левый)
  TestSend: array[0..9] of byte= (
    $9E,$DE,$DE,$9E, $9E,$9E,$DE,$DE,
    $DE,$9E);

; Стандартный префикс: 80+80+C6x3
  OutPort(PortData,$80);
  OutPort(PortData,$80);
  Send_Twice($C6);
  OutPort(PortData,$80);

  Send_Data(Data1);
  OutPort(PortData,$9E);

; Передаем 10 бит данных, последние пять могут отличаться от сессии к сесии

  for i:=0 to sizeof(TestSend)-1 do
    Send_TwiceBit5(TestSend[i]);

  { Читаем ответ }
  write('Answer:');
  for i:=0 to 16 do
    begin
      ResByte:=InPort(PortRead);
      OutPort(PortData,$BE);
      OutPort(PortData,$9E);
      BytesToHexWithFiller(ResByte,DebStr,1);
      write(DebStr);
    end;

  Таким образом, мы можем с помощью вот такого кода получить все возможные комбинации, которые программа только способна передать. Далее их нужно запомнить в подстановщике сценария - VxD, и при подмене сценария подставлять тот вариант ответа, который хочет программа в даннной сессии.

  Что же до второго "пятна" в логах, то, как это ни странно, оно оказалось совершенно идентично первому :) Это та же самая команда, с теми же самыми различными последними 5-мя битами.

  Таким образом в общем случае программная защита способна образовать 32x32 различных сессии, подставляя в двух случаях пять случайных бит. Возможно, это было сделано не специально ;) , а просто какая-нибудь секция .data? попадает под расшифровку. По крайней мере перевод системной даты на 5 лет вперед никак не помогает ей в этом.

  Последнее, что осталось - это привести пример (корявый) подстановщика верного отклика в этих сессиях:

@@NotDebugRegs:

; Запомнить байты инструкции
; Адрес возврата EIP
  mov  ecx,[ebp+4]
; Имитируем только отклики порта LPT
; Адрес возврата CS
  mov  es,word ptr [ebp+8]

  call GetFrom_LogRecord ; EDX и EAX - регистры из лога

  cmp  byte ptr es:[ecx-1],CMD_IN_AL_DX
  jnz  @@SkipLogPortsCommands

; Регистр eax меняем
  mov  byte ptr [ebp-4],al

@@SkipLogPortsCommands:

  ...

;
; Получить байты отклика из лог-буфера (EAX, EDX)
GetFrom_LogRecord proc
; Запоминаем байты и значения регистров команды
  mov  eax,dword ptr ds:LastLogPtr
  cmp  eax,dword ptr LogPtr
  jb   LogNotDone
  mov  dword ptr ds:LastLogPtr,0
  mov  eax,0
LogNotDone:

  inc  dword ptr ds:LastLogPtr
  imul eax,eax,sizeof(tLogPacket)
  mov  ebx,offset32 LogPackets
  add  ebx,eax
  assume ebx: ptr tLogPacket
; Регистр eax
  movzx eax,byte ptr [ebx].RegEAX
; Регистр dx
  movzx edx,word ptr [ebx].RegDX
  assume ebx:nothing

  ;; jmp  @@SkipAnalize

; Анализируем, что отдать/получить надо
  mov  ebx,dword ptr ds:LastLogPtr
  xor  esi,esi
  cmp  ebx,33373-1
  jb   @@SkipAnalize
  cmp  ebx,(33373+63)-1
  jbe  @@AnalizeIt
  mov  esi,35555-33373
  cmp  ebx,35555-1
  jb   @@SkipAnalize
  cmp  ebx,(35555+63)-1
  ja   @@SkipAnalize

@@AnalizeIt:

; Безотносительно места в логе  
  sub  ebx,esi
; Мы находимся в чтении ?
  cmp  ebx,33388-1
  jae  @@InCmds

; Нет, в записи
; Получаем номер пакета
  sub  ebx,33373-1
  push eax
  xor  dx,dx
  mov  ax,bx
  mov  bx,3
  div  bx
  mov  bx,dx
  movzx edi,ax
  pop  eax
  test bx,bx
  jnz  @@Next
; Номер пакета из трех байт передачи в edi (0-4)
; Записываемый байт в [ebp-4]
  push ecx
  push eax
  mov  al,byte ptr [ebp-4]
  shr  al,6
  and  al,1
  mov  ecx,edi
  shl  al,cl
  or   byte ptr ds:Variant,al
  pop  eax
  pop  ecx
  jmp  @@Next

@@InCmds:

  cmp  ebx,33391-1
  jb   @@Next
  sub  ebx,33391-1

; Номер пакета чтения
  push eax
  xor  dx,dx
  mov  ax,bx
  mov  bx,3
  div  bx
  mov  bx,dx
  movzx edi,ax
  pop  eax
  test bx,bx
  jnz  @@Next
; edi - номер пакета ответа (0..15)
  movzx eax,byte ptr ds:Variant
  shl  eax,4
  mov  al,byte ptr ArtAnswers[eax+edi]
  cmp  edi,15
  jb   @@Next
; Сбросить Variant
  mov  byte ptr ds:Variant,0

@@Next:

@@SkipAnalize:

  ret
GetFrom_LogRecord endp

  Спасибо всем прочитавшим ;)

  (C) Chingachguk /HI-TECH

Приложение 1. Код на паскале для работы с hasp. Выдержки из haspgrab

{$G+}
const
  base = $0378;
  PortData = 0;
  PortRead = 1;
  PortServ = 2;

procedure OutPort(PortAddr:word; PortData: Byte);
  begin
    Port[base+PortAddr]:=PortData;
    {PrintByte(PortData,'Bout=');}
  end;
function InPort(PortAddr:word):Byte;
  var
    bTmp: byte;
  begin
    bTmp:=Port[base+PortAddr];
    {PrintByte(bTmp,'BIn=');}
    InPort:=bTmp;
  end;
Procedure Send_Twice(PData: Byte);
  begin
    OutPort(PortData,PData);
    OutPort(PortData,PData or 1);
    OutPort(PortData,PData);
  end;
Procedure Send_TwiceBit5(PData: Byte);
  begin
    OutPort(PortData,PData);
    OutPort(PortData,PData or $20);
    OutPort(PortData,PData);
  end;
const
  Data0: array[0..15] of byte= (
    $8A,$F8,$DA,$BA, $94,$C8,$A8,$80,
    $92,$D0,$B0,$8C, $9E,$DC,$BC,$01);

  Data1: array[0..14] of byte= (
    $C2,$F0,$D2,$FA, $B4,$C0,$AC,$C0,
    $82,$C0,$F0,$84, $DE,$9C,$01);

  TestSend: array[0..9] of byte= (
    $9E,$DE,$DE,$9E, $9E,$9E,$DE,$DE,
    $DE,$9E);

  TestSend1: array[0..9] of byte= (
    $9E,$DE,$DE,$9E,$9E, $9E,$9E,$9E,$9E,$9E);

Procedure Send_Data(var PData: array of byte);
  var
    i: word;
  begin
    i:=0;
    while PData[i] <> $01 do
      begin
        Send_Twice(PData[i]);
        inc(i);
      end;
  end;
Function Read_DataBit: byte;
  begin
    Read_DataBit:= ( (InPort(PortRead) shr 5) and 1 );
  end;
Procedure Read_8Bytes(var Res8Bytes: array of byte);
  var
    i,j: word;
  begin
    FillChar(Res8Bytes,8,$00);
    for i:=0 to $3F do
      begin
        OutPort(PortData,((i shl 1) or $80));
        j:=(i shr 3);
        Res8Bytes[j]:=Res8Bytes[j] or (Read_DataBit shl (7-(i and $07)) );
      end;
  end;
{ Идентично предидущему, можно читать биты в обратном порядке }
Procedure Read_Swap8Bytes(var Res8Bytes: array of byte);
  var
    i,j: word;
  begin
    FillChar(Res8Bytes,8,$00);
    for i:=$3F downto 0 do
      begin
        OutPort(PortData,((i shl 1) or $80));
        j:=(i shr 3);
        Res8Bytes[j]:=Res8Bytes[j] or (Read_DataBit shl (7-(i and $07)) );
      end;
  end;
{$F+}
{ Заполнить строку AddrHex hex-представлением Number байтов из AddrBytes, }
{ но байты через пробел }
Procedure BytesToHexWithFiller(var AddrBytes,AddrHex; Number:Word);
  Begin
    Asm
    pusha
    push ds
    push es
    cld
    lds  si,AddrBytes
    les  di,AddrHex
    xor  cx,cx
    mov  al,byte ptr Number
    mov  cl,al
    shl  al,1
    add  al,cl {len x 3}
    stosb
    test cx,cx
    jz   @@Done
@@NextByte:
    lodsb
    mov  ah,al
    shr  al,4
    cmp  al,10
    sbb  al,69h
    das
    stosb
    mov  al,ah
    and  al,0Fh
    cmp  al,10
    sbb  al,69h
    das
    stosb
    mov  al,' '
    stosb

    loop @@NextByte
@@Done:
    pop  es
    pop  ds
    popa
    End;
  End;
var
  Res: array[0..7] of byte;
  ResByte: byte;
  DebStr: string;
  i, variant: word;
begin
  writeln('Start !');
  writeln('Send ini...');

  OutPort(PortServ,$0C);
  OutPort(PortData,$80);
  Send_Twice($C6);
  OutPort(PortData,$80);

  Send_Data(Data0);

  {Read_8Bytes(Res);}
  Read_Swap8Bytes(Res);

  BytesToHexWithFiller(Res,DebStr,8);

  writeln('Public table ?:',DebStr);

  exit;

  writeln('Write test:');

  OutPort(PortData,$80);
  OutPort(PortData,$80);
  Send_Twice($C6);
  OutPort(PortData,$80);

  Send_Data(Data1);
  OutPort(PortData,$9E);

  for i:=0 to sizeof(TestSend)-1 do
    Send_TwiceBit5(TestSend[i]);

  { Читаем ответ }
  write('Answer:');
  for i:=0 to 16 do
    begin
      ResByte:=InPort(PortRead);
      OutPort(PortData,$BE);
      OutPort(PortData,$9E);
      BytesToHexWithFiller(ResByte,DebStr,1);
      write(DebStr);
    end;

  writeln('All tests:');

  for variant:=1 to 32 do
    begin

      {BytesToHexWithFiller(TestSend1,DebStr,sizeof(TestSend1));
      writeln('Send:',DebStr);}

      OutPort(PortData,$80);
      OutPort(PortData,$80);
      Send_Twice($C6);
      OutPort(PortData,$80);

      Send_Data(Data1);
      OutPort(PortData,$9E);

      for i:=0 to sizeof(TestSend)-1 do Send_TwiceBit5(TestSend1[i]);

      { Читаем ответ }
      write('Answer:');
      for i:=0 to 16 do
        begin
          ResByte:=InPort(PortRead);
          OutPort(PortData,$BE);
          OutPort(PortData,$9E);
          BytesToHexWithFiller(ResByte,DebStr,1);
          asm mov  byte ptr DebStr[0],2 end;
          write('0',DebStr,'h');
          if i<16 then write(',');
        end;
      writeln;
      {readln;}

      { Следующий посыл }
      for i:=5 to 5+5 do
        begin
          if TestSend1[i] = $9E then
            begin
              TestSend1[i]:=$DE;
              break;
            end;
          TestSend1[i]:=$9E;
        end;
    end;

  writeln('Finish ;)');
end.


обсудить  |  все отзывы (0)

[34052; 57; 6.12]




Rambler's Top100
Рейтинг@Mail.ru





  Copyright © 2001-2024 Dmitry Leonov   Page build time: 1 s   Design: Vadim Derkach