Для начала качаем фаил с необходимым реквизитом отсюда. Разархивируем открываем 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 и получаем что пароль верен.
В принципе вот и все, не так и сложно :)
Комментариев нет:
Отправить комментарий