Особенности дизассемблирования под LINUX на примере tiny-crackme


         

в регистр EAX указатель на


Команда "mov eax, offset loc_20004B" в строке 002002F1h загружает в регистр EAX указатель на начало зашифрованного блока, а команда "mov ecx, 2A5h" задает количество обрабатываемых байт, которое тут же делиться на четыре (сдвиг на две позиции вправо эквивалентен делению на четыре, т. к. 2**2 = 4), поскольку расшифровка идет двойными словами. Цикл расшифровки предельно стандартен и тривиален: lodsd/xor eax, 3F5479F1h/stosd/loop (грузим в EAX очередное двойное слово/делаем ему XOR/сохраняем результат/мотаем цикл). Как это может работать?! Любой программист знает, что в LINUX'е сегмент кода доступен только на исполнение (чтение) и любая попытка записи приводит к аварийному завершению приложения. На самом деле это отнюдь не ограничение системы, а… всего лишь атрибуты кодового сегмента, назначаемые линкером по умолчанию. В данном случае, выставлены все три атрибута — чтение/запись/исполнение, о чем информирует нас IDA в первой строке (Segment permissions: Read/Write/Execute). Имейте это ввиду, при создании собственных защитных механизмов!

Чтобы расшифровать программу, необходимо поксорить блок от 20004Bh до (020004Bh+2A5h) константой 3F5479F1h. Нажимаем <Shift-F2> и в появившемся диалоговом окне вводим следующий скрипт:

auto a, x;                 // объявляем переменные (тип auto)

for (a = 0x20004B; a < (0x20024B+0x2A5);)

{                          // мотаем цикл

       x = Dword(a);        // берем очередное двойное слово по адресу a

       x = x ^ 0x3F5479F1;  // расшифровываем его

       PatchDword(a,x);     // патчим образ загруженного файла (не сам файл)

       a = a + 4;           // модифицируем счетчик цикла (IDA

не поддерживает a+=4)

}

Листинг 5 IDA-скрипт, автоматически снимающий шифровку



Рисунок 5 последняя проверка скрипта перед передачей на выполнение

Если скпипт написан без ошибок, то нажатие <Ctrl-Enter> приведет к его выполнению и расшифрует весь код. Кстати говоря, создатель крякмися допустил некритическую ошибку и расшифровал на два байта больше положенного, в результате чего угробил начало расшифровщика, к тому моменту уже отработавшее как первая ступень ракеты и никак не препятствующее нормальному выполнению программы:


Содержание  Назад  Вперед