Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Запись процедуры или функции в файл. [D7, WinXP]


Страницы:   1 2

Bios_ ©   (2005-08-11 14:27:00) 

Кодеры. Как записать процедуру или функцию в файл? Очень нужно,
заранее спасибо!


Наиль   (2005-08-15 21:50:00) [1]

Полностью согласен.
Надеюсь, теперь все знают, что так делать нельзя :-)


Eraser   (2005-08-15 21:46:00) [2]

Наиль ©   (15.08.05 21:41) [24]

Опять же это подходит только для Demo-версий, что вобщем не желательно, т.к. обязательно найдётся конкурент, который распространяет такую же прогу, но без урезаной функциональности до регистрации.
+ всё равно кто-нибудь выложит ключ на каком-нибудь crackway.com


Наиль   (2005-08-15 21:41:00) [3]

Предполагается, что функция расшифровывается всегда, если есть ключ. Верность расшифровки проверяется хешем. При этом, как писал Касперски, лучший хеш для такого случая 2-байтовый (10битный). Таким образом, злоумышленик получит слишком много ключей соответсвующий хешу, но не сможет подобрать верный.


Eraser   (2005-08-15 21:29:00) [4]

Наиль ©   (15.08.05 21:25) [22]
Вот я и говорю, что если функция используется, то защита есть. А если только проверяется, то защиты не получится. К примеру, в бухгалтерской программе расчёт производится по определёной формуле. Зашифруем функцию и программа будет бесполезной до её (функции) расшифровки.


Это всё конечно хорошо, но тут есть слабое место... а именно где определяется условие - расшифровывать или нет ф-ю.


Наиль   (2005-08-15 21:25:00) [5]

Eraser ©   (15.08.05 21:00) [21]
Вот я и говорю, что если функция используется, то защита есть. А если только проверяется, то защиты не получится. К примеру, в бухгалтерской программе расчёт производится по определёной формуле. Зашифруем функцию и программа будет бесполезной до её (функции) расшифровки. Сколько лет пишу программы, и не создал ни одного вируса. А вопрос защиты тут многим интересен. Полезно знать, что не стоит делать, пытаясь защитить свою программу.


Eraser   (2005-08-15 21:00:00) [6]

Наиль ©   (15.08.05 20:54) [20]

Защита сомнительная и громоздкая... да и к тому же большенство защит такого рода опять же взламываются подправлением условного перехода на безусловный, при проверке возвращаемого значения закриптованой ф-ии.

Вообще на виросописательством повеяло ;-))


Наиль   (2005-08-15 20:54:00) [7]

Раз уж я заговорил о защите, то такой способ в принципе может сработать.
К примеру в программе используется формула. Тогда её нужно вынести в отдельную функцию. Хранить её можно в зашифрованом виде, скажем, в ресурсах. На компьютере пользователя создаётся первая половина ключа, вторая половина создаётся создателем программы из первой половины. Далее пользователь используя половинки, активизирует программу. Т.е. происходит расшифровывание и использование формулы.
Этот способ обладает естественным недостатком. При выполнении программы (первая лицензионная копия) функция оказывается в памяти в открытом виде. А дальше, Вы уже знаете, что делать :-) (не лицензионная копия).
Если же, в ваше программе не используются формулы. То вам придётся, создать свою, постояно её сравнивать с неким оригиналом. В таком случае, нет ни какой защиты, т.к. злоумышленику не составит большого труда, добится положительного результата сравнения.
P.S. Касперски - мой любимый писатель.


Юрий Зотов   (2005-08-13 11:49:00) [8]

Вот пример исполнения кода в стеке с вызовом ShowMessage из этом коде. В данном случае буфер, хранящий исполняемый код копируется из тела программы, но понятно, что его можно заполнить и из файла, и вообще откуда угодно.

type
 TShowMsg = procedure(const Msg: string);
 TCallShowMsg = procedure(ShowMsg: TShowMsg; const Msg: string);

procedure CallShowMsg(ShowMsg: TShowMsg; const Msg: string);
begin
 ShowMsg(Msg)
end;

procedure ExecuteCodeInsideStack(Buff: string; const Msg: string);
begin
 TCallShowMsg(@Buff[1])(@ShowMessage, Msg)
end;

procedure TForm1.FormDblClick(Sender: TObject);
var
 L: Cardinal;
 S: string;
begin
 L := Cardinal(@ExecuteCodeInsideStack) - Cardinal(@CallShowMsg);
 SetLength(S, L);
 CopyMemory(@S[1], @CallShowMsg, L);
 ExecuteCodeInsideStack(S, 'OK')
end;


Юрий Зотов   (2005-08-13 11:16:00) [9]

> Наиль ©   (13.08.05 08:24) [15]

Об этом приеме еще лет 5 тому назад писал Крис Касперски в журнале "Программист". Вот эта статья:
http://reversing.by.ru/Manual/SelfMod.htm?extract=1123808127

Для компилятора Delphi прием работает, это давно проверено. Естественно, проблема перемещаемого кода остается и ее нужно как-то обходить - именно по этой причине "задача становиться действительно не выполнимой, при вызове любой процедуры или функции внутри загружаемой". Говоря точнее, задача НЕ становится невыполнимой, но выполнять ее приходится необычными способами.

> злобная танька (13.08.05 09:31) [16]

Ответ см. в упомянутой статье, в подразделе "Подводные камни перемещаемого кода".


Leonid Troyanovsky   (2005-08-13 11:14:00) [10]


> злобная танька   (13.08.05 09:31) [16]
> > Наиль ©   (13.08.05 08:24) [15]
> а если передавать в загруженную функцию адрес вызываемой
> из неё процедуры/функции? прокатит?


Адрес возврата и так есть - в стеке.
Главная проблема в том, что тело функции не должно содержать
ссылок на глобальные символы, адресных переходов да и многого
другого. Напрямую можно вызывать лишь функции kernel,
(но, именно напрямую, т.е., предварительно определив их
адрес путем GetAddressProc). Все остальные адреса внешних
функций должны определятся из кода.

--
Regards, LVT.


злобная танька   (2005-08-13 09:31:00) [11]

> Наиль ©   (13.08.05 08:24) [15]
а если передавать в загруженную функцию адрес вызываемой из неё процедуры/функции? прокатит?


Наиль   (2005-08-13 08:24:00) [12]

Не зависимо от целей, можно утверждать, что если что-то сохраняется, то должно и сохраняться. Если только для анализа, то лучше всё-таки пользоваться Debuger'ом. Если же для того, чтобы загрузить и выполнить, то задача становиться действительно не выполнимой, при вызове любой процедуры или функции внутри загружаемой.
Когда я впервые пришёл на этот сайт, то обнаружил исходники математического анализатора, который компилирует введёную формулу в память и вызывает полученую формулу. Более того, автор кратко объясняет приципы работы такой программы. Позже - найти эти исходники удалось только в "Королевстве". Я был потрясён. Но факт остаётся фактом. Функцию можно загрузить в память и выполнить. Но лёгко это делается, только математических формул.


evvcom   (2005-08-12 09:05:00) [13]


> Подозреваю, что это не которое подобие защиты. Часть функций
> программы храниться отдельно. Если регистрация прошла успешно,
> то они грузятся в память и вызываются.

Очень сомневаюсь в этом, но если это так, то задача в общем случае сложновата не только для новичка.


Наиль   (2005-08-12 08:59:00) [14]

Очепятка: Read(Fun -> Read(Fun^


Наиль   (2005-08-12 08:57:00) [15]

Подозреваю, что это не которое подобие защиты. Часть функций программы храниться отдельно. Если регистрация прошла успешно, то они грузятся в память и вызываются. Если нет, то программа не функциоиональна.
Пример:
Var
fs:TFileStream;
Fun:Pointer;
Begin
...
fs.Read(Fun,FunSize);
Button1.onClick:=TNotifyEvent(Fun);
...
End;


evvcom   (2005-08-12 08:27:00) [16]


> чтобы оный символ не
> экспортировался, иначе его адрес может быть невалиден

А подробнее можно? Чего-то не вижу причины этого.


Leonid Troyanovsky   (2005-08-11 19:57:00) [17]


> TStas ©   (11.08.05 19:37) [7]
> >begin...end
> То есть вторая процедура является просто ограничителем,
> по которй узнаем длинну кода первой?


Единственное(?) ограничение в том, чтобы оный символ не
экспортировался, иначе его адрес может быть невалиден.

--
Regards, LVT.


begin...end   (2005-08-11 19:39:00) [18]

> TStas ©   (11.08.05 19:37) [7]

Да.


begin...end   (2005-08-11 19:37:00) [19]

> Bios_   (11.08.05 15:18) [5]

Оно, конечно, пожалуйста, но в общем случае, как и было замечено в [6], это не будет работать. Поэтому в [4] и смайлик имеется.


TStas   (2005-08-11 19:37:00) [20]

>begin...end
То есть вторая процедура является просто ограничителем, по которй узнаем длинну кода первой?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо