Показать сообщение отдельно

  #2  
Старый 14.08.2006, 17:14
ProTeuS
Познавший АНТИЧАТ
Регистрация: 26.11.2004
Сообщений: 1,367
Провел на форуме:
4226592

Репутация: 2175


Отправить сообщение для ProTeuS с помощью ICQ
По умолчанию

Отладка и взлом жертвы с помощью патча

Загружаем распакованную прогу в отладчике. Поскольку для ввода регистрационных данный она использует стандартные окна ввода,



Окно ввода регистрационных данных

и стандартное окно ошибки, то было решино по старинке установить точки останова на вызовах функций MessageBoxA (выводящих сообщения об ошибке) или GetDlgItemTextA (считывающих вводимый текст).



Установка бряков на вызове функций MessageBoxA

Нажатие на кнопку "Enter License Information" привело на такой кусок кода в ольке:



Прервались на выводе ошибке длинны регкода (она должна быть равна 20)

Каким же было мое удивление, когда протрассируя участки с проверкой длин введенных регистрационных данных (.0042563A), кучей строковых и арифметических преобразований с ними (.00425692) и записью сомнительных ключей в реестр я не обнаружил их последующего чтения ни установкой бряков на соответствующих апи, ни с помощью RegMon'а (разумеется, все тестировалось после повторной загрузки программы)! Оказалось, что причиной тому был нижеприведенный участок кода:

Код:
seg000:00425D99                 call    esi ; DialogBoxParamA ; Create a modal dialog box from a
seg000:00425D99                                         ; dialog box template resource
seg000:00425D9B                 mov     edi, eax
seg000:00425D9D
seg000:00425D9D loc_425D9D:                             ; CODE XREF: sub_425C59+12Dj
seg000:00425D9D                 cmp     edi, 3EBh
seg000:00425DA3                 jnz     short loc_425DAA ; jmp если не вводились рег.данные
seg000:00425DA5                 call    sub_425228      ; CreateProcessA
seg000:00425DAA
seg000:00425DAA loc_425DAA:                             ; CODE XREF: sub_425C59+14Aj
seg000:00425DAA                 mov     eax, edi
seg000:00425DAC
seg000:00425DAC loc_425DAC:                             ; CODE XREF: sub_425C59+178j
seg000:00425DAC                 pop     edi
seg000:00425DAD                 pop     esi
seg000:00425DAE                 pop     ebx
seg000:00425DAF                 leave
seg000:00425DB0                 retn
Т.е., после ввода рег.данных, главное окно приложения просто дезактивировалось и приложение закрывалось. Но самое интересное, что до этого (.00425DA5) шел вызов функции, которая создавала новый процесс-копию только что запущенного нами процесса-жертвы(аля CopeMemII армы, хотя процессу взлома этот финт, по-моему, никакой сложности не прибавил, кроме как необычности). Вот кусок кода процедуры sub_425228, котоый это подтверждает.

Код:
seg000:00425278                 lea     eax, [ebp+ProcessInformation]
seg000:0042527B                 mov     [ebp+StartupInfo.cb], 44h
seg000:00425282                 mov     [ebp+StartupInfo.dwFlags], 40h
seg000:00425289                 push    eax             ; lpProcessInformation
seg000:0042528A                 lea     eax, [ebp+StartupInfo]
seg000:0042528D                 push    eax             ; lpStartupInfo
seg000:0042528E                 push    esi             ; lpCurrentDirectory
seg000:0042528F                 push    esi             ; lpEnvironment
seg000:00425290                 push    esi             ; dwCreationFlags
seg000:00425291                 push    esi             ; bInheritHandles
seg000:00425292                 push    esi             ; lpThreadAttributes
seg000:00425293                 push    esi             ; lpProcessAttributes
seg000:00425294                 lea     eax, [ebp+ApplicationName]
seg000:0042529A                 push    esi             ; lpCommandLine
seg000:0042529B                 push    eax             ; lpApplicationName
seg000:0042529C                 call    ds:CreateProcessA
seg000:004252A2                 pop     esi
seg000:004252A3                 leave
seg000:004252A4                 retn
seg000:004252A4 sub_425228      endp
seg000:004252A4
Пролистав код немного выше, я понял почему записаные в реестре рег.данные не считывались при запуске. Оказалось, что при создани процесса создавался уникальный мютекс, который "давал знать" родительскому процессу о том, запущен ли дочерний процесс в качестве "запустить игрушку", или в качестве "проверить корректность рег.данных". Поскольку проверки после ввода имени-кода проходили уже в доцернем процессе, а в OllyDbg их отловить не удавалось (за момент подключения к толькочто созданному процессу все проверки уже были пройденными, а возможности использования достойного ring0-mode отладчика не было), то я решил пойти на некоторую хитрость: модифицировать бинарник исследуемого файла таким образом, чтобы первой из строк его исполняемой функций (например, WinMain) было зацикливания (оппкоды EBFE). Таким образом созданный процесс зациклился и я бы смог подключится к нему вовремя и восстановив оригинальные 2 байта кода спокойно поисследовать нужные участки. Но, к сожалению, пробуя реализовать описанный метод было потрачено полчаса, а дочерний процесс никак не зацикливался! Не желая больше тратить время на нахождение причины (которая, видимо, состояла в дублировании функций Main в жертве) я решил пойти более "традиционным" методом и поставить бряки в родительском процессе на вызов функий TerminateProcess и ExitProcess



Ставим бряки на вызовы функций завершения работы приложения

Запускаем на выполнение наш файл, вводим необходимые рег.данные (я вводил имя: ProTeuS и код: 1234567890abcdeABCDE) и без проблем получаем искомую точку (.44А841)



Обнаружение точки вызова функции завершения работы приложения

поднявщись на несколько уровней вверх по структуре дизассемблерного листинга в IDA видим такой код: