Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.06.06;
Скачать: CL | DM;

Вниз

Слхранение функции   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.014 c
6-18076
xmag
2002-03-25 23:19
2002.06.06
Передаю url на сервер и полуаю ....


1-17879
dim-
2002-05-26 12:17
2002.06.06
интеграция в эксплорер


1-17858
stupid
2002-05-23 15:49
2002.06.06
Напоминалка...


3-17766
Oleg_er
2002-05-13 07:10
2002.06.06
Как запрос выполнить в потоке?


6-18094
End
2002-03-26 07:51
2002.06.06
Помогите плз....