15.03.2010, 17:46
Капитальныи и косметическии ремонт квартир remont-f.ru/remont-kvartir-pod-kluch/.
Основной
задачей, которая приводит к дизассемблированию приложений является
необходимость изменить структуру и поведение готового выполняемого
файла. Самым ярким примером дизассемблирования является взлом защиты
программ, встроенной разработчиками. Рассмотрим решение данной задачи на
практическом примере.
Внимание! Данное руководство
предназначено только для закрепления знаний ассемблера людям, которые
программируют электронику на данном языке. Ни в коем случае не следует
выполнять действия,приведенные в данном руководстве на любых программах
кроме той, что показана на примере.
Пусть дана консольная программа,
которая при запуске выполняет запрос на ввод пароля из клавиатуры.
Пароль хранится в программе в виде строковой переменной со значением
В«passwordВ». При правильном вводе на экран выводится сообщение В«OKВ», а
иначе – В«Password incorrectВ». Существует несколько способов взлома такой
защиты. Первый способ основан на необходимости только найти правильный
пароль и получить положительную авторизацию введя найденный пароль.
Второй способ – необходимость сделать так, чтобы при вводе любого пароля
программа считала его правильным и выдавала положительную авторизацию.
Первый способ
Идея: Необходимо путем пошаговой отладки
исполняемого файла найти место(адрес) в памяти, где находится переменная
с паролем, перейти по найденному адресу и выявить пароль. Для этого
нужно сначала найти место в программе, где находится ввод пароля и
место, где выводится результат авторизации. Дальше последовательной
трассировкой выявить предполагаемые критические точки в программе между
найденными участками, где происходит какое-либо сравнение с последующим
условным переходом (зачастую je либо jne). В разных программах сравнение
может быть выполнено по-разному: это либо операция CMP, либо вызов
процедуры сравнения, либо выполнения других операций, которые способны
выставлять флаги процессора. После этого происходит анализ найденных
точек в зависимости от вида сравнения для нахождения адреса переменной с
паролем. Если выявлена операция CMP, то происходит сравнение значений
пароля (символов, если пароль задан в виде строки и чисел, если задан
числовой пароль) с введенными значениями с клавиатуры. В данном случае
необходимо последовательно запоминать сравниваемые значения и в конце
сравнения составить из них правильный пароль. Если в критической точке
выявлен вызов процедуры сравнения, то перед ее вызовом можно найти
пересылку аргументов процедуры в стек (или, что очень редко, в
регистры). Аргументами процедуры сравнения очевидно и есть сравниваемые
данные, но в отличие от операции CMP данные аргументы зачастую
передаются не в виде значений, а в виде адресов на сравниваемые
переменные. Поэтому для нахождения пароля необходимо выявить, какие
адреса передаются в стек, и последовательно переходя по каждому адресу
найти в одном из них пароль. Если в критической точке происходят
какие-либо другие действия с выставлением флагов, то в такой
нестандартной ситуации необходимо выявлять пароль исходя из смысла
данных действий.
Поскольку
сравнение с использованием процедур выполняется наиболее часто, то в
данной лабораторной работе приведен пример программы, написанной на
языке С++, которая сравнивает пароль с введенной строкой процедурой int
strcmp(char *s,char *d), которая в качестве аргументов принимает адреса
сравниваемых строк и возвращает значение 0 если строки равны,
число меньше нуля, если строка s<d и число больше нуля, если строка
s>d. Для вывода на консоль используется функция << объекта
класса ostream, представляющего стандартный поток вывода, а для ввода –
функция >> объекта класса istream, представляющего стандартный
поток ввода.
Листинг тестовой программы для
нахождения пароля labDasm.cpp:
#include
<iostream.h>
#include
<string.h>
#include
<conio.h>
void
main()
{
char
*a,*pass="password";
clrscr(); // Очистка экрана
cout<<"Enter the password: "<<endl;
cin>>a;
if(!strcmp(a,pass))
cout<<"OK";
else
cout<<"Password incorrect";
cin.get();
cin.get(); // Ожидает нажатия клавиши Enter
}
|
Шаги алгоритма нахождения пароля:
1. Открыть в отладчике Turbo debugger
(TD.exe) исполняемый файл labDasm.exe;
2. Выполнить последовательную трассировку
программы (по запросу ввода пароля ввести любую строку, например В«12345В») до нахождения точки вызова процедуры
сравнения strcmp
(рис. 1);
Рис. 1
3. Перед найденной точкой вызова
находится пересылка адресов сравниваемых строк в стек, а после –
операция условного перехода jne. Данные два адреса хранятся в памяти,
как видно из рис.1, по смещению bp-04 и bp-02 сегмента
данных. Найти эти адреса перейдя в памяти на ds:0xFFF2 и ds:0xFFF4
соответственно (рис.2);
Рис. 2
В данном случае:
СМЕЩ1 = 00AAh
СМЕЩ2 = 5845h
4. Перейти по каждому из найденных адресов
(рис. 3):
Рис. 3
Как видно из рис.3, по смещению 5845h
находится введенная из клавиатуры ранее строка В«12345В» с кодом конца
строки 0, а по смещению 00AAh находиться пароль В«passwordВ».
Второй
способ
Идея: Необходимо найти предполагаемые
критические точки программы, как было показано в первом способе. Из
найденных точек определить истинную критическую точку (в данном примере
найдена только одна предполагаемая критическая точка, она и есть
истинной). Дальше необходимо выявить последующую за найденной точкой
операцию условного перехода, данный переход определяет, куда нужно
перейти в зависимости от правильности ввода пароля. Например, если
пароль введен правильно, то выводится сообщение об успешной авторизации,
а иначе – сообщение о
неправильности ввода. Поэтому, чтобы при неправильно введенной строке с
клавиатуры программа выдала сообщение о правильности ввода, необходимо
заменить в исполняемом файле условие перехода на противоположное (например jne на je, или jz на jnz и т.д.).
Алгоритм изменения исполняемого файла
для его положительной реакции на неправильно введенный пароль:
1. Открыть в отладчике Turbo debugger (TD.exe) исполняемый файл labDasm.exe;
2. Выполнить последовательную трассировку
программы до нахождения операции условного перехода после вызова
процедуры сравнения strcmp (рис. 4). Найденная операция условного перехода
jne имеет машинный код 7505h ;
3. Открыть в редакторе Hex View (hiew.exe)
исполняемый файл labDasm.exe;
4. Переключится в режим просмотра кода (F4
для переключения режима просмотра -> Decode);
5. Найти операцию с машинным кодом 7505h (F7 для поиска -> Hex для ввода шеснадцатеричных символов);
6. Изменить операцию из jne на je (F3 для входа в режим
редактирования затем F2 для изменения текущей
команды) (Рис. 5);
7. Сохранить изменения (F9).
Рис. 4
Рис. 5
Теперь, когда исполняемый файл изменен, при вводе
неправильного пароля, программа будет воспринимать его как правильный
(Рис. 6).
Рис. 6
На выполнение требований
данного руководства ушло 30 минут.
Полищук Олег
|