Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.005 c
1-17899
Andre V.
2002-05-24 12:46
2002.06.06
Опять про сохранение состояния программы


1-17914
stupid
2002-05-27 15:23
2002.06.06
Нужно узнать размер файла после сжатия.


1-17958
VeLeS
2002-05-23 17:39
2002.06.06
Как проверить полный путь к файлу на пренадлежность к Шаблону


4-18189
Nadin
2002-04-02 16:34
2002.06.06
Как найти дескриптор главного окна процесса?


14-18149
Mikeee
2002-05-03 13:38
2002.06.06
По какому событию...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский