14 мая 2012 г.

Введение в реверс инженеринг используя IDA - Глава 3

Сегодня займемся разборкой следующей главы Рикардо Нарваха под номерм 14, которая рассматривает еще один вид жестко прописанного серийника в коде программы, но реальный серийник будет вычилятся. Посмотреть эту статью на русском можно на сайте wasm.ru например тут.

Для начала качаем фаил с необходимым реквизитом отсюда. Разархивируем открываем IDA Pro, открываем File->Open и там выбираем crakmeeasy.exe.
Сразу с лева видим процедуры которые применяются в файле и можно в продолжении предыдущих статей про исключения, сразу обратить внимание на интересную функции под названием SetUnhandledExceptionFilter и главное TopLevelExceptionFilter. Почему я отклонился немного от стандартной статьи Рикардо Нарваха, а потому, что видя эти две функции должны насторожить любого исследователя программ, так как 1 функция обозначает, что программа ставит нестандартный обработчик исключений, а вот вторую функцию достроила сама IDA Pro, это та процедура которая будет вызвана при срабатывании исключения.
Посмотрим на скрин функций:

 
Стрелочками я выделил функции которые изначально меня заинтересовали, ну продолжим по мануалу Рикардо Нарвахо.
В списке видно знакомую функцию GetDlgItemTextA, будем отталкиваться от нее, ставим на нее брякпоинт - ПКМ на функцию и там Add breakpoint.
Запускаем программу по F9 и видим окошечко с полем ввода пароля. Набьем туда какойнить неверный пароль, например 1234567890 и нажмем кнопочку Check. Выпадем обратно в отладчик в начало вызова функции. Посмотрим на параметры функции GetDlgItemTextA, он имеет 4 параметра, из тех которые нас интересуют это буфер, куда будет положен неправильный серийник, этот параметр будет в стеке под номером 4. Можно на него нажать ПКМ и выбрать Follow in hex dump. См. скриншот:

 

В принципе я стрелочками все указал и описал, должно быть понятно. Буфер в текущий момент нулевой, так как функция не выполнилась. Нажимаем Ctrl+F7 и видим что буфер заполнился нашим неправильным серийником.
 

А в окне отладчика IDA Pro видно что копируем куюто длинную цифровую строку.
 
Можно сразу переменную как нибудь обозвать, типа mbSerial(May be Serial?), для этого ПКМ на a10445678951 и нажимем Rename ну или кнопку N.
Дальше небольшой код с разъяснениями
.text:0040130A mov     eax, offset mbSerial ; "10445678951" ; в eax копируется адрес возможного серийника
.text:0040130F mov     edx, [eax] ; копируем в edx первые 4 байта серийника
.text:00401311 mov     dword ptr [ebp+Str], edx ; копируем в другое место edx
.text:00401314 mov     edx, [eax+4] ; копируем в edx следующие 4 байта
.text:00401317 mov     [ebp+var_2C], edx  ; копируем в следующие 4 байта edx
.text:0040131A mov     eax, [eax+8] ; копируем последние 4 байта в edx
.text:0040131D mov     [ebp+var_28], eax ; завершаем копирование
Суть этого колдунства, число которое возможно серийник переместилось в другую ячейку памяти. Самое для нас интересное это адрес под именем ebp+Str его к стати тоже можно обозвать, таким же образом как было описано выше.

Дальше идет memset, он в принципе описан в каноничном мануале, но если в 2х словах, эта функция обнуляет некий участок в памяти. После него идет функция strlen которая измеряет длину возможного серийника.
В конце идет сравнение edx с числом в памяти по адресу: ebp+var_10
На текущий момент отладчик у нас выглядит вот так:

 
И после сравнения мы уходим в левую ветку, а там у нас уже идет вычисление серийника, попробуем разобраться:

.text:00401360 mov     eax, [ebp+lpString] ; копируем в eax адрес нашего серийника
.text:00401363 mov     edx, [ebp+var_10] ; в edx копируем 0 из счетчика
.text:00401366 add     eax, edx ; складываем eax и edx, это нужно чтобы был указатель на след цифру серийника
.text:00401368 movsx   edx, byte ptr [eax] ; в edx кладем цифру в текущей позиции из нашего серийника
.text:0040136B lea     eax, [edx-14h] ; отнимаем от нашего серийника 14h и кладем в eax
.text:0040136E lea     edx, [ebp+Str] ; в edx кладем адрес возможного серийника
.text:00401371 mov     ecx, [ebp+var_10] ; в ecx снова копируем значение из счетчика
.text:00401374 movsx   edx, byte ptr [ecx+edx] ; в edx кладем цифру из текущий позии возможного серийника
.text:00401378 cmp     eax, edx ; сравниваем наш серийник который ввели и эталонный
.text:0040137A jnz     short loc_4 ; прыгаем в зависимотсти от сравнения
Вообщем в принципе сразу становится ясно что тут происходит, от 16чного кода символа который мы ввели отнимается 14h и сравнивается с 16ричным кодом в псевдо серийнике, а это означает что это не возможный серийник, закодированная строка. Дальше идет сравнивание 31h с нашим неправильным 1Dh.
В итоге, чтобы получить правильный серийник нада к коду каждого символа в псевдо серийнике прибавить 14h.
Например первая цифра в псевдо серийники означает 31h прибавляем к ней 14h и получаем 45h, как поглядеть, что эта цифра означает в человеческих буковках. А очень просто, нада запустить калькулятор встроенный в IDA Pro, это View->Calc или нажать на Shift+/ дальше ввести туда 0x45 и нажать на Ok, получится что то типа такого:

 
Вот в строке Character как раз и будет искомый символ, проведя манипуляции над всеми кодами цифре в псевдо серийнике получим следюущую строку: EDHHIJKLMIE
Вводим его в окно серийника нажимаем Check и получаем что пароль верен.
В принципе вот и все, не так и сложно :)

Комментариев нет:

Отправить комментарий