Текущий архив: 2005.09.04;
Скачать: CL | DM;
Вниз
Запись процедуры или функции в файл. Найти похожие ветки
← →
Bios_ (2005-08-11 14:27) [0]Кодеры. Как записать процедуру или функцию в файл? Очень нужно,
заранее спасибо!
← →
Leonid Troyanovsky © (2005-08-11 14:39) [1]
> Bios_ (11.08.05 14:27)
> Кодеры. Как записать процедуру или функцию в файл? Очень
Compile project. {Program|Library}
--
Regards, LVT.
← →
Digitman © (2005-08-11 14:45) [2]запусти NotePad.exe
напиши в открывшемся окне для редактирования след.текст :
procedure MyDummyProc;
begin
end;
сохрани написанное в файл с указанным тобой именем.
все ! задача в приведенной формулировке решена.
← →
Rule © (2005-08-11 14:47) [3]чегото я не понял, неужели опять сессия :-)
← →
begin...end © (2005-08-11 14:51) [4]
function Func(A, B: Integer): Integer;
begin
Result := A + B
end;
procedure Proc;
begin
end;
...
// Сохранение Func
procedure TForm1.btnSaveClick(Sender: TObject);
var
L: Cardinal;
begin
L := Cardinal(@Proc) - Cardinal(@Func);
with TFileStream.Create("c:\File.ext", fmCreate) do
try
Write(L, sizeof(L));
Write(Func, L)
finally
Free
end
end;
// Загрузка Func
procedure TForm1.btnLoadClick(Sender: TObject);
type
MyFunc = function(A, B: Integer): Integer;
var
L: Cardinal;
P: Pointer;
begin
with TFileStream.Create("c:\File.ext", fmOpenRead) do
try
Read(L, sizeof(L));
GetMem(P, L);
try
Read(P^, L);
L := MyFunc(P)(3, 5);
ShowMessage(IntToStr(L))
finally
FreeMem(P)
end
finally
Free
end
end
:-)
← →
Bios_ (2005-08-11 15:18) [5]>>begin...end
Спасибо! У меня все получилось!
← →
Digitman © (2005-08-11 15:28) [6]
> Bios_ (11.08.05 15:18) [5]
в таком случае потенциальное хныканье, мол, "не работает" при коде отличном от А + В, будет расцениваться известным образом.
← →
TStas © (2005-08-11 19:37) [7]>begin...end
То есть вторая процедура является просто ограничителем, по которй узнаем длинну кода первой?
← →
begin...end © (2005-08-11 19:37) [8]> Bios_ (11.08.05 15:18) [5]
Оно, конечно, пожалуйста, но в общем случае, как и было замечено в [6], это не будет работать. Поэтому в [4] и смайлик имеется.
← →
begin...end © (2005-08-11 19:39) [9]> TStas © (11.08.05 19:37) [7]
Да.
← →
Leonid Troyanovsky © (2005-08-11 19:57) [10]
> TStas © (11.08.05 19:37) [7]
> >begin...end
> То есть вторая процедура является просто ограничителем,
> по которй узнаем длинну кода первой?
Единственное(?) ограничение в том, чтобы оный символ не
экспортировался, иначе его адрес может быть невалиден.
--
Regards, LVT.
← →
evvcom © (2005-08-12 08:27) [11]
> чтобы оный символ не
> экспортировался, иначе его адрес может быть невалиден
А подробнее можно? Чего-то не вижу причины этого.
← →
Наиль © (2005-08-12 08:57) [12]Подозреваю, что это не которое подобие защиты. Часть функций программы храниться отдельно. Если регистрация прошла успешно, то они грузятся в память и вызываются. Если нет, то программа не функциоиональна.
Пример:
Var
fs:TFileStream;
Fun:Pointer;
Begin
...
fs.Read(Fun,FunSize);
Button1.onClick:=TNotifyEvent(Fun);
...
End;
← →
Наиль © (2005-08-12 08:59) [13]Очепятка: Read(Fun -> Read(Fun^
← →
evvcom © (2005-08-12 09:05) [14]
> Подозреваю, что это не которое подобие защиты. Часть функций
> программы храниться отдельно. Если регистрация прошла успешно,
> то они грузятся в память и вызываются.
Очень сомневаюсь в этом, но если это так, то задача в общем случае сложновата не только для новичка.
← →
Наиль © (2005-08-13 08:24) [15]Не зависимо от целей, можно утверждать, что если что-то сохраняется, то должно и сохраняться. Если только для анализа, то лучше всё-таки пользоваться Debuger"ом. Если же для того, чтобы загрузить и выполнить, то задача становиться действительно не выполнимой, при вызове любой процедуры или функции внутри загружаемой.
Когда я впервые пришёл на этот сайт, то обнаружил исходники математического анализатора, который компилирует введёную формулу в память и вызывает полученую формулу. Более того, автор кратко объясняет приципы работы такой программы. Позже - найти эти исходники удалось только в "Королевстве". Я был потрясён. Но факт остаётся фактом. Функцию можно загрузить в память и выполнить. Но лёгко это делается, только математических формул.
← →
злобная танька (2005-08-13 09:31) [16]> Наиль © (13.08.05 08:24) [15]
а если передавать в загруженную функцию адрес вызываемой из неё процедуры/функции? прокатит?
← →
Leonid Troyanovsky © (2005-08-13 11:14) [17]
> злобная танька (13.08.05 09:31) [16]
> > Наиль © (13.08.05 08:24) [15]
> а если передавать в загруженную функцию адрес вызываемой
> из неё процедуры/функции? прокатит?
Адрес возврата и так есть - в стеке.
Главная проблема в том, что тело функции не должно содержать
ссылок на глобальные символы, адресных переходов да и многого
другого. Напрямую можно вызывать лишь функции kernel,
(но, именно напрямую, т.е., предварительно определив их
адрес путем GetAddressProc). Все остальные адреса внешних
функций должны определятся из кода.
--
Regards, LVT.
← →
Юрий Зотов © (2005-08-13 11:16) [18]> Наиль © (13.08.05 08:24) [15]
Об этом приеме еще лет 5 тому назад писал Крис Касперски в журнале "Программист". Вот эта статья:
http://reversing.by.ru/Manual/SelfMod.htm?extract=1123808127
Для компилятора Delphi прием работает, это давно проверено. Естественно, проблема перемещаемого кода остается и ее нужно как-то обходить - именно по этой причине "задача становиться действительно не выполнимой, при вызове любой процедуры или функции внутри загружаемой". Говоря точнее, задача НЕ становится невыполнимой, но выполнять ее приходится необычными способами.
> злобная танька (13.08.05 09:31) [16]
Ответ см. в упомянутой статье, в подразделе "Подводные камни перемещаемого кода".
← →
Юрий Зотов © (2005-08-13 11:49) [19]Вот пример исполнения кода в стеке с вызовом 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-15 20:54) [20]Раз уж я заговорил о защите, то такой способ в принципе может сработать.
К примеру в программе используется формула. Тогда её нужно вынести в отдельную функцию. Хранить её можно в зашифрованом виде, скажем, в ресурсах. На компьютере пользователя создаётся первая половина ключа, вторая половина создаётся создателем программы из первой половины. Далее пользователь используя половинки, активизирует программу. Т.е. происходит расшифровывание и использование формулы.
Этот способ обладает естественным недостатком. При выполнении программы (первая лицензионная копия) функция оказывается в памяти в открытом виде. А дальше, Вы уже знаете, что делать :-) (не лицензионная копия).
Если же, в ваше программе не используются формулы. То вам придётся, создать свою, постояно её сравнивать с неким оригиналом. В таком случае, нет ни какой защиты, т.к. злоумышленику не составит большого труда, добится положительного результата сравнения.
P.S. Касперски - мой любимый писатель.
← →
Eraser © (2005-08-15 21:00) [21]Наиль © (15.08.05 20:54) [20]
Защита сомнительная и громоздкая... да и к тому же большенство защит такого рода опять же взламываются подправлением условного перехода на безусловный, при проверке возвращаемого значения закриптованой ф-ии.
Вообще на виросописательством повеяло ;-))
← →
Наиль © (2005-08-15 21:25) [22]Eraser © (15.08.05 21:00) [21]
Вот я и говорю, что если функция используется, то защита есть. А если только проверяется, то защиты не получится. К примеру, в бухгалтерской программе расчёт производится по определёной формуле. Зашифруем функцию и программа будет бесполезной до её (функции) расшифровки. Сколько лет пишу программы, и не создал ни одного вируса. А вопрос защиты тут многим интересен. Полезно знать, что не стоит делать, пытаясь защитить свою программу.
← →
Eraser © (2005-08-15 21:29) [23]Наиль © (15.08.05 21:25) [22]
Вот я и говорю, что если функция используется, то защита есть. А если только проверяется, то защиты не получится. К примеру, в бухгалтерской программе расчёт производится по определёной формуле. Зашифруем функцию и программа будет бесполезной до её (функции) расшифровки.
Это всё конечно хорошо, но тут есть слабое место... а именно где определяется условие - расшифровывать или нет ф-ю.
← →
Наиль © (2005-08-15 21:41) [24]Предполагается, что функция расшифровывается всегда, если есть ключ. Верность расшифровки проверяется хешем. При этом, как писал Касперски, лучший хеш для такого случая 2-байтовый (10битный). Таким образом, злоумышленик получит слишком много ключей соответсвующий хешу, но не сможет подобрать верный.
← →
Eraser © (2005-08-15 21:46) [25]Наиль © (15.08.05 21:41) [24]
Опять же это подходит только для Demo-версий, что вобщем не желательно, т.к. обязательно найдётся конкурент, который распространяет такую же прогу, но без урезаной функциональности до регистрации.
+ всё равно кто-нибудь выложит ключ на каком-нибудь crackway.com
← →
Наиль © (2005-08-15 21:50) [26]Полностью согласен.
Надеюсь, теперь все знают, что так делать нельзя :-)
Страницы: 1 вся ветка
Текущий архив: 2005.09.04;
Скачать: CL | DM;
Память: 0.54 MB
Время: 0.042 c