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

Вниз

Генерировать функцию во время выполнения   Найти похожие ветки 

 
KSergey ©   (2016-04-12 15:24) [0]

Почитал тему рядом и подумал, что наверное и на мой вопрос будут идеи реализации.
Что есть:
В коде есть некие разные функции с единым прототипом.
Есть функция, которая регистрирует их как callback"и.

Что нужно:
Нужна такая функция, которая во внешней системе будет регистрировать на сам переданный ей call-back, а обёртку на call-back"ом, которая уже будет этот call-back вызывать.

Сама обёртка каждый раз совершенно идентичная:
  код до
  вызов оригинального callback
  код после

Передать через параметры какой call-back вызывать - возможности нет. Т.е. call-back-функции различаются только адресами получается.
Тогда нужно регистрировать каждый раз регистрировать новый адрес обёртки, а где его взять.

Есть ли возможность лепить такие обёртки в run-time?


 
sniknik ©   (2016-04-12 15:29) [1]

там же, рядом, уже предлагали встраиваемые скриптовые языки, нет?


 
Sha ©   (2016-04-12 15:34) [2]

> KSergey

Было проще понять проблему, если бы был код, что есть и что хочешь.


 
Sha ©   (2016-04-12 15:48) [3]

> KSergey

Если правильно понял, тебе достаточно одной процедуры с сотней входов.
Регистрируешь все входы.
Потом по адресу входа определяешь, что надо вызвать.


 
DVM ©   (2016-04-12 15:50) [4]


> Есть ли возможность лепить такие обёртки в run-time?

Их бесконечное множество что ли? Может заранее слепить все варианты, не?


 
KSergey ©   (2016-04-13 08:57) [5]

> DVM ©   (12.04.16 15:50) [4]
> Их бесконечное множество что ли? Может заранее слепить все варианты, не?

Да, это понятный вариант.
Но как-то не спортивно )


 
KSergey ©   (2016-04-13 08:58) [6]

> Sha ©   (12.04.16 15:48) [3]
> Потом по адресу входа определяешь, что надо вызвать.

Да, вот это и надо как бы, но вопрос: в памяти по "адресу входа" должен лежать какой-то разумный код. И так для каждого адреса.


 
KSergey ©   (2016-04-13 09:09) [7]

Возможно в самом деле не достаточно понятно написано.
Попробую еще раз.

Есть код:
   function Func1: Integer;
   begin
   ....
   end;
....
   function Func2: Integer;
   begin
   ....
   end;
....
   function Func3: Integer;
   begin
   ....
   end;
....
....
SetCallbackA(Func1);
SetCallbackB(Func2);
SetCallbackC(Func3);


Хочется получить такое:

   function Func1: Integer;
   begin
   ....
   end;

   function Func1Cover: Integer;
   begin
     try
       Result := Func1;
     except
       .....
     end;
   end;
....
   function Func2: Integer;
   begin
   ....
   end;

   function Func2Cover: Integer;
   begin
     try
       Result := Func2;
     except
       .....
     end;
   end;
....
   function Func3: Integer;
   begin
   ....
   end;

   function Func3Cover: Integer;
   begin
     try
       Result := Func3;
     except
       .....
     end;
   end;
....
....
SetCallbackA(Func1Cover);
SetCallbackB(Func2Cover);
SetCallbackC(Func3Cover);


Т.к. функции-обёртки идентичны, кроме самой вызываемой функции - хотелось бы куража ради придумать хитровыпученный способ, когда бы при вызове некоей

SetCallbackA_My(Func1);

волшебно вокруг Func1 подставлялась (генерировалась) "индивидуальная" (в смысле адреса) обёртка, т.к. никаким параметром, увы, параметризировать вызов не удастся, интерфейс установки call-back"ов за зоной моего влияния.

Есть такой способ - хорошо, нет - ну и ладно.


 
icWasya ©   (2016-04-13 09:39) [8]

И уточни, это всё будет находиться в одном исполняемом файле, в разных (Exe,dll), Какую часть ты можешь модифицировать, какую нет.
Где находится код Func1,FuncX..., где находится код Func1Cover,FuncXCover


 
KSergey ©   (2016-04-13 10:15) [9]

Func1,FuncX...,  - моё (т.е. это мой код, который могу изменить как угодно)
Func1Cover,FuncXCover - моё
Всё это внутри dll, подгружаемой во внешний процесс.

SetCallbackA, SetCallbackB, SetCallbackC - не моё.
Код, который в итоге вызывает зарегистрированные callback"и - не моё, менять ничего в нём не могу.


 
Sha ©   (2016-04-13 12:45) [10]

Что-то вроде этого, например.
Проверил в D7.


unit CoverForm;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   Memo1: TMemo;
   Button1: TButton;
   Button2: TButton;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

type
 TMyFunc= function: integer;

function Func1: integer;
begin;
 Result:=1;
 Form1.Memo1.Lines.Add(IntToStr(Result));
 end;

function Func2: integer;
begin;
 Result:=2;
 Form1.Memo1.Lines.Add(IntToStr(Result));
 end;

var
 Callback: array[1..8] of TMyFunc= (nil, nil, nil, nil, nil, nil, nil, nil);

procedure SetCallback(No: integer; Func: TMyFunc);
begin;
 CallBack[No]:=@Func;
 end;

procedure Run;
begin;
 if Assigned(Callback[1]) then Callback[1];
 if Assigned(Callback[2]) then Callback[2];
 end;

procedure TForm1.Button1Click(Sender: TObject);
begin;
 SetCallback(1,Func1);
 SetCallback(2,Func2);
 Run;
 end;

var
 CoverBase: pAnsiChar= nil;
 CoverCallback: array[1..8] of TMyFunc= (nil, nil, nil, nil, nil, nil, nil, nil);

function Cover(Func: TMyFunc): integer;
var
 p: PAnsiChar;
 i: integer;
begin;
 //получить адрес возврата
 asm
   mov eax,[ebp+4]
   mov p, eax
   end;
 i:=((p-CoverBase)+1) div 6;
 Form1.Memo1.Lines.Add("Enter Cover");
 try
   Result:=CoverCallback[i];
 except
   Result:=0;
   end;
 Form1.Memo1.Lines.Add("Leave Cover");
 end;

procedure CoveredFunc;
asm
 call Cover
 ret
 call Cover
 ret
 call Cover
 ret
 call Cover
 ret
 call Cover
 ret
 call Cover
 ret
 call Cover
 ret
 call Cover
 ret
 end;

procedure SetCoverCallback(No: integer; Func: TMyFunc);
begin;
 CoverCallBack[No]:=Func;
 CoverBase:=@CoveredFunc;
 SetCallback(No, TMyFunc(CoverBase+6*(No-1)));
 end;

procedure TForm1.Button2Click(Sender: TObject);
begin;
 SetCoverCallback(1,Func1);
 SetCoverCallback(2,Func2);
 Run;
 end;

end.


 
Sha ©   (2016-04-13 13:05) [11]

В коде есть пара опечаток:

1. Объявление функции Cover должно удовлетворять типу TMyFunc,
т.е. ее надо объявить так:
function Cover: integer;

2. Где-то в коде собака потерялась. Лучше ее найти. Для строгости.


 
Leonid Troyanovsky ©   (2016-06-02 09:16) [12]


> KSergey ©   (13.04.16 09:09) [7]

> обёртки идентичны, кроме самой вызываемой функции - хотелось
> бы куража ради придумать хитровыпученный способ, когда бы
> при вызове некоейSetCallbackA_My(Func1);волшебно вокруг
> Func1 подставлялась (генерировалась) "индивидуальная" (в
> смысле адреса) обёртка

Проверил в D6.

type
 TProc = procedure;
 TEProc = procedure(E: Exception);

 TModProcs = packed record
   proc1: TProc;
   proc2: TEProc;
   code: PByte;
 end;
 PModProcs=^TModProcs;

procedure Agregate(p1: TProc; p2: TEProc);
begin
 try
   p1;
 except
   on E: Exception do
     p2(E);
 end;
end;

const
 vagr: procedure(p1: TProc; p2: TEProc)= Agregate;

procedure Template(m: PModProcs); register;
begin
 with m^ do
   vagr(proc1, proc2);
end;

type
 TPrecode = packed record
   b8: Byte;
   m: Pointer;
 end;

procedure AddModProc(const p1: TProc; p2: TEProc; var p3: TProc);
var
 procsize: Longint;
 p0, pt: PByte;
 pc: TPrecode;
 pmp: PModProcs;
begin
 New(pmp);
 procsize := Dword(@AddModProc)-Dword(@template)+1;
 pc.b8 := $B8;
 pc.m := pmp;   // mov eax, pmp = B8 00 00 00 00
 with pmp^ do
   begin
     proc1 := p1;
     proc2 := p2;
     GetMem(code, SizeOf(pc)+ procsize);
     pt := code;
     Move(pc.b8, pt^, SizeOf(pc));
     inc(pt, SizeOf(pc));
     p0 := @template;
     Move(p0^, pt^, procsize);
     p3 := @code^;
   end;
end;

procedure a;
begin
 ShowMessage("a: "+IntToStr(GetTickCount));
 abort;
end;

procedure b(E: Exception);
begin
 Application.ShowException(E);
end;

procedure d;
begin
 ShowMessage("a: "+IntToStr(GetTickCount));
 raise Exception.Create("MyException");
end;

procedure TForm1.Button2Click(Sender: TObject);
var
 c, e: TProc;
begin
 AddModProc(a, b, c);
 AddModProc(d, b, e);
 c;
 e;
end;

--
Regards, LVT.


 
KSergey ©   (2016-06-02 09:56) [13]

Ого!
Спасибо, мастера.
Буду изучать.


 
Плохиш ©   (2016-06-02 10:32) [14]

Хм, и для чего только придумывали интерфейсы?


 
ВладОшин ©   (2016-07-04 09:35) [15]

как то надо было сделать быстро нечто похожее - сделал тупо:
положил рядом dcc, писал налету dll, компилил ее, подгружал, получал адрес процы, выполнял, выгружал, удалял.



Страницы: 1 вся ветка

Текущий архив: 2018.06.10;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.004 c
2-1460463897
KSergey
2016-04-12 15:24
2018.06.10
Генерировать функцию во время выполнения


6-1286126664
Сёмсей
2010-10-03 21:24
2018.06.10
Как связать vnc в обход nat proxy


15-1472731971
ВладОшин
2016-09-01 15:12
2018.06.10
бред.. цикл от 0 до -1 как-то зашел в тело


2-1466614978
Sergey
2016-06-22 20:02
2018.06.10
Перевёртывание бит в байте


2-1463998221
ford
2016-05-23 13:10
2018.06.10
TWebBrowser , в режиме редактирования, заменить текст выделения