Анализ APP'98 v1.96 - 19:08 - by CyberPoizon, mongoose
 
-  Вступление

    CyberPozion уже публиковал статью о APP`98 v1.70 в журнале TopDevice onli-
 ne,  это было только началом.  В статье использовались исследования CyberPoi-
 zon'а (руководителя исследований) и mongoose.

    CyberPoizon  [cPz] - исследования APP`98 v1.96
    mongoose     [mng] - написание утилиты, мелкие исследования


-  Об антивирусе

 [cpz]

    Антивирус довольно новый,  поэтому совершенно естествено, что он недорабо-
 тан. Мне было интересно посмотреть на его устойчивость. Результаты работы пе-
 ред Вами. Хотелось бы выразить признательность господину Каримову, за то, что
 он постоянно улучшает антивирус.  Я желаю ему успехов  в  продвижении  своего
 продукта  на  отечественный и зарубежный рынок.  Осталось лишь добавить,  что
 последущие версии продукта, я попытаюсь не обойти своим вниманием.


 [mng]

    Ранее я никогда не занимался исследованием антивирусов,  тем более ревизо-
 вор. Когда-то давно я пользовался Adinf'ом и мне он не особенно нравился, т.к
 мои  черви (в то время файловые) легко его обходили.  AP98 так же можно легко
 обойти, он содержит множество недоработок. Несмотря на все это на моей машине
 стоит копия антивируса.


-  Регистрационный ключ

    Регистрационный ключ должен находиться в  каталоге  APP'98  и  обязательно
 должен иметь расширение "KEY".

    Формат ключа:

   смещение      длина         содержимое

    000h [000]    07bh [123]    Нули (00h)
    07bh [124]    001h [001]    Символ 0D6h
    07ch [125]    050h [080]    Нули (00h)
    0cch [204]    007h [007]    Дата годности ключа в аscii, например
                                11/07/2003, следующие два символа любые
    0d8h [216]    001h [001]    Размер регистрационного имяни
    0d9h [217]    01bh [027]    Регистрационное имя, максимальный размер 25
                                байт, следующие 2 символа любые
    0f4h [244]    001h [001]    Размер серийного номера
    0f5h [245]    063h [099]    Серийный номер, максимальный размер 25 байт
                                остальные 74 символа любые
    158h [344]    001h [001]    Размер строки "поддержки" ;]
    159h [345]    068h [104]    Строка "поддержки" ;], максимальный размер 103
                                байта

    Данные с ДАТЫ ГОДНОСТИ КЛЮЧА (0cch) по РАЗМЕР СТРОКИ "ПОДДЕРЖКИ" (не вклю-
 чая  РСП,  158h) зашифрованны комбинацией:  xor al,2/ror al,1/not al,  что бы
 рас- шифровать, используйте комбинацию:

                mov     cx,(размер строки поддержки-дата годности ключа)
                lea     si,offset дата годности ключа
                push    si
                pop     di                      ; si=di
 decrypt_cycle: lodsb                           ; byte from [si], to al
                not     al                      ; 
                rol     al,1                    ; decryption instructions
                xor     al,2                    ; 
                stosb                           ; byte from al, to [di]
                loop    decrypt_cycle


-  Конфигурационный файл "AP98.CFG"

    Конфигурационный файл не зашифрован. Из него  были убраны сигнатуры и  оп-
 ция работы с диском через IDE.

   смещение      длина         содержимое

    06Bh [107]    001h [001]    Чтение через IDE
    071h [113]    001h [001]    Проверка диска A (0-No,1-Yes)
    074h [116]    001h [001]    Создание log файла (0-No,1-Yes)
    075h [117]    004h [004]    Адрес обработчика int 13h
    279h [633]    002h [002]    Кол-во дисков в системе
    27Bh [635]    001h [001]    Проверка Flash Bios (0-No,1-Yes)


-  Таблица "AP98.TB1"


   смещение      длина         содержимое

    273h [627]   256h [512]     копия MBR


   Таблица "AP98F.TBL"

    Разработчики убрали сигнатуры из начала таблицы,  но  так  и  не  вставили
 функцию позволяющую задавать пользователю произвольное имя таблиц,  и мы спо-
 койно можем искать файл "AP98F.TBL".

    В данной таблице хранятся данные о проверяемых файлах,  она  зашифрованна,
 но расшифровывается довольно просто:

                mov     cx,размер таблицы
                lea     si,таблица
                push    si
                pop     di                      ; si=di
 decrypt_cycle: lodsb                           ; byte from [si], to al
                not     al                      ; 
                ror     al,1                    ; (de)cryption instructions
                xor     al,2                    ; 
                stosb                           ; byte from al, to [di]
                loop    decrypt_cycle

 [cPz]  В отладчике это выглядит, примерно, так:

3A85:4B49  7F1D             JG        4B68
3A85:4B4B  A36AC8           MOV       [C86A],AX
3A85:4B4E  EB04             JMP       4B54
3A85:4B50  FF066AC8         INC       [WORD C86A]
3A85:4B54  FF366AC8         PUSH      [WORD C86A]
3A85:4B58  E8C1F6           CALL      421C       ; [!] Самое интересное
3A85:4B5B  9AC10C3A40       CALL FAR  403A:0CC1
3A85:4B60  A16AC8           MOV       AX,[C86A]
3A85:4B63  3B46FE           CMP       AX,[BP-02]
3A85:4B66  75E8             JNE       4B50
3A85:4B68  E9C702           JMP       4E32

    Далее входим в call 421C и трассируем до такого участка:

3A85:4249  E805E3           CALL      2551       ; [!] Вот здесь
3A85:424C  E8F1EF           CALL      3240
3A85:424F  E8FBE7           CALL      2A4D
3A85:4252  E812EA           CALL      2C67
3A85:4255  E8B5EA           CALL      2D0D
3A85:4258  E8F3EB           CALL      2E4E
3A85:425B  E84CF0           CALL      32AA
3A85:425E  E800F1           CALL      3361
3A85:4261  833E6AC801       CMP       [WORD C86A],01
3A85:4266  7503             JNE       426B
3A85:4268  E821ED           CALL      2F8C

    Вся работа с таблицами начинается в отмеченном вызове,  входим в процедуру
 и просто заходим во все вызовы.  Там будет и проверка ключа,  и работа с фай-
 лом. Но нас интересует это:

28FE:28C3  680002           PUSH      0200
28FE:28C6  9AC3004B37       CALL FAR  374B:00C3  ; [!] Вот тут
28FE:28CB  BF62BC           MOV       DI,BC62
28FE:28CE  1E               PUSH      DS
28FE:28CF  57               PUSH      DI
28FE:28D0  9A5639D745       CALL FAR  45D7:3956
28FE:28D5  BF62BC           MOV       DI,BC62
28FE:28D8  1E               PUSH      DS
28FE:28D9  57               PUSH      DI
28FE:28DA  6A02             PUSH      02
28FE:28DC  9A9B003B45       CALL FAR  453B:009B
28FE:28E1  BF4F25           MOV       DI,254F

    Входим в процедуру и трассируем до:

48D2:00DE  AC               LODSB
48D2:00DF  F6D0             NOT       AL        ; 
48D2:00E1  D0C0             ROL       AL,1      ;  собственно расшифровка
48D2:00E3  3402             XOR       AL,02     ; 
48D2:00E5  AA               STOSB
48D2:00E6  E2F6             LOOP      00DE
48D2:00E8  1F               POP       DS
48D2:00E9  C9               LEAVE
48D2:00EA  CA0600           RETF      0006


    Кстати, для зашифровки файлов (конфигурационного файлов  и  таблиц)  нужно
 использовать последовательность команд xor al,2/ror al,1/not al. Таблица сос-
 тоит из записей, размер одной записи (одна запись соответствует данным об од-
 ном файле) 86 байт.

    Формат таблицы следующий:

   смещение      длина         содержимое

    000h [000]    001h [001]    Длина пути к файлу
    001h [001]                  Путь к файлу (размер по смещению 000h)
    051h [081]    004h [004]    Размер файла
    055h [085]    002h [002]    CRC16 X)

    Мне непонятно,  только одно, почему если в "FILES.DAT" после каталога ука-
 зываешь маску "*.*", то база каталога будет содержать не только записи о фай-
 лах, но и записи о каталогах "." и "..". X)

                                  article by CyberPozion, mongoose [MY AS 2K]