Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 12 ноября!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

Text Log Monitor 1.0.0.17: Вечный триал

Обсудить статью на форуме

Хорошая подборка видеоуроков, инструментов крэкера, книг и статей - здесь.

Автор: RedAbishai <RedAbishai@tut.by>

Text Log Monitor 1.0.0.17: Вечный триал
(программа находится по адресу hттp://www.diskmonitor.com, [64.106.248.15])
Инструменты: FAR, HIEW, IDA.

1. Краткое описание.


Text Log Monitor - это программа для сбора, анализа и просмотра различного рода журналов операционных систем, серверов баз данных и т.д. и т.п. Теоретически может представлять интерес для системных и сетевых администраторов (практически, как выяснилось, довольно тормознутая вещь, хотя для постоянного наблюдения за журналами может пригодиться).

2. Предварительный осмотр.


Размер дистрибутива - 1696 килобайт, размер папки с установленной программой - 2423 килобайт. Написана под .NET, поэтому можно смело прибавить размеры дистрибутива .NET. После первого запуска программа просит регистрации на сайте, при последующих запусках выводит краткое сообщение:

"You have 20 (19,18 и т.д.) trial days left.

Once the trial period expires, you will no
longer be able to use this software.

Would you like to register this software now?"

После успешной регистрации файл лицензии, привязанный к MAC-адресу сетевой карты, высылается конторой-изготовителем программы на указанный в ходе регистрации email. Существуют три типа лицензии:

Desktop - для Windows Vista, XP, 2000 и наблюдения за 20 журналами.
Server - для Windows Server 2003, 2000, Windows Vista, XP, 2000 и 50 журналов.
Server Unlimited - для Windows Server 2003, 2000, Windows Vista, XP, 2000 и неограниченного количества журналов.

3. Начало анализа.


Поиск в каталоге программы файлов со словом "trial" (можно искать в FAR, сразу в двух кодировках - Windows и Unicode) выводит нас на cblib.dll, в которой в Unicode в открытом виде содержится вышеупомянутое триальное сообщение. Запускаем IDA, она нас обрадует, что этот файл - сборка .NET, и бодро проведет дизассемблирование. Ищем по дизассемблированному тексту все тот же "trial", по адресу 1A4BE попадаем на сообщение "Your trial period has expired. Would you like to register this software now?", ниже по тексту - искомое " trial days left". Вот код функции целиком (я дал ей говорящее само за себя имя ShowNagScreen):

  .method private static hidebysig bool a(class
[System.Windows.Forms]System.Windows.Forms.IWin32Window A_0, int64 A_1)
                                        // CODE XREF: sub_1A1E0+180p sub_1A1E0+210p
  {
    .locals init (value class [mscorlib]System.DateTime V0,
                  class w V1,
                  value class [mscorlib]System.DateTime V2)
                ldarg.1
                ldc.i4.0
                conv.i8
                bne.un.s loc_1A4A4
                call    value class [mscorlib]System.DateTime [mscorlib]System.DateTime::get_Now()
                stloc.2
                ldloca.s 2
                call    int64 [mscorlib]System.DateTime::get_Ticks()
                starg.s 1

loc_1A4A4:                              // CODE XREF: ShowNagScreen+3j
                ldloca.s 0
                ldarg.1
                call    void [mscorlib]System.DateTime::.ctor(int64)
                ldloc.0
                newobj  void w::.ctor(value class [mscorlib]System.DateTime A_0)
                stloc.1
                ldloc.1
                callvirt int32 w::c()   // get number of trial days left
                ldc.i4.0
                bgt.s   l_1A4D3_nag
                ldc.i4.6
                ldarg.0
                ldstr   "Your trial period has expired. Would you like to register this software now?"
                call    value class [System.Windows.Forms]System.Windows.Forms.DialogResult q::d
(class [System.Windows.Forms]System.Windows.Forms.IWin32Window A_0, class System.String A_1)
                beq.s   l_1A4CC_register
                ldc.i4.0
                ret

l_1A4CC_register:                       // CODE XREF: ShowNagScreen+38j
                ldarg.0
                call    bool b::a(class [System.Windows.Forms]System.Windows.Forms.IWin32Window A_0)
                ret

l_1A4D3_nag:                            // CODE XREF: ShowNagScreen+2Aj
                ldloc.1
                stsfld  class w b::c
                ldc.i4.6
                ldarg.0
                ldstr   "You have "
                ldloc.1
                callvirt int32 w::c()   // get number of trial days left
                box     [mscorlib]System.Int32
                ldstr   " trial days left.rnrnOnce the trial period expires, you will no rnlonger be able to
use this software.rnrnWould you like to register this software now?"
                call    class System.String [mscorlib]System.String::Concat
(class System.Object, class System.Object, class System.Object)
                call    value class [System.Windows.Forms]System.Windows.Forms.DialogResult q::d
(class [System.Windows.Forms]System.Windows.Forms.IWin32Window A_0, class System.String A_1)
                bne.un.s l_1A503_exit_1
                ldarg.0
                call    bool b::a(class [System.Windows.Forms]System.Windows.Forms.IWin32Window A_0)
                pop

l_1A503_exit_1:                         // CODE XREF: ShowNagScreen+6Aj
                ldc.i4.1
                ret
  }

Видим проверку на истекший триал (вызов функции w::c и условный переход по результату сравнения с нулем):

                callvirt int32 w::c()   // get number of trial days left
                ldc.i4.0
                bgt.s   l_1A4D3_nag

Видим вставку количества оставшихся дней в триальное сообщение:

                ldstr   "You have "
                ldloc.1
                callvirt int32 w::c()   // get number of trial days left
                box     [mscorlib]System.Int32
                ldstr   " trial days left.rnrnOnce the trial period expires, you will no rnlonger be able to
use this software.rnrnWould you like to register this software now?"

Видим, что возвращаемый методом результат - булевский (IDA назвала его .method private static hidebysig bool a), а фактически - 0 или 1:

                ldc.i4.0
                ret
...
l_1A503_exit_1:                         // CODE XREF: ShowNagScreen+6Aj
                ldc.i4.1
                ret

Далее проанализируем вызываемую функцию w::c (чтобы было удобнее ориентироваться в IDA, я дал ей имя GetDaysLeft, находится по адресу 6D60, смещение в файле 7B28):

GetDaysLeft:                            // CODE XREF: sub_11610+13p ShowNagScreen+24p
                                        // ShowNagScreen+51p
  .method public hidebysig specialname int32 c() // get number of trial days left
  {
    .locals init (value class [mscorlib]System.TimeSpan V0)
                ldarg.0
                ldflda  value class [mscorlib]System.DateTime w::z
                call    value class [mscorlib]System.DateTime [mscorlib]System.DateTime::get_Now()
                call    value class [mscorlib]System.TimeSpan [mscorlib]System.DateTime::Subtract
(value class [mscorlib]System.DateTime)
                stloc.0
                ldloca.s 0
                call    int32 [mscorlib]System.TimeSpan::get_Days()
                ldc.i4.0
                ble.s   loc_6D83
                ldloca.s 0
                call    int32 [mscorlib]System.TimeSpan::get_Days()
                ret

loc_6D83:                               // CODE XREF: seg000:6D79j
                ldc.i4.0
                ret
  }

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

  .method public hidebysig specialname int32 c() // get number of trial days left
  {
    .locals init (value class [mscorlib]System.TimeSpan V0)
                ldc.i4.1
                ret
  }

и она всегда будет убежденно отвечать, что у нас остался еще один день испытательного срока. Соответственно, вот diff для внесения изменений в файл:

00007B28: 02 17
00007B29: 7C 2A

В принципе, байт-код позволяет и бОльшее число, например, если вписать 1C вместо 17 - будет инструкция ldc.i4.6 и 6 дней соответственно, можно вписать инструкцию ldc.i4.s 16 (байт-код 1F 10) - будет 16 дней:

00007B28: 02 1F
00007B29: 7C 10
00007B2A: DA 2A

Проверяем - работает, программа действительно говорит, что у нас "1 trial days left". Хорошим признаком является то, что на внесенное изменение программа не ругается - значит самоконтроля нет (или он спрятан - при построении защиты плохим тоном считается сразу же после проверки выбрасывать ругательные сообщения типа "Регистрационный код неверен!", "Программа несанкционированно изменена!" и т.д.). Теперь можно прибить надоедающий триальный диалог. Как вариант - подправить переход по адресу 1A4BA (смещение 1AF36):

                callvirt int32 w::c()   // get number of trial days left
                ldc.i4.0
                bgt.s   l_1A4D3_nag

на точку выхода из функции с положительным результатом:

                bgt.s   l_1A503_exit_1

то есть ровно на 0x30 байт:

0001AF37: 17 47

В результате программа стартует молча, но выдает исключение при выборе пункта меню "About" - она не может найти объект лицензии, ведь мы пропускаем запись созданного таким конструктором объекта:

                ldloc.0
                newobj  void w::.ctor(value class [mscorlib]System.DateTime A_0)
                stloc.1

в поле b::c

                ldloc.1
                stsfld  class w b::c

Откатим это неудачное изменение и попробуем вставить безусловный переход непосредственно перед выводом триального диалога:

l_1A4D3_nag:                            // CODE XREF: ShowNagScreen+2Aj
                ldloc.1
                stsfld  class w b::c
                br.s    l_1A503_exit_1

Diff будет таким:

0001AF55: 1C 2B
0001AF56: 02 28

Теперь программа работает устойчиво. Переводим для проверки время на год вперед - тоже работает. Исходная цель достигнута - мы получили бесконечный триал.

4. Домашнее задание.


Желающие запустить данную программу на серверных окнах с обработкой тучи журналов могут продолжить самостоятельно и прибить проверки на разные типы лицензий (функция по адресу 15870 возвращает 1, если программа запущена на сервере, точнее, если в реестре в ветке "SYSTEM\CurrentControlSet\Control\ProductOptions" в ключе ProductType лежит что-то вроде "servernt" или "lanmannt", функция по адресу 60A0 формирует текстовое описание лицензии для диалога About и т.д.), можно пойти другим путем - выяснить формат файла лицензии, и убить проверки на ее правильность, после чего создать универсальный файл неограниченной лицензии. В общем, открыто широкое поле деятельности - программа послушна нашей воле.




Обсуждение статьи: Text Log Monitor 1.0.0.17: Вечный триал >>>


Комментарии к статье: Text Log Monitor 1.0.0.17: Вечный триал

nicedude86 15.01.2009 08:34:57
klassno
---

Материалы находятся на сайте https://exelab.ru



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS