Лекарство для CuteFTP EGOiST/TSRh (egoist_tsrh@bk.ru) Хакер, номер #079, стр. 079-062-3 В поставке с Олькой есть плагин Command line — некое подобие командной строки в SoftIce. Запустить его можно нажав Alt+F1. Если следовать классическим представлениям о крякинге, то сейчас надо установить точку останова (далее — бряк, от слова breakpoint) на вызов окошка об ошибке или на чтение текста из бокса. Но мы пойдем другим путем: поставим брейк на WinAPI-функцию чтения текста из окна GetWindowTextA, что можно сделать командой bp GetWindowTextA. Если ты постоянный читатель рубрики «Кодинг», у тебя наверняка есть MSDN, загляни туда, чтобы получить информацию об API-функциях Windows. Плагин Command Line поддерживает множество команд, узнать о которых можно набрав help. Я же выделю самые нужные: * bp [address] — ставит бряк на определенный адрес; * bc [address] — удаляет бряк; * d [address] — показывает в окне дампа памяти, что находится по данному адресу; * he/hr/hw [address] — ставят железные (hardware) бряки на исполнение, чтение, запись по адресу соответственно. Командой «bp GetWindowTextA» мы поставили бряк на GetWindowTextA. Жмем в CuteFTP Next и вываливаемся в Olly. Чтобы выйти из WinApi-функции, нажимаем Ctrl+F9 — курсор встанет на инструкции retn 0C. Это инструкция возврата из функции. В дебаггерах инструкции можно выполнять пошагово и наблюдать за изменениями (в этом и есть их преимущество). Бряк, который мы установили, нам больше не понадобится, поэтому удаляем его командой bc GetWindowTextA. Идем по коду, нажимая F8, пока не выйдем из функции. Сразу после этого мы оказываемся в другом блоке кода, и аналогичным образом пробираемся к выходу, нажимая Ctrl+F9. Здесь идет сравнение регистра eax с нулем: test eax, eax, далее je 0046ec06 — осуществляется прыжок на 0046ec06, если eax равен нулю, или просто дальше по коду, если нет. Проходим до 0046ea46, тут в eax закидывают адрес введенного нами серийника, посмотреть его можно командой d eax (только надо пройти на инструкцию дальше). В ecx кидается (можно догадаться) длина серийника, сравнивается, опять же, с 0. Так как длина номера не равна нулю, мы прыгаем на 0046eab2 и ползем дальше. Call 00527793 загружает строку из ресурсов (если покопаться внутри, можно заметить вызов LoadStringA). Далее в call 005098b3 эта строка сравнивается с нашим серийником, и если они совпадают, то в eax возвращается 0, в противном случае — позиция в строке, с которой начинается несовпадение. А вот что-то интересное: call 00476bf0, при этом перед ней в стек кладется наш серийник. Нажав F7, заходим в процедуру. if lstrlen('ахинея')==14 .. :) mov edx, [esp+20h+arg_4] push edi mov edi, edx or ecx, 0FFFFFFFFh xor eax, eax mov [esp+24h+var_12], 0 repne scasb not ecx dec ecx mov [esp+24h+var_2], 0 cmp ecx, 0Eh jnz loc_476C99 В самом начале длина серийника вычисляется и сравнивается с 0E (14 в десятичной системе). Нажимаем Ctrl+F9, ставим бряк на вызов функции: bp 0046eaf5 и пускаем прогу, нажав F9. Естественно, выскакивает ошибка: мы ввели строку длиной больше 14-ти символов. Теперь вводим 14-байтную ахинею, жмем Next и останавливаемся в Ольке на бряке. Заходим в функцию — серийник теперь ровно в 14 символов, так что проверку длины проходим без проблем и идем дальше. |