И снова здравствуй, уважаемый читатель! В прошлых частях я рассказывал о:
- Защита Delphi-программ от взлома. Часть I – Инструментальная
- Защита Delphi-программ от взлома. Часть II – Защитно-обзорная
- Защита Delphi-программ от взлома. Часть III – Навесная
Я продолжаю публиковать заметки о защите программного обеспечения на Delphi и сегодня мы рассмотрим такой известный декомпилятор, как DeDe ну и конечно попробуем от него защищаться :) Поехали?
Тестовый проект
Для начала, накидайте на Делфи простой тестовый проект с защитой (можно не извращаться, это просто для тестов). Вот как выглядит моя защита:procedure TForm1.Button1Click(Sender: TObject); begin Edit1.Text := fGeneratePass; end; procedure TForm1.Button2Click(Sender: TObject); begin if Edit2.Text = fGeneratePass then ShowMessage('Good Boy!'); end; function TForm1.fGeneratePass: String; var pPCName: array [0..MAX_COMPUTERNAME_LENGTH+1] of Char; cPassLen: Cardinal; i,j:integer; Password:string; begin ZeroMemory(@pPCName, SizeOf(pPCName)); cPassLen := MAX_COMPUTERNAME_LENGTH+1; GetComputerName(@pPCName,cPassLen); for i := 0 to High(pPCName) - 1 do for j := 0 to Length(Self.Caption) - 1 do Password := Password + IntToStr(Ord(pPCName[i]) xor Ord(Self.Caption[j])); result := Password; end;
Интерфейс программы тоже минимальный:
Кнопка Generate генерирует серийник на основе имени машины и заголовка программы, а кнопка Check Key соответственно, проверяет его.
Внимание!
Так, как сделал проверку я, никогда не следует делать. Это просто тестовый пример для DeDe! А вот о том, как следует, читайте в моих следующих заметках.
Вроде бы всё просто. Компилируем. И тут… Тут стоит остановиться и сказать, что сама DeDe разделяется на так называемую старую версию, которая от DaFixer и новую, которая от BitMaker. Ни одна из них, даже с учётом последних версий точно не понимают компилятора Delphi версии 21.00
(Delphi 2010). Может быть они не понимали его ещё с версии 2009 – точно не знаю, проверьте если интересно. По крайней мере, компилятор Delphi 15.0 (Delphi 7) они понимают прекрасно.
Что значит “понимают” и не “понимают”? Мы поймём, как только начнём исследовать программу, скомпилированную разными компиляторами в DeDe. Не будем терять времени и загрузим в новую версию DeDe программу скомпилированную в Delphi 7. Переходим на вкладку “Процедуры” и видим, в моём случае два события класса TForm1! Это как раз те два OnClick, которые я написал в тестовом примере. Вот посмотрите:
Как видите, по информационному окну информации предоставляется просто предостаточно! И имя метода и событие, и вызывающий объект, и даже заголовок кнопки. Прибавить к тому, самое главное – RVA-адрес, с которого собственно и начинается наша процедура сравнения и получаем собственно всю необходимую информацию для успешного реверсинга нашей программки. По двойному клику на событие откроется так-же и дизассемблированный код процедуры. Он конечно может быть сколько угодно глубоким, но факт остаётся фактом – информация есть, и она представлена в лучшем виде.
Если мы загрузим в DeDe программу скомпилированную в Delphi 2010, то кроме имён классов вы ничего не увидите. Те, кто сидит на Delphi 2010 сейчас обрадуются, но им всё-же не стоит забывать, что кроме DeDe, существуют и другие инструменты, которым на версию компилятора глубоко фиолетово – уж поверьте…
А что, если я не хочу отходить от использования Delphi 7? Ничего не поделаешь. Придётся. Даже если заменить компилятор 7 Delphi на 10 всё равно ничего вы этим не добьётесь, так как связано это с внутренним устройством среды Delphi 2010. Во первых в разных библиотеках, разные адреса функций (DCCxx.dll), а во вторых стоит ли надеяться, что библиотеки эти одинаковы в плане своей архитектуры? Но это не говорит о том, единственным способом защиты от DeDe является переход на молодые версии, можно прекрасно защищаться и на Delphi 7! И вот как!
Защищаемся
Основным способом защиты от DeDe является динамическое присваивание событиям указателей методов. Давайте рассмотрим как это происходит:
// Форма //########################################################## public { Public declarations } function fGeneratePass:String; procedure pGetPassToEdit(Sender:TObject); procedure pCheckPass(Sender:TObject); ... // Методы procedure TForm1.pGetPassToEdit(Sender:TObject); begin Form1.Edit1.Text := Form1.fGeneratePass; end; procedure TForm1.pCheckPass(Sender:TObject); begin if Form1.Edit2.Text = Form1.fGeneratePass then ShowMessage('Good Boy!'); end; // функция генерации function TForm1.fGeneratePass: String; var pPCName: array [0..MAX_COMPUTERNAME_LENGTH+1] of Char; cPassLen: Cardinal; i,j:integer; Password:string; begin ZeroMemory(@pPCName, SizeOf(pPCName)); cPassLen := MAX_COMPUTERNAME_LENGTH+1; GetComputerName(@pPCName,cPassLen); for i := 0 to High(pPCName) - 1 do for j := 0 to Length(Self.Caption) - 1 do Password := Password + IntToStr(Ord(pPCName[i]) xor Ord(Self.Caption[j])); result := Password; end; // Проект //########################################################## program Project1; uses Forms, Unit1 in 'Unit1.pas' {Form1}; {$R *.res} begin Application.Initialize; Application.CreateForm(TForm1, Form1); Form1.Button1.OnClick := Form1.pGetPassToEdit; // !! присваиваем указатели на методы Form1.Button2.OnClick := Form1.pCheckPass; // !! --//-- Application.Run; end.
Результатом будет служить то, что DeDe не сможет распознать обработчики событий:
Не пробовали IDR (Interactive Delphi Reconstructor)? Это фриварный продукт, скачать можно с сайта http://www.shell-codes.com
ОтветитьУдалитьcrypto
http://wireless-hack.ucoz.ru - Универсальный софт для подбора пароля к Wi-Fi сетям
УдалитьНа этом сайте вы сможете скачать программу для подбора пароля к Wi-Fi
Скачать: http://goo.gl/RvYYLr
Ознакомиться с видео презентацией работы программы: http://goo.gl/GxwLdF
Скачать приватный hack софт бесплатно: http://goo.gl/oR7rQW
Услуги по подбору паролей к Wi-Fi, Rar, Zip.: http://goo.gl/oTKnnE
http://www.google.ru/#btnI=rutigunu&q=wireless-hack.ucoz
Генератор ключей Steam: http://goo.gl/ah3i6E
http://wireless-hack.ucoz.ru/soft/soft1.html
Первый раз слышу, если честно. Попробую, спасибо.
ОтветитьУдалитьЕсли Касперски предоставил место для хостинга страницы программы, то она определённо заслуживает внимания :)
ОтветитьУдалитьIDR сейчас поддерживает версии до 2009 включительно. Версия 2010 тоже уже поддерживается, но соответствующий билд будет доступен чуть позже...
ОтветитьУдалитьБлин, она... она замечательна! Я пока не сильно конечно разобрался, но то, что получается - очень даже не дурно! Респект!
ОтветитьУдалитьКстати, было бы приятно, если бы когда я например тыкаю на форму и открывалась бы не модально, но показывалась бы всё равно, то есть, когда открыта форма, невозможно работать с ClassViewer & CodeViewer. Вот такое пожелание :)
ОтветитьУдалитьCrypto, свяжитесь со мной, есть о чём поговорить. uin: 982401
ОтветитьУдалитьIDR уже официально поддерживает версию 2010
ОтветитьУдалить1. При 'for j:=0' вылетает ошибка 'Range check error', работает 'for j:=1'
ОтветитьУдалить2. Дополнительно скрыть информацию от DeDe и других редакторов ресурсов можно путем динамического создания контролов (Edit, Button и др.).
Пример:
Удаляем все с Формы.
Для Формы создаем событие FormCreate
procedure TForm1.FormCreate(Sender: TObject);
begin
Edit1:=TEdit.Create(Form1); //Создаем 'Edit1'
Edit1.Parent:=Form1;
Edit1.Left:=20; //Располагаем 'Edit1' на форме
Edit1.Top:=20;
BitBtn1:=TBitBtn.Create(Form1); //Создаем Кнопку
BitBtn1.Parent:=Form1;
BitBtn1.Left:=Edit1.Left;
BitBtn1.Top:=Edit1.Top+Edit1.Height+8;
BitBtn1.Caption:='Generate'; //Надпись на Кнопке
BitBtn1.OnClick:=Form1.pGetPassToEdit; //Дейтвие на нажатие Кнопки
end;
Создавать Контролы можно в середине программы по мере надобности, тогда их вообще будет трудно отследить.
Как правило контролы создаются динамически именно в обработчике события FormCreate, там же назначаются и их собственные обработчики событий, поэтому восстановить их с помощью IDR особого труда не составляет. Я подобные вещи проделывал не раз на нескольких известных программах, все прекрасно работает.
Удалитьcrypto
Спасибо за комментарии. По поводу того, что трудно отследить... хмм.. не согласен... Обычный брейк на функции CreateWindow & CreateWindowEx в отладчике сразу же спалят весь сакральный смысл тайной вечерии....
ОтветитьУдалитьВообще-то, в статье говорится о защите программы от предварительного анализа в декомпиляторах DeDe и IDR, показывающих названия и подписи кнопок и полей, адреса функций их обработки, что сразу подсказывает, где проверяется пароль и куда ставить прерывание. При динамическом создании контролов, этой информации нет. Полей (кнопок) можно создать пару десятков (сотен), и определить какие из них отвечают за ввод пароля будет труднее... Да и работа с отладчиками IDA и OllyDbg, это уже другой уровень.
ОтветитьУдалить