1. Вы находитесь в архивной версии форума xaker.name. Здесь собраны темы с 2007 по 2012 год, большинство инструкций и мануалов уже неактуальны.
    Скрыть объявление

Взлом (Cracking) IcoFX v2.0

Тема в разделе "Исследование софта на уязвимости, crackme", создана пользователем Dr. MefistO, 6 сен 2011.

  1. Dr. MefistO

    Dr. MefistO Крывіч Глобальный модератор

    Регистрация:
    3 авг 2008
    Сообщения:
    152
    Симпатии:
    254
    Баллы:
    0
    [​IMG]

    Доброго утра/дня/вечера/ночи, ребята!

    Сегодня я расскажу о совсем не сложном взломе программы для работы с иконками - IcoFX v2.0. Изменять придется всего семь байт (две строчки в отладчике)! А расценки такие:
    2 строчки кода = 59$
    Не дешево!

    В общем, поехали...

    Открывайте IDR, и грузите в него файлик IcoFX2.exe. Подождем окончания анализа.

    Первой при запуске программы появляется splash-заставка, с надписью Unregistered, но я не буду ковырять ее код.
    [​IMG]

    Я начну с самого главного - формы регистрации, и ввода лицензионного ключа.
    Попробуйте запустить программу, глянуть на это окошко, и вы увидите, что кнопка Register недоступна!
    [​IMG]

    Пробуем что-нибудь ввести в оба поля, и увидим, что кнопка все равно не активируется. Нам же легче!

    Ищем среди списка форм программы в IDR TFRMREGISTER. Это форма регистрации. Включаем режим просмотра формы:
    [​IMG]

    Увидим такую вот форму:
    [​IMG]

    Странно, но второго поля для ввода ключа здесь не видно, только надпись KeyEdit1. Это не проблема. Сейчас заодно я и познакомлю вас с алиасами. Это замечательная штука, придуманная автором IDR для удобства отладки приложения, и просмотра форм приложения.

    Под списком форм найдите маленькое окошко со списком компонентов:
    [​IMG]

    И найдите там TKeyEdit. Теперь нажмите двойным щелчком по этой строке. В появившемся поле исправьте текст TPanel на TEdit, как показано на картинке:
    [​IMG]

    и нажмите ОК. Как видите, форма преобразилась:
    [​IMG]

    На заметку: алиасами можно пользоваться, например, в приложениях, где много скинированых форм, и нужные вам кнопки, эдиты не находятся на глаз!

    Теперь ищем на этой форме компонент TTimer:
    [​IMG]

    Жмем правой кнопкой мыши, и выбираем OnTimer:
    [​IMG]

    Почти внизу видим:
    Код:
     0068639B    mov        dl,1
     0068639D    mov        eax,dword ptr [ebx+370]; TfrmRegister.btnRegister:TButton
     006863A3    mov        ecx,dword ptr [eax]
     006863A5    call       dword ptr [ecx+68]; TControl.SetEnabled
    Это код установки доступности, либо недоступности кнопки. Приблизительно, здесь происходит следующее: проверяется введенный ключ, и, если он гуд, выставляется флаг доступности кнопки на 1, иначе - 0.

    Как выяснилось, по умолчанию кнопка Register активна, но по таймеру каждый раз проверяется код, и кнопка становится неактивной. А мы возьмем, да и проскочим место проверки пароля, и сразу установим доступность кнопки.

    Найдите первый условный прыжок (JE - 00686386) в этой процедуре. Давайте поменяем его на безусловный прыжок сразу на вышеуказанный код установки активности кнопки.

    Для этого загрузим программу в отладчик (я использую Olly Debugger v2), нажмем комбинацию клавиш Ctrl+G и введем адрес перехода, подсмотренный в IDR - (00686386), нажмем ОК. Двойным щелчком по строке с переходом мы вызовем окно изменения команды:
    [​IMG]

    Измените появившуюся в поле ввода команду на команду, указанную на скрине:
    (JMP SHORT 0068639B - слово SHORT можно не писать).
    Нажмите Assemble.

    Как бы все хорошо, программа принимает введенные вами данные, регистрируется, но, при закрытии программы, все равно вылезает окно регистрации. Исправим...

    Ищем в списке форм TFRMMAIN. Нам нужен его FormClose. Сейчас мне очень тяжело пояснить - как же я попал в код FormClose - плохо, что у IDR нет мануала, но:
    адрес этой процедуры = 0068F5EC.

    Добавлено позже - замечание автора IDR: Еще есть фишка такая, как клавиша F11 на открытой форме. Там можно найти искомый FormClose.

    Код:
     0068F5EC    call       00691814
     0068F5F1    ret
    
    Здесь мы видим вызов процедуры по адресу: 00691814. Переходим туда двойным щелчком.

    Переходов здесь никаких нет, одни вызовы (CALL). Смотрим в IDR вызовы, не определенные как функции Delphi. Смотрим первый (call 00669CE8) - ничего подозрительного, смотрим второй (call 00691AC0).... Ага!

    Старый знакомый CheckKey. Значит все просто - не будем вызывать эту процедуру. Как это сделать?
    Открываем отладчик, переходим по адресу 0069183A - это адрес по которому происходит call 00691AC0.

    Теперь жмем правой кнопкой на этой строке, там меню Edit->Fill with NOPsOlly Debugger v1 - Binary->Fill with NOPs). Теперь сохраняем изменения в файл (Copy To Executable). Если после успешной регистрации будет выскакивать при открытии программы окно ввода пароля, в отладчике жмем Ctrl+F, и ищем:
    (call 00691AC0) Тоже заменяем NOPами. Это Все!!!

    [​IMG]
    Взлом программы завершен!

    Всем спасибо за внимание...
    Автор: Владимир Мефисто;


    Для конкурса статей.
     
    Последнее редактирование: 7 сен 2011
    3 пользователям это понравилось.
  2. Dr. MefistO

    Dr. MefistO Крывіч Глобальный модератор

    Регистрация:
    3 авг 2008
    Сообщения:
    152
    Симпатии:
    254
    Баллы:
    0
    Очень жадная контора, оказалось.
    Ну да ладно. Думал, у них хоть алгоритм ключей серьезный, так там ситуация не лучше. Алгоритм подобрал за 20 минут.

    Выкладываю функции, отвечающие за генерацию ключа:
    Код:
    function GetNumCheckSum(const Str: string): word;
    var
      i: byte;
      AX, CX: cardinal;
    begin
      AX := $AF;
      CX := $56;
      
      for i:=1 to Length(Str) do
      begin
        AX := (AX + Ord(str[i]));
        if AX > $0FF then AX := AX - $0FF;
        CX := (CX + AX);
        if CX > $0FF then CX := CX - $0FF;
      end;
      CX := (CX shl 8);
      AX := (AX + CX);
      CX := AX mod $B63F;
      Result := CX;
    end;
    function GetStrCheckSum(Num: word): string;
    const
      alpha = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    var
      CX, AX: word;
      s: string;
    begin
      Result := '';
      s := '';
      CX := Num;
      AX := 1;
      while AX>0 do
      begin
        AX := CX mod $24 + 1;
        s := alpha[AX];
        result := s + result;
        AX := CX div $24;
        CX := AX;
      end;
    end;
    В первую функцию нужно передать любые 22 символа. Полученную сумму нужно передать во вторую функцию, и мы получим из нее 3 символа, которые в сочетании с первыми 22-мя символами и будут лицензионным ключом на любое имя.

    Пример:
    Код:
    sum22 := GetNumCheckSum('ABCDEFGHIJKLMNOPQRSTUV');
    resultkey := 'ABCDEFGHIJKLMNOPQRSTUV' + GetStrCheckSum(sum22);
     

Поделиться этой страницей