Форум: "Основная";
Текущий архив: 2002.06.06;
Скачать: [xml.tar.bz2];
ВнизСлхранение функции Найти похожие ветки
← →
MaD (2002-05-25 16:02) [0]Подскажите пожалуйста. Как мне записать функцию в файл??? Как загружать функцию из файла и выполнять её??? Я записываю в файл через адрес функции, но не могу получить её длину.
← →
rhf (2002-05-25 16:04) [1]ты не про DLL?
← →
ION T (2002-05-25 17:00) [2]А по моему он хочет откомпилированный код сохранить в файл и потом подгружать его прямо в память и выполнять.....теоретически это возможно, но надо ещё стек сохранять, регистры,....ну в общем, удачи;))
← →
Юрий Зотов (2002-05-25 17:30) [3]Все очень просто. Компилятор Delphi строит машинный код в порядке объявления функций, поэтому после такого объявления
procedure A(...);
begin
...
end;
procedure B(...);
begin
...
end;
длина кода процедуры A будет равна Integer(B) - Integer(A). Но чтобы выполнить ее код, подгруженный извне, его сначала нужно будет поместить в сегмент стека.
См. статью Криса Касперски в журнале "Программист", №3 за 2001 год - там и об этом и еще о многом.
← →
MaD (2002-05-25 21:40) [4]Если Integer(B)-Integer(A), то фактически размер такой же как и sizeof(@A) и равен 4 байта.
А где взять журнал???
← →
y-soft (2002-05-26 17:48) [5]>MaD
http://www.programme.ru/index.phtml?arch/032001/index.htm
При творческом подходе можно использовать исполняемый код, созданный и иными способами
← →
SPeller (2002-05-26 18:34) [6]2 MaD (25.05.02 21:40)
размер такой же как и sizeof(@A) и равен 4 байта.
А как ты хотел? Измеряется в этом случае указатель на функцию, который 32-х разрядный, и равен соответственно 4-ём быйтам.
← →
Vaddya (2002-05-26 20:14) [7]Функции WriteFile в качестве второго параметра задается указатель на данные, записываемые в файл, а третьего - размер этих данных. Если написать указатель на функцию и ее размер, то наверное можно будет сохранить ее в файл.
← →
y-soft (2002-05-27 10:14) [8]>Vaddya (26.05.02 20:14)
Ваш подход скорее всего не будет работать, если в функции есть какие-либо внешние ссылки на адресное пространство вызывающего процесса
← →
Юрий Зотов (2002-05-27 16:07) [9]> MaD (25.05.02 21:40)
Это вряд ли... :о)
> Vaddya (26.05.02 20:14)
И даже без "наверное". Код спокойно сохраняется, читается обратно и даже выполняется - проверено.
> y-soft © (27.05.02 10:14)
Конечно, в общем случае не будет, разве что случайно. Например, не будут работать вызовы других функций. Но способ есть - чтобы ссылки работали, надо писать загружаемую функцию в виде перемещаемого кода и передавать ей базовый адрес.
← →
Romkin (2002-05-27 16:40) [10]Может быть, не стоит мудрить, а просто воспользоваться, к примеру MS Scripting? Готовый интерпретатор JScript/VBScript
← →
y-soft (2002-05-27 21:12) [11]>Юрий Зотов © (27.05.02 16:07)
Именно такие ограничения я и имел в виду :)
А вообще, вопрос интересен скорее теоретически, т.к. практически всегда можно обойтись легальными DLL, да и нынешние мощные скриптовые языки при производительности современных компьютеров вполне подойдут
← →
ION T (2002-05-27 22:10) [12]В общем попробовал я написать простенький пример:
unit MainFrm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
btnWrite: TButton;
btnLoadExec: TButton;
procedure btnWriteClick(Sender: TObject);
procedure btnLoadExecClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function FuncToWrite(Tst: boolean; CallbackAddr: pointer): boolean;
type _Callback= procedure (Value: boolean);
begin
_Callback(CallBackAddr)(tst);
{asm
mov al, tst;
call CallBackAddr;
end;}
if Tst then
begin
Result:= true
end else
Result:= false;
end;
procedure Callback(Value: boolean);
begin
Form1.Caption:= booltostr(value, true);
end;
function WriteFunc(FileName: string; FuncAddr: pointer; FuncLen: integer): integer;
var f: file;
begin
AssignFile(f, FileName);
rewrite(f, 1);
BlockWrite(f, FuncAddr^, FuncLen, Result);
CloseFile(f);
end;
function LoadFunc(FileName: string; var Buffer; Offset: integer= 0): boolean;
var f: file;
begin
Result:= false;
AssignFile(f, FileName);
{$I-}
reset(f, 1);
{$I+}
if IOResult= 0 then
begin
Seek(f, Offset);
BlockRead(f, Buffer, FileSize(f));
Result:= true;
end;
CloseFile(f);
end;
procedure TForm1.btnWriteClick(Sender: TObject);
begin
btnWrite.Caption:= inttostr(
WriteFunc("Func2Write.bin", @FuncToWrite, integer(@Callback)- integer(@FuncToWrite)));
end;
procedure TForm1.btnLoadExecClick(Sender: TObject);
type _FunctionToWrite= procedure (Tst: boolean; CallbackAddr: pointer);
var StackFunc: array[0..1023] of byte;
// StackFuncPtr, CallbackPtr: pointer;
begin
FillChar(StackFunc, 1024, $c3); //just in case:))
if LoadFunc("Func2Write.bin", StackFunc) then
begin
_FunctionToWrite(@StackFunc)(true, @Callback);
{ StackFuncPtr:= @StackFunc;
CallbackPtr:= @Callback;
asm
mov al, true; //Setting first parameter to whatever (boolean)
mov edx, CallbackPtr; //Second one pointing to callback()
call StackFuncPtr;
end;}
end;
end;
end.
Конечно для проверки серийника использовать можно (если ещё и зашифровать), но для чего-то ещё вряд-ли.......
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.06.06;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.01 c