AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Adresse eine Funktion / Prozedur ermitteln
Thema durchsuchen
Ansicht
Themen-Optionen

Adresse eine Funktion / Prozedur ermitteln

Ein Thema von Fussball-Robby · begonnen am 15. Jun 2008 · letzter Beitrag vom 10. Dez 2013
Antwort Antwort
Seite 3 von 4     123 4      
static_cast

Registriert seit: 19. Okt 2003
Ort: Peine
300 Beiträge
 
#1

AW: Adresse eine Funktion / Prozedur ermitteln

  Alt 10. Dez 2013, 16:58
Hallo und danke euch zwei für die Antworten

Dachte mir schon das es nicht so einfach ist, aber fragen kostet ja nichts ^^ und da ich jetzt auch kein ASM-Crack bin versuch ich das dann wohl anders umzusetzen, oder ich lass es so und es gibt halt kein x64 build

Viele Grüße
Daniel
Daniel M.
"The WM_NULL message performs no operation. An application sends the WM_NULL message if it wants to post a message that the recipient window will ignore."
  Mit Zitat antworten Zitat
Benutzerbild von Fussball-Robby
Fussball-Robby

Registriert seit: 22. Okt 2007
Ort: Nähe Köln
1.063 Beiträge
 
Delphi 7 Enterprise
 
#2

Re: Adresse eine Funktion / Prozedur ermitteln

  Alt 15. Jun 2008, 17:05
Ich bin hier gerade am verzweifeln..
Ich bekomm es einfach nicht hin, dass die Prozedur ShowString den Parameter mittes ShowMessage richtig ausgibt..Mal gibts ne AV, mal kommt ne leere MessageBox... Könntest du mir villeicht ein kleines Demo machen, ich kriegs einfach nicht hin
Robert L.
Der folgende Satz ist richtig!
Der vorherige Satz ist falsch!

Paradox
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#3

Re: Adresse eine Funktion / Prozedur ermitteln

  Alt 15. Jun 2008, 18:31
Hab dir mal eine Demo angehängt. Hab auch noch einen Fehler korrigiert und die Methode kann jetzt alles außer Variants.

Hier nochmal der komplette Quelltext:
Delphi-Quellcode:
type
  TProcedures = class
  published // Oder Public, dann muss aber der Compilerschalter {$METHODINFO ON} aktiviert sein
    class procedure ShowString(S: String);
    class procedure MegaTest(a: Integer; b: Boolean; c: Char; d: Extended; e: String; f: Pointer;
                             g: PChar; h: TObject; i: TClass; j: WideChar; k: PWideChar;
                             l: AnsiString; m: Currency; n: IUnknown;
                             o: WideString; p: Int64);
    class procedure RunMethod(AMethod: String; Params: Array of Const);
  end;

implementation

class procedure TProcedures.RunMethod(AMethod: String;
  Params: Array of Const);
var proc: Pointer;
    hi: Integer;
    i, off: Integer;
    param: Byte;
begin
  proc := MethodAddress(AMethod);
  hi := High(Params);
  asm
    mov param,0
    mov i,0
    @loop:
      mov eax,i
      cmp eax,hi
      jg @loopend
        imul eax,i,8
        add eax,4
        mov off,eax

        mov eax,[Params]
        add eax,off
        movzx ax,byte ptr [eax]

        cmp ax,vtExtended
        je @EditParam
          cmp ax,vtInt64
          je @EditParam
          cmp ax,vtCurrency
          je @EditParam
          inc param
          cmp param,2
          jle @NextLoop
        @EditParam:
          sub off,4
          cmp ax,vtExtended
          jne @NoExt
            mov eax,[Params]
            add eax,off
            mov eax,[eax]
            movzx edx, word ptr [eax+$08]
            push edx
            push [eax+$04]
            push [eax]
            jmp @NextLoop
          @NoExt:
            cmp ax,vtInt64
            je @Int64Currency
            cmp ax,vtCurrency
            je @Int64Currency
            cmp ax,vtChar
            je @Char
            @Standard:
              mov eax,[Params]
              add eax,off
              push [eax]
              jmp @NextLoop
            @Char:
              mov eax,[Params]
              add eax,off
              mov eax,[eax]
              xor edx,edx
              mov dl,al
              push edx
              jmp @NextLoop
            @Int64Currency:
              mov eax,[Params]
              add eax,off
              mov eax,[eax]
              push [eax+$04]
              push [eax]
        @NextLoop:
          inc i
          jmp @loop
    @loopend:

    mov param,0
    mov i,0
    @loop2:
      mov eax,i
      cmp eax,hi
      jg @loop2end
        imul eax,i,8
        add eax,4
        mov off,eax

        mov eax,[Params]
        add eax,off
        movzx ax,byte ptr [eax]

        cmp ax,vtExtended
        je @NextLoop2
        cmp ax,vtInt64
        je @NextLoop2
        cmp ax,vtCurrency
        je @NextLoop2
        
        inc param

        cmp param,1
        je @edx
        cmp param,2
        je @ecx
        jmp @loop2end

        @edx:
          sub off,4
          mov eax,[Params]
          add eax,off
          mov edx,[eax]
          jmp @NextLoop2
        @ecx:
          sub off,4
          mov eax,[Params]
          add eax,off
          mov ecx,[eax]
          jmp @Loop2End
      @NextLoop2:
        inc i
        jmp @loop2
    @loop2end:

    mov eax,Self
    call proc
  end;
end;

class procedure TProcedures.ShowString(S: String);
begin
  ShowMessage(S);
end;

class procedure TProcedures.MegaTest(a: Integer; b: Boolean; c: Char; d: Extended;
  e: String; f: Pointer; g: PChar; h: TObject; i: TClass; j: WideChar;
  k: PWideChar; l: AnsiString; m: Currency; n: IInterface;
  o: WideString; p: Int64);
begin
  ShowMessage(Format('a: %d'#13#10 // Integer
                   + 'b: %d'#13#10 // Boolean (auf Integer gecastet)
                   + 'c: %s'#13#10 // Char
                   + 'd: %f'#13#10 // Extended (Single,Double)
                   + 'e: %s'#13#10 // String
                   + 'f: %p'#13#10 // Pointer
                   + 'g: %s'#13#10 // PChar
                   + 'h: %s'#13#10 // TObject (Classname)
                   + 'i: %s'#13#10 // TClass (Classname)
                   + 'j: %d'#13#10 // WideChar
                   + 'k: %s'#13#10 // PWideChar
                   + 'l: %s'#13#10 // AnsiString
                   + 'm: %f'#13#10 // Currency
                   + 'n: %d'#13#10 // Interface
                   + 'o: %s'#13#10 // WideString
                   + 'p: %d'#13#10,// Int64
                   [a,Integer(b),c,d,e,f,g,h.ClassName,i.ClassName,Word(j),k,l,m,Integer(n),o,p]));
end;
Aufruf:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  TProcedures.RunMethod('ShowString',['Test']);
end;

// Der utlimative Test/Beweis für das funktionieren meiner Methode :P
// Gibt man konkrete Werte an, muss z.T. gecastet werden, da der Compiler
// z.B. 123456789 ohne den Cast auf Int64 als normalen Integer behandelt
// ==> Exception!
// Man muss halt entweder casten oder int64 variablen etc übergeben.
// Das gleiche gilt auch noch für ein paar andere Typen, aber das kann man unten
// ja ablesen
//
// PS: Das bei dem Interface '0' angezeigt wird, ist schon richtig so ;)
procedure TForm1.Button2Click(Sender: TObject);
var x: IUnknown;
    curr: Currency;
    pwc : PWideCHar;
begin
  curr := 999;
  pwc := 'WideChar Welt';
  TProcedures.RunMethod('MegaTest',[22,true,'c',123.456,'Hallo Welt',Pointer($ABCDEF),
                        'Hallo Welt 2',Form1,TButton,WideChar('w'),pwc,
                        'En Ansistring',curr,x,WideString('B r e i t e r S t r i n g *g*'),
                         Int64(123456789)]);
end;
Gruß
Neutral General
Angehängte Dateien
Dateityp: rar runmethod_demo_301.rar (167,2 KB, 28x aufgerufen)
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
BlueWonder

Registriert seit: 20. Jun 2008
4 Beiträge
 
Delphi 2006 Architect
 
#4

Re: Adresse eine Funktion / Prozedur ermitteln

  Alt 20. Jun 2008, 10:44
Ich hätte da noch eine etwas einfachere Lösung. Also ohne Assembler. Dabei stellt "TDynMethod" die Signatur der aufzurufenden Methoden dar und die Adresse der gesuchten Methode kommt in eine Variable vom Typ "TMethod" und wird anschließend in den Typ "TDynMethod" gecastet und hier auch gleich ausgeführt. Hab allerdings nicht explizit alle Datentypen durchprobiert. Da der Auffruf aber nicht aus der Applikation raus geht, sollten eigentlich alle Parameter-Typen funktionieren.

Delphi-Quellcode:
unit Unit3;

{$METHODINFO ON}

interface

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

type

  TDynMethod = function(s: String):String of object;

  TForm3 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    procedure execMyMethod(name: String);
    function m1(value: String): String;
    function m2(value: String): String;
  end;

var
  Form3: TForm3;

implementation

{$R *.dfm}


procedure TForm3.execMyMethod(name: string);
var
  dMethode: TMethod;
begin
  dMethode.Data := Self; // Objekt zu dem die Methode gehört
  dMethode.Code := Self.MethodAddress(name); // Adresse der gesuchten Methode
  if (dMethode.Code <> nil) then
    ShowMessage(TDynMethod(dMethode)('Teststring')) // Type-Cast und sofortiger Aufruf mit einem sinnlosen String :)
  else
    ShowMessage('Die angegebene Methode wurde nicht gefunden!');
end;


function TForm3.m1(value: string): String;
begin
  Result := 'Ich bin Methode 1 und übergeben wurde: ' + value;
end;


function TForm3.m2(value: string): String;
begin
  Result := 'Ich bin Methode 2 und übergeben wurde: ' + value;
end;


procedure TForm3.Button1Click(Sender: TObject);
begin
  execMyMethod(Edit1.Text);
end;

end.
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

Re: Adresse eine Funktion / Prozedur ermitteln

  Alt 20. Jun 2008, 11:26
Klar, aber das funktioniert nur wenn die Signatur der Methoden immer gleich ist.

Wenn du ne Methode hast in der ein Integer übergeben wird statt einem String oder mehrere Parameter dann stößt du damit schnell an Grenzen.
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.993 Beiträge
 
Delphi 7 Professional
 
#6

Re: Adresse eine Funktion / Prozedur ermitteln

  Alt 20. Jun 2008, 11:40
Moin, Moin,
mal die vermutlich geniale technische Lösung ausser Acht gelassen:

Ich habe (sofern ich die Aufgabenstellung richtig verstanden habe) Zweifel am Grundkonzept. Der Anwender soll im Freitext den Namen einer fest verdrahteten Func/Proc eingeben, die dann aufgerufen wird? Seltsam!

Da der "Befehlsvorrat" fest vorgegeben ist, wäre es doch viel effizienter wenn der Anwender aus dem Befehlsvorrat auswählen könnte. Also Listbox, Combobox - whatever. Das ist schneller, einfacher und schließt Fehler aus.
Ralph
  Mit Zitat antworten Zitat
BlueWonder

Registriert seit: 20. Jun 2008
4 Beiträge
 
Delphi 2006 Architect
 
#7

Re: Adresse eine Funktion / Prozedur ermitteln

  Alt 20. Jun 2008, 11:53
@NeutralGeneral:
Nach etwas grübeln, versteh ich jetzt glaub was du meinst. Jetzt steig ich auch langsam dahinter, was der ASM-Code genau bewirkt. Muss ich zugeben, is ne clevere Sache. Bei mir hat es bisher diese Unterschiede so nich gegeben, deswegen reichte mir eine feste Signatur, wo eben nur jede Methode ihre spezielle Arbeit verrichtet. Dann möchte ich mich für meinen Post entschuldigen und den mal so als Alternative für simple Sachen stehen lassen.

@taaktaak:
Der Sinn dieser ganzen Sache kann sich über mehrere Bereiche Verteilen. Zum Beispiel kann in ein Programm eine Art Konsole eingebaut werden, in welcher der Benutzer Befehle eintippen kann, die dann ausgeführt werden. (wie zb. "clear" um den Inhalt zu löschen) Der Funktionsumfang könnte durchaus so groß werden, dass er in List-Boxen nicht mehr recht überschaubar wäre. Außerdem verstößt das gegen das Grundlayout einer Konsole.
Oder aber das Programm bekommt ein Objekt übergeben, von dem es die genaue Klassenbeschreibung nicht kennt. Wohl aber weiß oder mitgeteilt bekommt, dass dieses Objekt die Methode "bla" enthält und diese Aufzurufen ist.
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#8

Re: Adresse eine Funktion / Prozedur ermitteln

  Alt 20. Jun 2008, 12:39
Hi BlueWonder,

Brauchst dich nicht zu entschuldigen Hast mich ja nicht irgendwie angegriffen oder so

Gruß
Neutral General
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
Vjay

Registriert seit: 2. Dez 2003
Ort: Berlin/Eschede
481 Beiträge
 
Delphi 7 Professional
 
#9

Re: Adresse eine Funktion / Prozedur ermitteln

  Alt 20. Jun 2008, 13:09
Hi, mal eine Frage dazu ob das prinzipiell möglich ist.

Ich habe schon lange mal vorgehabt (ist halt immer an keiner Zeit oder Faulheit gescheitert) ein Programm zu schreiben, welches auf Plugins und Events basiert und deren SInn es ist diese zusammen zu bringen. Ein Beispiel, es gibt eine DLL, welche Hooking benutzt um den Fenstermanager zu überwachen bzw. Events zu abonieren in der DLL, andererseits stellt sie Funktionen bereit um z.B. Mausklicks oder Tastatureingaben zu simulieren (diese bräuchten z.B. ein Handle als Ausgangsbasis). Nun hat man z.B. dieses Windowplugin, ein http Plugin, ein Comportplugin, ein Timerplugin, ein Systemplugin, ein Dateiplugin, etc pp.

Jetzt habe ich als Benutzer der Anwendung das spontane Problem, dass ich als Beispiel auf einen langen Download warten muss und ins Bett möchte. Also öffne ich schnell das Einstellungsfenster des Programms, ziehe ein Event vom Windowplugin hinein, lege fest, ich möchte Informiert werden wenn ein Fenster geschlossen wird, lege als Filter die Caption fest, ziehe das Herunterfahren Symbol vom Systemplugin hinein, sage herunterfahren + ausschalten und verknüpfe diese beiden Symbole und fertig.

So, ewig lange ausgeholt, tut mir leid. Das Problem an der Geschichte ist bisher, dass einige Funktionen ja Übergabeparameter erwarten/zurückliefern, wie ein Fensterhandle z.B. Diese müsste man ja quasi mitverknüpfen. Als Beispiel WindowEventFensterGeöffnet(HWND)->SimuliereMausklickAufFenster(HWND) oder WindEventFensterGeöffnet(HWND)->FindWindowObjekt(HWND)->SimuliereMausklickAufFenster(HWND) um woanders hin zu klicken.

Ist es irgendwie möglich Prozeduren währned der Laufzeit in diese Richtung zu analysieren welche Parameter sie erwarten? Es müssten ja (automatisiert) Zuweisungen und evtl sogar impliziert Typecasts erfolgen. Ich hatte damals(5 Jahre etwa) mit Variants mal gestartet, aber abgebrochen, da es in unendliche Komplexität ausgeartet ist.
Wer später bremst ist eher tot.
  Mit Zitat antworten Zitat
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.749 Beiträge
 
Delphi 2007 Professional
 
#10

Re: Adresse eine Funktion / Prozedur ermitteln

  Alt 20. Jun 2008, 13:10
Zitat von Fussball-Robby:
Naja, dann mach ich mich mal ans if..then..else tippen.. Wenn jemand noch eine Idee hat, immer her damit.
Ich würde statt einer if-then-else-Wüste eine TStringList o.ä. nehmen, bei der du die Prozedurzeiger in .Objects reinstopfst.

HTH,
Uli.
Uli Gerhardt
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 4     123 4      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:43 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz