• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Реверс-инжиниринг для начинающих [Часть 3 \ -EXE-]

-EXE-

RAID-массив
Пользователь
Регистрация
07.08.2022
Сообщения
55
Реакции
349
Ч-3.png

В продолжении цикла статей, Реверс-инжиниринг для начинающих, представляю Вам - 3 часть. В нашем реверс Меню сегодня это программа Http Master 5.6.1 (Актуальная версия, на момент написания этой статьи). Вы можете сами убедится посмотрев на историю версий (Обновлений с официального сайта): https://www.httpmaster.net/history

И сегодня рассмотрим не только алгоритм действий защиты программы, делая различные манипуляции, правки с кодом а и рассмотрим принцип локализации программы на нужный, Вам, язык. При работе, бывает, что есть хорошая программа но вот нужного Вам языка для неё не существует - по стандарту, что для большинства пользователей есть не очень удобно. И тогда, мы начинаем искать аналог или же соглашаемся с реальностью и работает с чем есть. Способов перевода (локализации программ) есть не мало, сегодня проделаем, как раз, один из них. Но Всему свое время, что бы не затягивать тему, стартуем ! :cool:.

Обычно я делаю так, если есть возможность посмотреть, вкратце, что собой представляет защита, на официальном ресурсе (хоть какое то описание или упоминание о ограничениях) то я так и делаю, смотрю (чтобы облегчить себе задачу). Заходим по ссылке, на оф. сайт программы https://www.httpmaster.net/compare . Тут нам разработчик, любезно, предоставляет сравнение различий между Бесплатной и Профессиональной версией. Уже что то есть и Мы, как минимум, понимаем
что сумма в 99$ (для одного пользователя) за лицензию, для такой программы, это очень много.

И уже по стандартному принципу, сначала определим на чем написана программа (перетащив на утилиту ExeInfo PE (Принцип работы утилиты можно прочитать в предыдущих моих статьях), её разрядность и есть ли какой упаковщик (протектор) что усложнит нам анализ программы. Как бы не так, условно говоря и не такое видели. И вот тут как обычно, по стандарту, Видим:

р-1.jpg

  1. Тут у нас исполняемый файл, его имя: HttpMaster.Windows.exe
  2. Разрядность (ВНИМАНИЕ!): А вот разрядность системы не смогла определить программа ExeInfo PE.
  3. На сем написана программа( то есть Язык программирования) и есть ли обфускация или упаковка (сжатие): Язык С# а вот упаковщика или дополнительной защиты нет, но это еще ни о чем не говорит.
  4. Рекомендации: Для отладки файла утилита предлагает использовать Net Reflector, версии 11. Кому как удобно, дело и свободный выбор каждого.
Но так как утилита ExeInfo PE не смогла определить разрядность установленной программы, то при установке Мы видим что по стандарту (При установке на X64 систему Windows) нам предложена установка в C:\Program Files (x86)\HttpMaster\ (Everyone и Just me, установка для Всех или для одного (конкретного) пользователя). А выходя их этого можем сделать Вывод что программа у нас x32 и для отладки (анализа) будем использовать отладчик x32 - DnSpy. Выходя чисто из логики, сделали такой Вывод, продолжаем далее.

р-2.jpg

Но сначала давайте запустим программу и посмотрим на её внешний вид и посмотрим на информацию и поля вызова активации лицензии, мало ли что а может информация будет полезной. Запускаем программу и видим что программа далее не идет а в замен нам предлагают два режима запуска, первый это триальный (режим для ознакомления с программой, с ограниченными функциями). И второй режим, активируется только в том случае если Вы купили данные активации - регистрационное имя и ключ. А в этот раз мы поступим проще и просто выберем режим триал и запустимся в нем.

zapusk-1.jpg

Запуск в триальном режиме и посмотрев в меню Help - License Data (информацию о лицензии). И сразу становится ясно что нет ключа, нет дополнительных функций. Обидно, досадно но сейчас разберемся ;) , выглядит все это дело вот так.

zapusk-2.jpg


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

А поскольку, вот как 7 дней DnSpy обновился https://github.com/dnSpyEx/dnSpy/releases/tag/v6.3.0-rc1 до версии 6.3.0-rc1 то мы будет использовать актуальную версию отладчика ;). Закидываем нашу программу в отладчик, перетащив файл HttpMaster.Windows.exe. И сразу же переходи в точке входа программы, нажав на HttpMaster.Windows.exe правой кнопкой мыши.

р-3.jpg


И наш отладчик перемещается в class Program - метод private static void Main(string[] args) и давайте посмотрим что тут происходит.

р-4.jpg


Полный код для наглядного примера, чтобы легче было воспринимать статью.
C#:
private static void Main(string[] args)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.ApplicationExit += Program.OnApplicationExit;
            Application.ThreadException += Program.OnThreadException;
            SettingsManager settingsManager = new SettingsManager();
            int num = 1;
            do
            {
                try
                {
                    settingsManager.CreateSettings();
                    AppData.ApplicationSettings = settingsManager.GetSettings();
                    num += 2;
                }
                catch (Exception)
                {
                    settingsManager.DeleteSettingsFile();
                    num++;
                }
            }
            while (num <= 2);
            if (AppData.ApplicationSettings == null)
            {
                MessageBox.Show(string.Format(Messages.readSettingsError, settingsManager.GetSettingsFolder()), "HttpMaster", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                Application.Exit();
                return;
            }
            if (AppData.ApplicationSettings.SupportInternationalDomainNames)
            {
                try
                {
                    OtherUtils.EnableInternationalSupport(true);
                }
                catch (Exception ex)
                {
                    if (AppData.ApplicationSettings.LogUnhandledError)
                    {
                        Program.WriteToLog(ex.GetType().ToString(), ExceptionUtils.CombineExceptionMessage(ex), ex.StackTrace);
                    }
                }
            }
            if (AppData.ApplicationSettings.DefaultViewer == GlobalValues.PrettyViewEnum.Browser)
            {
                AppData.ApplicationSettings.DefaultViewer = GlobalValues.PrettyViewEnum.Auto;
            }
            AppProcedures.SetScalingValues();
            RegistrationManager registrationManager = new RegistrationManager();
            bool flag = false;
            if (registrationManager.NewLicenseKeyExists())
            {
                flag = true;
                registrationManager.DeleteOldLicense();
            }
            else if (registrationManager.OldLicenseKeyExists() && registrationManager.ConvertLicense())
            {
                flag = true;
                registrationManager.DeleteOldLicense();
            }
            if (!flag)
            {
                using (RegistrationForm registrationForm = new RegistrationForm())
                {
                    registrationForm.HeaderTitle = TextManager.GetFormHeaderTitle(registrationForm.Name);
                    registrationForm.ShowDialog();
                    if (!registrationForm.AllowToContinue)
                    {
                        Application.Exit();
                        return;
                    }
                    AppData.Licensed = registrationForm.LicenseSuccessful;
                    goto IL_175;
                }
            }
            AppData.Licensed = true;
            IL_175:
            string text = string.Empty;
            string text2 = string.Empty;
            bool flag2 = true;
            foreach (string text3 in args)
            {
                if (File.Exists(text3))
                {
                    string extension = Path.GetExtension(text3);
                    string text4 = ".hmpr";
                    string text5 = ".hmex";
                    if (string.Compare(extension, text4, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        text = text3;
                        flag2 = true;
                        break;
                    }
                    if (string.Compare(extension, text5, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        text2 = text3;
                        flag2 = true;
                        break;
                    }
                }
                flag2 = false;
            }
            if (!flag2)
            {
                MessageBox.Show(Messages.invalidStartArgument, "HttpMaster", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                Application.Exit();
                return;
            }
            MainForm mainForm = new MainForm();
            if (!AppProcedures.SetFormSize(mainForm))
            {
                mainForm.WindowState = FormWindowState.Maximized;
            }
            if (string.IsNullOrEmpty(text) && string.IsNullOrEmpty(text2))
            {
                if (!AppData.ApplicationSettings.ShowWelcomeForm && AppData.ApplicationSettings.OpenLastProject)
                {
                    string text6 = AppProcedures.DetermineProjectFilePath(0);
                    if (!string.IsNullOrEmpty(text6))
                    {
                        mainForm.OpenProjectFileArgument(text6);
                    }
                }
            }
            else
            {
                mainForm.HmprArgument = text;
                mainForm.HmexArgument = text2;
                if (!string.IsNullOrEmpty(text))
                {
                    mainForm.OpenProjectFileArgument(text);
                }
            }
            Application.Run(mainForm);
        }
    }
}

Пролистав немного ниже мы видим кусок кода, своего рода конструкцию. И в нем методы NewLicenseKeyExists и DeleteOldLicense; Понимаете направление мысли :cool:, уже что то нашли что связано с лицензией, но нужно еще посмотреть что происходит внутри. Так как бывают (конструкции кода, что по первых кажутся простыми а на самом деле все не так просто как нам казалось. DeleteOldLicense Сам за себя говорит и нам это не так интересно, что то связано с удалением старой лицензии, можем предположить что это деактивация уже имеющиеся лицензии. А вот NewLicenseKeyExists это уже более интересней

Кусок кода, что очевидно наст интересует.
Код:
RegistrationManager registrationManager = new RegistrationManager();
    bool flag = false;
    if (registrationManager.NewLicenseKeyExists())
    {
        flag = true;
        registrationManager.DeleteOldLicense();
    }
    else if (registrationManager.OldLicenseKeyExists() && registrationManager.ConvertLicense())
    {
        flag = true;
        registrationManager.DeleteOldLicense();
    }

р-5.jpg


Давайте же перейдем в NewLicenseKeyExists и посмотрим что у нас там спрятаны за сюрпризы, а может какой то универсальный метод проверок или не ломаемый алгоритм :D. Для этого жмем левой кнопкой мышки по NewLicenseKeyExists.

р-6.jpg


И после этого нам становится доступный вот такой кусок кода. В котором проверяются значения в реестре Windows и если их там нет то результат нам возвращается как False - то есть запретить (нет) а если даже есть какое-то значение то тут уже идут криптографические вычисления (Магия одним словом от разработчика :D). Ковырять такое и разбираться в том мега - крутой криптографии это себе дороже по времени и не имеет никакого смысла когда можно поступить в разы проще, быстрее и радикальней, даже и не парится.

р-7.jpg


C#:
public bool NewLicenseKeyExists()
        {
            string text = RegistryUtils.GetRegistryKey("Software\\Borvid\\HttpMaster", "Id");
            if (string.IsNullOrEmpty(text))
            {
                return false;
            }
            text = EncryptionUtils.Decrypt(text);
            this.LicenseKeyUsed = text;
            return new EncryptedLicenseProvider("<EncryptedLicenseParameters>\r\n\t          <ProductName>HttpMaster Professional 2</ProductName>\r\n\t          <RSAKeyValue>\r\n\t            <Modulus>hQQnn6qzLcZdZPFiCcodmOnnEY/OWaM9DQUFKB8EMBndDF/TvgPduwO2vpClJ7qrf7f8sUuEGcGTjyZfcbverN2JaUynGPCXT1/lBDMMoRnbQmbr2qwVWS/cZBPR4s/4OyAM+mbKfc+OsUoUhHY4jYqf00in2XJQoVc8fXtbdic=</Modulus>\r\n\t            <Exponent>AQAB</Exponent>\r\n\t          </RSAKeyValue>\r\n\t          <DesignSignature>CHiUADfZeCEbMXEd87J+eusIYl8UyoMp9X7Fw17BwVwMCGyjarSCF66NwqOmxI6VWJR3lSRR1BOU8Z92PFE1OdApmhyE70dOuFNtEHfy69oH1zB2fHyy+S5fx3w2WHczExSVIGq43MJaJ06D6t4sz7ZL790PbviuLZIyDfAlBYQ=</DesignSignature>\r\n\t          <RuntimeSignature>SV7vYU99/VR0R/rfj5eDdiM96V1OKyMrkqUS962XiC33Y+JPi6GGLU9XDcMiq37CWV8Pi+pR+buNbbOq9tSF6Z8+xGHyYU+VKdIDfkpmxKsgVMQAJ8vfPZoVOAceB/sid6KQyxdZlAKMX1mMo+/FXHwZ2anHHbjDarQUWPGCG4A=</RuntimeSignature>\r\n\t          <KeyStrength>7</KeyStrength>\r\n\t        </EncryptedLicenseParameters>", string.Empty).ValidateLicenseKey(text) != null;
        }

Обратите ВНИМАНИЕ: Что вызов NewLicenseKeyExists идет из динамической библиотеки HttpMaster.Engine.dll что расположена рядом с основным файлом программы HttpMaster.Windows.exe. Это можно легко понять посмотрев в отладчике. То есть своего рода конструкция где из основного файла программы идет загрузка проверочных функций из dll, если уже просто говорить.

dll-1.jpg


Что тут можно сделать ? Да все очень просто, можно сделать так что бы функция постоянно возвращала True, при любом исходе. А всю криптографическую проверку вырезать и на этом точка :D. Для этого нажимаем правой кнопкой по функции и в меню выбираем изменить метод.

р-8.jpg


В итоге весь код проверки превратится в одну строку return true; и выглядеть будет вот так:

р-9.jpg


И теперь сохраняем наши изменения уже в HttpMaster.Engine.dll (Файл динамической библиотеки). Давайте запустим программу и посмотрим что у нас получилось. Окно с просьбой активировать программу пропало, программа запустилась в профессиональном режиме. Но вот есть одно но, если зайти в меню Help - License Data что бы посмотреть информацию о лицензии. То тут картина отображается не очень красивая, у нас возникло исключение в виде ошибки и оно отображается и режет глаз. :cool:. Понятно что и при таком раскладе программа будет работать идеально но смотрится не красиво и давайте это исправим.

р-10.jpg


Вернувшись в начало и воспользовавшись или поиском к примеру Licenseinfo или визуально, мы находим функцию, место где именно Вызывается NewLicenseKeyExists
и в зависимости от результата отображается в Информации о лицензии. Вот это место :D нам и нужно было найти.

То есть:
C#:
public LicenseInfoForm()
{
    this.InitializeComponent();
    RegistrationManager registrationManager = new RegistrationManager();
    if (registrationManager.NewLicenseKeyExists())
    {
        this.licenseKeyLabel.Text = string.Format(this.licenseKeyLabel.Text, registrationManager.LicenseKeyUsed.Substring(0, 5) + " ...");
        this.deleteLicensePanel.Visible = true;
        this.purchaseButton.Visible = false;
        this.okButton.Visible = false;
        this.cancelButton.Text = FormStrings.closeButton;
        return;
    }
    this.addLicensePanel.Visible = true;
}

р-11.jpg


Что же делать далее ? Да ничего такого особо сложного а именно поле this.licenseKeyLabel.Text = и отвечает за Вывод данных в программу в меню Help - License Data.
А поскольку программу мы уже вылечили то это поле мы можем заполнить любыми произвольными данными и на работу программы уже это никак не повлияет. Давайте туда впишем, к примеру, вот такой текст "Зарегистрировано на -EXE- что на форуме xss.pro";. То есть полный код будет выглядеть вот так:

C#:
public LicenseInfoForm()
{
    this.InitializeComponent();
    if (new RegistrationManager().NewLicenseKeyExists())
    {
       // То есть вот тут добавили вывод наших данных, авторства.
        this.licenseKeyLabel.Text = "Зарегистрировано на -EXE- что на форуме xss.pro";
        this.deleteLicensePanel.Visible = true;
        this.purchaseButton.Visible = false;
        this.okButton.Visible = false;
        this.cancelButton.Text = FormStrings.closeButton;
        return;
    }
    this.addLicensePanel.Visible = true;
}

р-12.jpg


Сохраняем результат и смотрим что у нас получилось. Запускаем программу и заходим в меню Help - License Data и видим как у нас красуется наш надпись. Это уже более солидней смотрится, согласитесь ? :cool:


р-13.jpg

Можно пойти далее и прописать свое авторство или произвольный текст в названии самой программы, в главной форме. Как это сделать ? Да все просто. Как мы знаем, все текстовые переменные что касаются названия окон, полей и не только присваиваются в основной форме программы. Для того что бы найти нужную нам строку в отладчике переходим на MainForm и ищем слово Professional так как оно отображается в названии программы.

р-14.jpg


После чего редактируем название программы как Вам угодно, можете добавить любой текст. К примеру давайте допишем туда вот такой текст (Статья для форума xss.pro от -EXE-). Нажимаем правой кнопкой мышки и выбираем изменить IL инструкцию, добавляем текст и сохраняем.

iL.jpg



Ну и как Вам такой вариант, смотрится тоже ничего. Пользователь запустив программу сражу же увидит кто её отреверсил ;). Ну а что если уж показывать крякинг программы то и такие мелочи тоже пригодятся на будущее. В итоге программу Мы вылечили, навели красоту, на этом по крякинге данного софта все. А в целом не все идем дальше.

р-15.jpg

Давайте я теперь покажу как можно локализировать софт на нужный Вам язык, если есть в этом надобность. Ну бывает же такое что вот глаза режет если в программе только английский язык и все. Так вот сейчас посмотрим способ как это сделать прямо с отладчика, не выходя из дома :cool:.давайте запустим программу и посмотрим на меню File. Мы видим что изначально все меню как и программа на английском языке, вот давайте же найдем это меню в структуре кода и переведем несколько пунктов на русский.

р-16.jpg

Для этого поиском по MainForm ищем к примеру названия меню New Project. Тут нам главное только зацепится и найти хотя бы один пункт а где один там и остальные, поверьте мне. И о чудо находим желаемый текст. Видим группы меню и их структуру. Ну и теперь давайте же изменим несколько значений и посмотрим что у нас получилось.

р-17.jpg


Для этого нажимаем правой кнопкой мышки и выбираем изменить метод. Правим нужный нам текст, переводим на русский и нажимаем Компилировать.
р-18.jpg


После чего у нас получается уже версия программы с изменениями. И нам осталось только сохранить результат в готовый exe файл и посмотреть на результат, запустив программу.

р-19.jpg


Сохраняем программу, в отладчике файл - сохранить все и запускаем программу. И смотрим что у нас получилось. А получилось у нас то что мы перевели строки на русский с английского, что есть очень хорошо, разве я не прав ?. Ну и так при надобности можно перевести (локализировать) программу на нужный Вам язык.

р-20.jpg

Ну что, немного подведём итоги.
В этой статье мы рассмотрели защиту очередной программы. Из статьи освоили некие нюансы, а именно что защита софта может вызываться (проверятся) не только из основного файла а также из вспомогательных файлов, динамических библиотек. Может и подход от части правильный, но создавая какие проверки, разработчик, прежде всего должен подумать, запрограммировать не стандартный способ (алгоритм) защиты. Мыльные пузырки раздувать не будем :cool: , поскольку все видели как я обошел защиту. Так это только один из способом, показанный, грубо говоря на пальцах.

На этом я не останавливаюсь, каждая статья будет равна поломанной душе программы ;). Ну и всем приятного освоения, практикуйте и современен у Вас все получится, от себя желаю только Успехов! ;). Да простите меня разработчики софтов :D.

Что в архиве, скриншот:
р-21.jpg



Наш пациент (Http Master 5.6.1): https://www.virustotal.com/gui/file/a7b972fc34f3ad02d4d3409096c2049e29cdf732718ee63ce1fdab2f19ac8baa
dnSpy x32 / virustotal:
https://www.virustotal.com/gui/file/7ce05f1aafaaa87d046bbad1b07801777e724251b084bc7f70cef71c98b08105
dnSpy x64 / virustotal: https://www.virustotal.com/gui/file/cc15f3f7836f5c976e058aabdd55af8635b484a6b9a5e94a2cb048856965f9e2
ExeinfoPe / virustotal: https://www.virustotal.com/gui/file/32e6df44a529d3bd543aae01365852990c0e7f3b4f84b5a7f9d7dfc18d6a46fd

Файлы к статье:
Скрытый контент для зарегистрированных пользователей.
 

Вложения

  • р-1.jpg
    р-1.jpg
    43.6 КБ · Просмотры: 35


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх