Авторские статьи Взлом и исправление багов в WinNavigator v1.96

Discussion in 'Статьи' started by ProTeuS, 2 Jan 2007.

  1. ProTeuS

    ProTeuS --

    Joined:
    26 Nov 2004
    Messages:
    1,239
    Likes Received:
    542
    Reputations:
    445
    Взлом и исправление багов в WinNavigator v1.96

    Сегодня будем исследовать мой любимый файловый менеджер WinNavigator. Я лет 5 пользовался 1.95 версией, т.к.
    1.96(последняя версия, доступна на wnsoft.com, жаль проэкт закрыт уже 4 года) имела один досадный баг,
    времени на исследование которого никогда не хватало(по при4ине утери всех интсаллов это время теперь нашлось ;).
    Все, кто еще с DOSa привык пользоваться горя4имы клавишами, как и я, плохо себя 4увствуют если какая-то из них не работает.
    Так в 1.96 версии сабжа при нажатии хоткея "Ctrl + \" для перехода в корень текущего диска возникала ошибка вместо нужной операции:

    [​IMG]
    Усугубляется проблема еще тем, 4то при попытке распаковки выполняемого файла программы
    (как сказал PEID, он запротек4ен ASProtect 1.22 - 1.23 Beta 21 -> Alexey Solodovnikov) лицензия пропадает
    даже при нали4ии валидной регистрации =(
    Протестировать можно на этом клю4е(лу4ше вбивать клю4 непосредственно в редакторе реестра):
    Code:
    REGEDIT4
    [HKEY_CURRENT_USER\Software\WinNavigator]
    "Key"="0nhVQp5A+vUjiP4KIJsJtcqZ3t/LUFVBW0Fo3zUVIF5S
    1ccGs9gkabulamlqLQLR33evIRSekR+JJP5f6VFNxh+i0NLD98q
    RmczWjAQiP6QSlUOSOUi7AeK51MqPKDA3dmYWCI+1qJUGKTuR2M
    MRJRQFOGzXMgrxeT16B7LYbZWI= "
    "Reg"="313"
    
    Приступим к распаковке навесного протектора. Загрузив подопытного в ольку, видим знакомые команды.

    Code:
    00401000 >/$ 68 01F06100    PUSH WN.0061F001
    00401005  |. E8 01000000    CALL WN.0040100B
    0040100A  \. C3             RETN
    0040100B   $ C3             RETN
    
    В "исклю4ениях" свойств отладки отклю4аем все 4екбоксы и (не забыв активировать плагин IsDebugPresent, либо вру4ную пропат4ив соответствующий флаг)
    проходим 32 исклю4ения. Видим такой код:

    Code:
    012005CC   3100             XOR DWORD PTR DS:[EAX],EAX
    012005CE   64:8F05 00000000 POP DWORD PTR FS:[0]
    012005D5   58               POP EAX
    012005D6   833D DC492001 00 CMP DWORD PTR DS:[12049DC],0
    012005DD   74 14            JE SHORT 012005F3
    
    Ставим бряк на 012005DD, жмем Ctrl + F9 и бряк на доступ к памяти секции кода екзешника. F9 и мы на OEP. Дампим, восстанавливаем импорт в Imprec
    (воспользовавшись функциями DisAsm1 и плагом для аспра, 4тобы восстановить нерезолвящиеся функции).

    Запустив распакованый файл на свое удивление полу4аем такое вот сообщение (даже при валидной регистрации):

    Code:
    005380B8   . B8 AC815300    MOV EAX,fixed.005381AC                   ; |ASCII "Dear registered user of WinNavigator!
    We have changed registration mechanism, so you need a new registration key.
    Please contact us ([email protected]) and get a new registration for FREE.
    
    Sorry for some inconvenience."
    и приставку
    005380DC   . B9 94825300    MOV ECX,fixed.00538294                   ;  ASCII "  -  UNREGISTERED"
    на главном окне программы + ку4у ограни4ений и нагов
    
    [​IMG]
    Изменив выделенную команду на нопы, сообщении выдаваться не будет.
    4тобы узнать логику срабатывания условного перехода делаем следующее.
    Ставим бряк на соответсвующие строки и жмем F9. При отработке бряка смотрим в стек вызовов и самой верхней надфункцией в нем есть
    00537ADB |. E8 D4040000 CALL fixed.00537FB4
    Входим в нее и видим код:

    Code:
    00537FD6   > A1 B4F55600    MOV EAX,DWORD PTR DS:[56F5B4]
    00537FDB   . 50             PUSH EAX                                 ; /ProcNameOrOrdinal => #5
    00537FDC   . A1 B0F55600    MOV EAX,DWORD PTR DS:[56F5B0]            ; |
    00537FE1   . 50             PUSH EAX                                 ; |hModule => FFFFFFFF
    00537FE2   . E8 D9F2ECFF    CALL <JMP.&kernel32.GetProcAddress>      ; \GetProcAddress
    00537FE7   . 85C0           TEST EAX,EAX
    00537FE9   . 74 62          JE SHORT fixed.0053804D
    
    Можно догадаться, 4то в пакованом (видимо это особенность мутации ли4ной версии спра с выполняемым файлом) файле функция .00537FE2
    выдаст правильный результат, т.к ей аргументом передастся верный hModule, в нашем же слу4ае для подмены результатов проверки (в распакованной проге, понятное дело, они никогда не будут правильными)
    достато4но занопить команду .00537FE9.

    Нагов нет, вот только осталась надпись о незарегистрированности в окне "О программе". 4тобы ее по-быстрому снять, ищем строку
    "NOT REGISTERED COPY" в перекрестных ссылках. Попадаем сюда:
    [​IMG]

    Видим знакомый вызов. Поскольку GetProcAddress явно возвратит 0, а не нужный адрес искомой функции (которая потом будет вызываться call esi),
    то во избежение переполнения удалим весь код непосредственно до .4FD37F
    [​IMG]

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

    Самый быстрый способ - отклю4ить игнор в ольке на все эксепшены и просто нажать в запущеной проге Ктрл + \ ;)
    Брякаемся на эксепшене
    [​IMG]

    На 3 команды выше выполняется основная функция файлового менеджера по парсингу путей, которая выдаст в EDX
    указатель на надпапку (EDX=0121A114, (ASCII ".."). Команда .53E92B постоянно возвращает нуль (DS:[012087CC]=00000000).
    Таким образом, команда .53E931 будет ссылаться на несуществующий указатель. А поскольку команда пыталась записать в DL
    байт по [EDX] (а EDX имел нулевое зна4ение), то можно предположить, 4то в DL надо просто записать нуль (либо ни4его не делать, т.к.
    в нешем слу4ае он уже там). Тогда просто забиваем .53E931 нопами и радуемся полнофункциональности файлового менеджера и отсутствию
    исследованого бага.

    gl hhf!
     
    5 people like this.