ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2
Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей. Здесь обсуждаются безопасность, программирование, технологии и многое другое. Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Вернуться   Форум АНТИЧАТ > Программирование > Реверсинг
   
 
 
Опции темы Поиск в этой теме Опции просмотра

Введение в .Net Cracking
  #1  
Старый 20.02.2008, 17:22
Аватар для 0x0c0de
0x0c0de
Постоянный
Регистрация: 25.05.2007
Сообщений: 448
Провел на форуме:
4226446

Репутация: 1564
Отправить сообщение для 0x0c0de с помощью ICQ
По умолчанию Введение в .Net Cracking

[.Net Cracking]
Жертва - DVD Cover Searcher. Это .Net приложение, отказывающееся работать без триал-ключа (или фул)

[Introduction]
Что нам потребуется при изучении .Net приложений?

1.MSIL Disassembler (есть в составе Net Framework SDK) – далее просто дизассемблер

Рабочее окно дизассемблера


2. Хекс редактор, любой понравившийся

Основные команды, нам нужные для понимания того, что нам выдал MSIL Disassembler. На эту тему есть неплохой материал (правда на английском). Почитать, интересующимся, можно здесь (MSIL Tutorial)

http://www.codeguru.com/Csharp/.NET/net_general/il/article.php/c4635

По опкодам (просто мего находка)

http://blogs.msdn.com/bluecollar/archive/2006/09/27/773065.aspx

А опкоды будут необходимы для патча.
Кое-что было на краклабе и tuts4you. Однако у меня возникло желание привести пример практический (и, главное, на русском), а не витать в теоретических абстракциях. Сокращенно (очень очень сокращенно) я привожу список команд, нам необходимых

[Commands]
Ldstr строка—загрузка строки в стек

Call функция(аргументы)—вызов функции.

Pop- эквивалентно одноименной команде ассемблера – выталкивание значения из стека

ret—возврат из функции

ldc.i4.n—загрузка 32-битной константы в стек

stloc.n—загрузка значения из стека в переменную

add—сложение двух чисел

sub—вычитание

mul- умножение

br.s метка—безусловный переход по адресу _метка_

Перед исследованием стоит включить показ байтов команд в меню View->Show Bytes (должна стоять галочка). Это нам нужно для того, чтобы найти место патча в хекс-редакторе (я буду использовать hiew, так как привычка). Дизассемблер показывает rva метода, что очень удобно. Например

Код:
// Method begins at RVA 0x13e8cc

В hiew добавить к 13e8cc ImageBase (400000) и получим адрес начала метода. А дальше нужно искать искомую последовательность, которая подвергнется патчу.


[Исследуем]

Теперь загрузим программу в дизассемблер. Цель – убрать злое окно при загрузке.

NagScreen

У нас есть несколько вариантов действий. Запросить триал ключ, ввести рег данные, купить, выйти.

Попробуем пропатчить проверку введенного ключа. Посмотрим какие методы использует frmKeyEntry. Нужный нам метод - cmdUnlock_Click

Код:
.method private instance void  cmdUnlock_Click(object sender,
                                               class [mscorlib]System.EventArgs e) cil managed
// SIG: 20 02 01 1C 12 61
{
  // Method begins at RVA 0x131f84
  // Code size       112 (0x70)
  .maxstack  6
  IL_0000:  /* 28   | (06)00000A       */ call       class DCSP.My.MyProject/MyForms DCSP.My.MyProject::get_Forms()
  IL_0005:  /* 6F   | (06)000010       */ callvirt   instance class DCSP.frmMain DCSP.My.MyProject/MyForms::get_frmMain()
  IL_000a:  /* 6F   | (06)000293       */ callvirt   instance class DCSP.Registration.clsRegistration DCSP.frmMain::get_clsReg()
  IL_000f:  /* 02   |                  */ ldarg.0
  IL_0010:  /* 6F   | (06)0000AE       */ callvirt   instance class [System.Windows.Forms]System.Windows.Forms.TextBox DCSP.frmKeyEntry::get_txtKey()
  IL_0015:  /* 6F   | (0A)000120       */ callvirt   instance string [System.Windows.Forms]System.Windows.Forms.TextBox::get_Text()
  IL_001a:  /* 6F   | (0A)000121       */ callvirt   instance string [mscorlib]System.String::Trim()
  IL_001f:  /* 6F   | (06)00003C       */ callvirt   instance bool DCSP.Registration.clsRegistration::Unlock(object)
  IL_0024:  /* 2D   | 2E               */ brtrue.s   IL_0054
  IL_0026:  /* 02   |                  */ ldarg.0
  IL_0027:  /* 72   | (70)000D16       */ ldstr      "Invalid Serial Key. Please Try Again."
  IL_002c:  /* 72   | (70)000CF4       */ ldstr      "Serial Key Entry"
  IL_0031:  /* 16   |                  */ ldc.i4.0
  IL_0032:  /* 1F   | 40               */ ldc.i4.s   64
  IL_0034:  /* 16   |                  */ ldc.i4.0
  IL_0035:  /* 28   | (06)0003D1       */ call       valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult DCSP.modCenterDialog::Show(class [System.Windows.Forms]System.Windows.Forms.IWin32Window,
                                                                                                                                                  string,
                                                                                                                                                  string,
                                                                                                                                                  valuetype [System.Windows.Forms]System.Windows.Forms.MessageBoxButtons,
                                                                                                                                                  valuetype [System.Windows.Forms]System.Windows.Forms.MessageBoxIcon,
                                                                                                                                                  valuetype [System.Windows.Forms]System.Windows.Forms.MessageBoxDefaultButton)
  IL_003a:  /* 26   |                  */ pop
  IL_003b:  /* 02   |                  */ ldarg.0
  IL_003c:  /* 6F   | (06)0000AE       */ callvirt   instance class [System.Windows.Forms]System.Windows.Forms.TextBox DCSP.frmKeyEntry::get_txtKey()
  IL_0041:  /* 6F   | (0A)000122       */ callvirt   instance void [System.Windows.Forms]System.Windows.Forms.TextBoxBase::SelectAll()
  IL_0046:  /* 02   |                  */ ldarg.0
  IL_0047:  /* 6F   | (06)0000AE       */ callvirt   instance class [System.Windows.Forms]System.Windows.Forms.TextBox DCSP.frmKeyEntry::get_txtKey()
  IL_004c:  /* 6F   | (0A)000123       */ callvirt   instance bool [System.Windows.Forms]System.Windows.Forms.Control::Focus()
  IL_0051:  /* 26   |                  */ pop
  IL_0052:  /* 2B   | 1B               */ br.s       IL_006f
  IL_0054:  /* 02   |                  */ ldarg.0
  IL_0055:  /* 72   | (70)000D62       */ ldstr      "Thank you for registering."
  IL_005a:  /* 72   | (70)000CF4       */ ldstr      "Serial Key Entry"
  IL_005f:  /* 16   |                  */ ldc.i4.0
  IL_0060:  /* 1F   | 40               */ ldc.i4.s   64
  IL_0062:  /* 16   |                  */ ldc.i4.0
  IL_0063:  /* 28   | (06)0003D1       */ call       valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult DCSP.modCenterDialog::Show(class [System.Windows.Forms]System.Windows.Forms.IWin32Window,
                                                                                                                                                  string,
                                                                                                                                                  string,
                                                                                                                                                  valuetype [System.Windows.Forms]System.Windows.Forms.MessageBoxButtons,
                                                                                                                                                  valuetype [System.Windows.Forms]System.Windows.Forms.MessageBoxIcon,
                                                                                                                                                  valuetype [System.Windows.Forms]System.Windows.Forms.MessageBoxDefaultButton)
  IL_0068:  /* 26   |                  */ pop
  IL_0069:  /* 02   |                  */ ldarg.0
  IL_006a:  /* 6F   | (0A)0000E0       */ callvirt   instance void [System.Windows.Forms]System.Windows.Forms.Form::Close()
  IL_006f:  /* 2A   |                  */ ret
} // end of method frmKeyEntry::cmdUnlock_Click
Основной прыжок. Если он произойдет, то мы ввели верный ключ
Код:
  IL_0024:  /* 2D   | 2E               */ brtrue.s   IL_0054
Заменим его на противоположный – brfalse. Для этого нужно заменить байт 2d на 2с. После патча программа принимает любой ключ, но по-прежнему не дает нормально с собой работать. Это значит, что, скорее всего еще одна проверка будет при перезапуске. Искать ее очень лениво, в силу обилия методов и форм. Надо найти другой, более быстрый и удобный способ. А что если… вообще убрать окно About?
Попробуем подойти с другой стороны. Сначала появляется основное окно программы, а потом требующее ключ. Значит процедура создания окна About (оно же NagScreen) происходит в Main Form. Под подозрение попадают методы
frmMain_Load
frmMain_Shown

В первом нет ничего полезного, а второе уже более интересно..

Код:
.method private instance void  frmMain_Shown(object sender,
                                             class [mscorlib]System.EventArgs e) cil managed
// SIG: 20 02 01 1C 12 61
{
  // Method begins at RVA 0x13e368
  …
  IL_0085:  /* 6F   | (06)000293       */ callvirt   instance class DCSP.Registration.clsRegistration DCSP.frmMain::get_clsReg()
  IL_008a:  /* 7B   | (04)000015       */ ldfld      valuetype DCSP.Registration.clsRegistration/enmRegistrationMode DCSP.Registration.clsRegistration::intRegistrationMode
  IL_008f:  /* 45   | 02000000         */ switch     ( 
            /*      | 02000000         */             IL_009e,
            /*      | 14000000         */             IL_00b0)
  IL_009c:  /* 2B   | 24               */ br.s       IL_00c2
  IL_009e:  /* 28   | (06)00000A       */ call       class DCSP.My.MyProject/MyForms DCSP.My.MyProject::get_Forms()
  IL_00a3:  /* 6F   | (06)00000C       */ callvirt   instance class DCSP.frmAbout DCSP.My.MyProject/MyForms::get_frmAbout()
  IL_00a8:  /* 6F   | (0A)0000E6       */ callvirt   instance valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult [System.Windows.Forms]System.Windows.Forms.Form::ShowDialog()
  IL_00ad:  /* 26   |                  */ pop
  IL_00ae:  /* 2B   | 12               */ br.s       IL_00c2
  IL_00b0:  /* 28   | (06)00000A       */ call       class DCSP.My.MyProject/MyForms DCSP.My.MyProject::get_Forms()
  IL_00b5:  /* 6F   | (06)00000C       */ callvirt   instance class DCSP.frmAbout DCSP.My.MyProject/MyForms::get_frmAbout()
  IL_00ba:  /* 1F   | 0A               */ ldc.i4.s   10
  IL_00bc:  /* 6F   | (06)000070       */ callvirt   instance valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult DCSP.frmAbout::ShowDialog(int32)
…

  IL_0151:  /* 2A   |                  */ ret
} // end of method frmMain::frmMain_Shown
Хм.. RegistrationMode… Флаг регистрации.
Значения, которые может принимать intRegistrationMode

RM_EVALUATION = int32(0x00000001)
RM_NONE = int32(0x00000000)
RM_PREMIUM = int32(0x00000003)
RM_PROFESSIONAL = int32(0x00000002)

Если Evaluation, то

Код:
  IL_008f:  /* 45   | 02000000         */ switch     ( 
            /*      | 02000000         */             IL_009e,
            /*      | 14000000         */             IL_00b0)
  IL_009c:  /* 2B   | 24               */ br.s       IL_00c2
Сработает вторая ветка свитча. И нам придется ждать 20 секунд, пока включится кнопка OK. Это нам совсем не надо.. А выполняется по дефолту как раз первая ветка. Поэтому менять здесь что-либо бестолку. Посмотрим, что по смещению IL_009e

Код:
 
  IL_009e:  /* 28   | (06)00000A       */ call       class DCSP.My.MyProject/MyForms DCSP.My.MyProject::get_Forms()
  IL_00a3:  /* 6F   | (06)00000C       */ callvirt   instance class DCSP.frmAbout DCSP.My.MyProject/MyForms::get_frmAbout()
  IL_00a8:  /* 6F   | (0A)0000E6       */ callvirt   instance valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult [System.Windows.Forms]System.Windows.Forms.Form::ShowDialog()
  IL_00ad:  /* 26   |                  */ pop
  IL_00ae:  /* 2B   | 12               */ br.s       IL_00c2
Вот и показ нашего About. Как вариант можно занопить три call, отвечающих за инициализацию и показ frmAbout. Опкод команды nop – 00h. Нет, я не ошиблась – именно 00h, а не 90h. В msil все не так, как в стандартном ассемблере. Попробуем так сделать.. Забьем нулями байты с 28h по 0Ah (не 0e6h! в хекс-редакторе байты будут идти в обратном порядке). Запускаем и… Программа падает.. Почему? Все дело, как оказалось в команде pop, которую я сразу не занопила. Pop чистит стек после передыдущих call. А их теперь нет! Значит программа будет работать неправильно. Перейдем в hiew по адресу, выданном msil disassembler и добьем инструкцию pop (байт 26h). Ура. Теперь программа работает как надо. И при запуске не выводится злого окна. Все функции работают.

[Outro]
Вот и все… Вопросы по статье в пм

Последний раз редактировалось 0x0c0de; 20.02.2008 в 19:01..
 
Ответить с цитированием
 



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Microsoft открыла коды .Net Framework iddqd Мировые новости 5 28.01.2008 14:29
Прямое введение команд в Sql сервер k00p3r Чужие Статьи 1 13.06.2005 21:05
Введение в cgi-security k00p3r Чужие Статьи 0 09.06.2005 19:30



Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ