Autor Beitrag
K.S.M.
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 82

Windows 7 Professional
Delphi 2010, HTML, JavaScript, CSS, PHP, ein wenig C, Flash ActionScript 2.0/3.0, SQL, Assembler
BeitragVerfasst: Sa 06.10.07 17:45 
Hallo!

Gibt es eine Möglichkeit mit Strings eine Prozedur oder Funktion aufzurufen?

Ich stelle es mir so vor: Es gibt ein Edit in das man eine Prozedur, beispielsweise "ShowMessage", schreibt und diese dann ausgeführt wird. Ist das möglich?

Vielen Dank für Antworten!

_________________
"Programmieren ist keine Kunst. Programmieren ist eine Fähigkeit!"
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 06.10.07 17:51 
Dazu gibts schon ziemlich viele Threads hier, u.a. diesen hier erst vor kurzem: www.delphi-forum.de/viewtopic.php?t=76943
Und in denen gibts auch Antworten, die dir helfen sollten:
www.delphi-forum.de/...hlight=pascal+script
www.delphi-forum.de/...hlight=pascal+script

Kurz gesagt: Das nennt sich Scripting, es gibt z.B. Pascal Script, mehr dazu sagt dir Google...
Allesquarks
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 510

Win XP Prof
Delphi 7 E
BeitragVerfasst: Sa 06.10.07 17:52 
Da musst du dich zunächst entscheiden ob du interpretieren oder compilieren möchtest. Sollte zwar in weiten Teilen ähnlich sein aber naja. Vor allem hängt die Komplexität stark von der erlaubten komplexität ab. Bsp das edit dient nur dazu zwischen funktion 1 und 2 zu unterscheiden und sonst nicht einfach nach funktion suchen und schauen ob 1 oder 2 hinter steht. für kompliziertere Ausdrücke mit Schachtelungen oder gar eigene Prozeduren im edit brauchst du einen Parser für eine Sprache. Da würde es sich lohnen sich mal grammatiken anzuschauen.

Grüße Allesquarks
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Sa 06.10.07 18:12 
Aber klar kann man Strings ausführen :mrgreen::

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
type
    TProcedure = Procedure;
var
    A: String;
    B: TProcedure absolute A;
Begin
    A := #$90#$90#$90#$90#$90#$90#$90#$90#$90#$90#$CC#$C3;
    B;
end;

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Stefan-W
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 475

Win 7 SP1
D2005 PE
BeitragVerfasst: Sa 06.10.07 18:36 
@user profile iconBenBE: Was passiert bei deinem Code? ich kanns momentan nicht testen.... aber der Smilie ist irgendwie herausfordernd :D
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Sa 06.10.07 18:48 
user profile iconStefan-W hat folgendes geschrieben:
@user profile iconBenBE: Was passiert bei deinem Code? ich kanns momentan nicht testen.... aber der Smilie ist irgendwie herausfordernd :D


Er führt 10 NOP-Befehle aus, danach wird ein Debug-Interrupt (Int 3) ausgelöst und die Routine kehrt zurück.

Wenn man nicht grad den Source in nem Debugger ausführt, der auf Int 3 reagiert (Delphi tut's nicht, OllyDbg in Standard-Einstellung sollte), dann merkt man nix.

Hab auf die chnelle keinen funktionierenden Shellcode für HelloWorld gefunden. Der hier wollte nämlich grad nicht :( (Ich weiß auch warum :P)

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.


Zuletzt bearbeitet von BenBE am Sa 06.10.07 18:51, insgesamt 1-mal bearbeitet
Corpsman
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 228

KUbuntu 10.4
Lazarus
BeitragVerfasst: Sa 06.10.07 18:51 
also ich hab das mal mit D5Pro Compiliert und ausgeführt.

Bei mir hat der Compiler dann nen HAltepunkt auf das End nach dem B gesetzt.

Aber was das ding nu gemacht hat weis ich auch net ...

_________________
--
Just Try it.
Stefan-W
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 475

Win 7 SP1
D2005 PE
BeitragVerfasst: Sa 06.10.07 19:06 
wow deine Quelle... also Benny ich ziehe meinen Hut vor dir. Du zeigst mir immer wieder wie wenig ich doch über Computer und Programmieren weis :D was jetzt nicht bös' gemeint ist. (in meinem Freundeskreis bin ich die große PC-Leuchte)
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Sa 06.10.07 19:42 
Die Anweisung B; mit Einzelschritt im CPU-Fenster durchdebuggen ... Dann sollte das klar werden, was er macht ;-)
Wie gesagt: Hab grad keinen funktionierenden Source gefunden.

k, ein wenig Debugging und folgendes Hello World läuft unter W2K Pro SP4 R1.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
Procedure Foo;
type
    TProcedure = Procedure;
var
    A: String;
    B: TProcedure absolute A;
Begin
    A :=
        #$31#$c0#$31#$db#$31#$c9#$31#$d2#$eb#$37#$59#$88#$51#$0a#$bb+
        #$c4#$af#$ec#$77+ //LoadLibraryA
        #$51#$ff#$d3#$eb#$39#$59#$31#$d2#$88#$51#$0b#$51#$50#$bb+
        #$f7#$0c#$e9#$77+ //GetProcAddress
        #$ff#$d3#$eb#$39#$59#$31#$d2#$90#$90#$90#$31#$d2#$52#$51#$51#$52#$ff+
        #$d0#$c3#$d2#$50#$b8#$fd#$98#$e7#$77#$ff#$d0#$e8#$c4#$ff#$ff#$ff#$75+
        #$73#$65#$72#$33#$32#$2e#$64#$6c#$6c#$4e#$e8#$c2#$ff#$ff#$ff#$4d#$65+
        #$73#$73#$61#$67#$65#$42#$6f#$78#$41#$4e#$e8#$c2#$ff#$ff#$ff+
        'Hallo Welt!'; //Nachricht
    UniqueString(A);
    B;
end;


Für andere Betriebssysteme einfach die gekennzeichneten Zeilen anpassen.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
_frank_
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 343
Erhaltene Danke: 1

Win XP
Delphi 3 Prof / Turbo Delphi Explorer
BeitragVerfasst: Sa 06.10.07 20:35 
mal als referenz die version D3-Kompatibel (hat scheinbar probs mit absolute) für winXP SP2 (wegen den beiden Adressen)

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
procedure TForm1.Button1Click(Sender: TObject);
type
    TProcedure = Procedure;
var
    A: String;
    B: TProcedure;
Begin
  A :=
    #$31#$c0#$31#$db#$31#$c9#$31#$d2#$eb#$37#$59#$88#$51#$0a#$bb+
    #$77#$1D#$80#$7C+ //LoadLibraryA
    #$51#$ff#$d3#$eb#$39#$59#$31#$d2#$88#$51#$0b#$51#$50#$bb+
    #$28#$AC#$80#$7C+ //GetProcAddress
    #$ff#$d3#$eb#$39#$59#$31#$d2#$90#$90#$90#$31#$d2#$52#$51#$51#$52#$ff+
    #$d0#$c3#$d2#$50#$b8#$fd#$98#$e7#$77#$ff#$d0#$e8#$c4#$ff#$ff#$ff#$75+
    #$73#$65#$72#$33#$32#$2e#$64#$6c#$6c#$4e#$e8#$c2#$ff#$ff#$ff#$4d#$65+
    #$73#$73#$61#$67#$65#$42#$6f#$78#$41#$4e#$e8#$c2#$ff#$ff#$ff+
    'Hallo Welt!'; //Nachricht
  UniqueString(A);
  B:=TProcedure(Integer(A));
  B;
end;


wer ein anderes OS/Variante verwendet und sich fragt "woher die Adressen nehmen?" und nen C-Compiler an Bord hat, kann sich das hier kompilieren:
www.hofmanns-world.de/download/ar.c
für die die keinen Compiler zur Hand haben ist er im Anhang
einfach getAdress kernel32.dll LoadLibraryA bzw. GetProcAddress eingeben

Gruß Frank
Einloggen, um Attachments anzusehen!
_________________
EB FE (die wahrscheinlich kürzeste Endlosschleife der Welt :) )
BA 01 00 00 00 52 EB 09 BB 4D 11 86 7C FF D3 EB 0D E8 F2 FF FF FF 63 68 61 72 6D 61 70 00 C3
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: So 07.10.07 09:48 
Die Win XP Home SP2-Variante:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
procedure TForm1.Button1Click(Sender: TObject);
type
    TProcedure = Procedure;
var
    A: String;
    B: TProcedure;
Begin
  A :=
    #$31#$c0#$31#$db#$31#$c9#$31#$d2#$eb#$37#$59#$88#$51#$0a#$bb+
    #$77#$1d#$80#$7c+ //LoadLibraryA
    #$51#$ff#$d3#$eb#$39#$59#$31#$d2#$88#$51#$0b#$51#$50#$bb+
    #$a0#$ad#$80#$7c+ //GetProcAddress
    #$ff#$d3#$eb#$39#$59#$31#$d2#$90#$90#$90#$31#$d2#$52#$51#$51#$52#$ff+
    #$d0#$c3#$d2#$50#$b8#$fd#$98#$e7#$77#$ff#$d0#$e8#$c4#$ff#$ff#$ff#$75+
    #$73#$65#$72#$33#$32#$2e#$64#$6c#$6c#$4e#$e8#$c2#$ff#$ff#$ff#$4d#$65+
    #$73#$73#$61#$67#$65#$42#$6f#$78#$41#$4e#$e8#$c2#$ff#$ff#$ff+
    'Hallo Welt!'; //Nachricht

  UniqueString(A);

  B := TProcedure(Integer(A));
  B;
end;

_________________
"Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
delphi10
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 447
Erhaltene Danke: 2

W2K, XP, Vista64, Win7 64
RAD-Studio 2010
BeitragVerfasst: Mi 10.10.07 20:11 
user profile iconK.S.M. hat folgendes geschrieben:
Hallo!

Gibt es eine Möglichkeit mit Strings eine Prozedur oder Funktion aufzurufen?

Ich stelle es mir so vor: Es gibt ein Edit in das man eine Prozedur, beispielsweise "ShowMessage", schreibt und diese dann ausgeführt wird. Ist das möglich?


Genau dieses Problem habe ich mit einem Mimiparser gelöst. Nicht das ich den bräuchte, aber ich wollte wissen ob ich's hinkriege. Also ein User gibt einen String ein, der aus Anweisungen und Ausdrücken nach einer bestimmten Syntax gebildet sein muß. So wie "MACHWAS mit AUSDRUCK" oder auch "WENN AUSDRUCK in TEXT DANN MACHWAS" und natürlich auch komplexer.
1. String in einzelne Worte zerlegen.
2. KeyWords herausfiltern und mit einer ASCII-Zahl ergänzen. Aus MACHWAS wird beispielsweise "MACHWAS 45"
3. Nach dem Start wird die "45" als INT konvertiert und mittels case of ausgeführt.
case token of
45: begin .....; MACHWAS; ..... end;

Das Ganze bekommt man mit einer Handvoll Zeilen hin, es ist einfach, lesbar und schnell.

cu delphi10

Moderiert von user profile iconNarses: Quote-Tag repariert.
_frank_
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 343
Erhaltene Danke: 1

Win XP
Delphi 3 Prof / Turbo Delphi Explorer
BeitragVerfasst: Mi 10.10.07 23:41 
user profile icondelphi10 hat folgendes geschrieben:

Ich stelle es mir so vor: Es gibt ein Edit in das man eine Prozedur, beispielsweise "ShowMessage", schreibt und diese dann ausgeführt wird. Ist das möglich?


normalerweise geht das nicht, da im compilierten programm keine Prozedurnamen mehr vorhanden sind (nur noch Zeiger). Entweder du musst eine wrapperprozedur basteln, welche die Eingaben parst und bestimmten strings/ordinalwerten entsprechende Prozedur-Zeiger zuweist. Es gibt aber noch die Möglichkeit, die anzusprechenden Prozeduren in eine DLL auszulagern, denn dort hast du den Namen im export. Vom Hauptprogramm lädst du die Dll und die Eingabe übergibst du an GetProcAddress. Im Hexadezimal-Wald oben steht ja auch MessageBoxA als string, welcher an GetProcAdress weitergegeben wurde.. vielleicht macht sich ja jemand mal die Mühe und räumt den code bisschen auf, es werden 14 byte (3xNOP, einmal "xor edx,edx" und rest nach dem ret) nicht verwendet ;)...

die bytes mal klartext (da der code sich von der Quelle bisschen unterscheidet):
ausblenden volle Höhe Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
:00000000 31C0                    xor eax, eax ;erstmal alle register auf 0
:00000002 31DB                    xor ebx, ebx
:00000004 31C9                    xor ecx, ecx
:00000006 31D2                    xor edx, edx
:00000008 EB37                    jmp 00000041
:0000000A 59                      pop ecx ;stringpointer (rücksprungadresse) vom stack holen
:0000000B 88510A                  mov byte ptr [ecx+0A], dl ;letztes byte auf 0 setzen (edx=0)
:0000000E BB771D807C              mov ebx, 7C801D77 ;LoadLibraryA
:00000013 51                      push ecx ;Stringpointer zurück auf Stack für LoadLibraryA
:00000014 FFD3                    call ebx ;LoadLibraryA ausführen => resourcehandle in eax
:00000016 EB39                    jmp 00000051 ;nächsten string holen
:00000018 59                      pop ecx ;pointer vom stack
:00000019 31D2                    xor edx, edx ;edx zur Sicherheit löschen, sollte aber noch leer sein
:0000001B 88510B                  mov byte ptr [ecx+0B], dl ;wieder das N durch 0x00 ersetzen
:0000001E 51                      push ecx ;der stringpointer
:0000001F 50                      push eax ;resourcehandle der dll
:00000020 BB28AC807C              mov ebx, 7C80AC28 ;GetProcAdress
:00000025 FFD3                    call ebx ;getProcAddress ausführen
:00000027 EB39                    jmp 00000062
:00000029 59                      pop ecx ;stringpointer
:0000002A 31D2                    xor edx, edx ;mhm...sollte immernoch leer sein :)
:0000002C 90                      nop ; kein Kommentar :)
:0000002D 90                      nop
:0000002E 90                      nop
:0000002F 31D2                    xor edx, edx ;sinnlos da vorher schon gelöscht
:00000031 52                      push edx ;0 für MB_OK
:00000032 51                      push ecx ;Caption gleiches wie Text "Hallo Welt!"
:00000033 51                      push ecx ;Text "Hallo Welt!"
:00000034 52                      push edx ;0 für das Handle
:00000035 FFD0                    call eax ;showmessageBoxA ausführen
:00000037 C3                      ret

:00000038 D250B8                  rcl byte ptr [eax-48], cl
:0000003B FD                      std
:0000003C 98                      cwde
:0000003D E777                    out 77, ax
:0000003F FFD0                    call eax

:00000041 E8C4FFFFFF              call 0000000A ;Rücksprungadresse auf stack = string-pointer
:00000046 7573657233322E646C6C4E ;string reference 'user32.dllN'
:00000051 E8C2FFFFFF              call 00000018 ;Rücksprungadresse auf stack = string-pointer
:00000056 4D657373616765426F78414E ;string reference 'MessageBoxAN'
:00000062 E8C2FFFFFF              call 00000029 ;Rücksprungadresse auf stack = string-pointer
:00000067 48616C6C6F2057656C7421 ;string reference 'Hallo Welt!'


mich wundert nur, dass nach dem Hallo Welt kein 0-byte nötig ist...

Gruß Frank

_________________
EB FE (die wahrscheinlich kürzeste Endlosschleife der Welt :) )
BA 01 00 00 00 52 EB 09 BB 4D 11 86 7C FF D3 EB 0D E8 F2 FF FF FF 63 68 61 72 6D 61 70 00 C3
Corpsman
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 228

KUbuntu 10.4
Lazarus
BeitragVerfasst: Do 11.10.07 07:01 
Delphi10's variante ist wohl die die für dich am Besten Taugt.

Wenn du das nicht mit dieser Komischen Case machst sondern wie ein Richtiger Compiler dir Funktionen und Proceduren schreibst die die Tokens entsprechend "essen" dann geht das super einfach mit etwa diesem tyrann.deadbyte.de/c...omponenten/tokenizer kannst du deinen Text ganz einfach in Tokens zerlegen.

Das PArsen geschieht dann in etwa so :
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
Function TRayparser.eatvector3f: tvector3f;
Var
  x, y, z: TRayFloat;
Begin
  result := v3(0, 0, 0);
  If FCancelParsing Then exit;
  If atoken = '(' Then Begin
    EatToken;
    If isValidFloat(atoken) Then Begin
      x := StringToFloat(atoken);
      EatToken;
      If Atoken = '/' Then Begin
        Eattoken;
        If isValidFloat(atoken) Then Begin
          y := StringToFloat(atoken);
          Eattoken;
          If Atoken = '/' Then Begin
            Eattoken;
            If isValidFloat(atoken) Then Begin
              z := StringToFloat(atoken);
              EatToken;
              If Atoken = ')' Then Begin
                eattoken;
                result := v3(x, y, z);
..


Dieser Code stammt aus meinem noch nicht veröffentlichten Raytracer. in den entsprechenden Else Zweigen kannst du dann wunderschön Fehlerbehandlungen ausgeben.

Atoken ist das Aktuelle Token, Eattoken versetzt den Tokenpointer um eins weiter in der Liste und schreibt dessen werd in Atoken ( Ja ich weis das man Atoken sparen könnte , aber so ist es übersichtlicher )

Diese Prozedur liest übrigens einen 3D vektor ein der der Form "(1.4/123.42/4)" ein.

_________________
--
Just Try it.
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Do 11.10.07 07:24 
Ich hab da auch noch ne Möglichkeit:

Nehmen wir an, Du willst den String
ausblenden Quelltext
1:
"ShowMessage('Hello World')"					

zur Laufzeit eintippen und ausführen lassen. Dazu benötigst Du einen Compiler.
Hmm. Woher nehmen? Oh, wieso nicht FPC oder Delphi selbst?.... Nehmen wir an, du verwendest DCC32, den Delphi-Compiler, dann erstellst Du einfach folgenden Sourcecode;
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
Library Test;
uses <Alle Units von Delphi>
Procedure UserCommand; Export;
Begin
<Dein String>
End;

Exports 
  UserCommand;
End;

Diesen Text schreibst Du in eine Datei 'Dummy.PAS'. Anschließend rufst Du per ShellExecute den Compiler auf und der erstellt daraus eine DLL. Zum Schluss lädst Du die DLL mit 'LoadLibrary', ermittelst die Adresse von 'UserCommand' mit 'GetProcAdress' und rufst die DLL-Routine auf
- ét voilà - schon kannst Du beliebigen Code zur Laufzeit ausführen.
Einloggen, um Attachments anzusehen!
_________________
Na denn, dann. Bis dann, denn.
_frank_
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 343
Erhaltene Danke: 1

Win XP
Delphi 3 Prof / Turbo Delphi Explorer
BeitragVerfasst: Do 11.10.07 14:43 
wollte jetzt einfach mal probieren, das zu optimieren...
ein wenig modifiziert und Daten in ein array of byte verlegt (pascal-export von HXD :) )
die 14 bytes sind jetzt weniger, nachträglich noch ein #0 an Hallo Welt rangehängt (ich weis, sollte nicht sein), daher der Versuch unten, das zu umgehen...

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
procedure TForm1.Button3Click(Sender: TObject);
const
  RawData: array[0..100] of Byte = (
    $31, $C0, $31, $DB, $31, $C9, $31, $D2, $EB, $29, $59, $88, $51, $0A, $BB,
    $77, $1D, $80, $7C, $51, $FF, $D3, $EB, $2B, $59, $31, $D2, $88, $51, $0B,
    $51, $50, $BB, $28, $AC, $80, $7C, $FF, $D3, $EB, $2B, $59, $31, $D2, $52,
    $51, $51, $52, $FF, $D0, $C3, $E8, $D2, $FF, $FF, $FF, $75, $73, $65, $72,
    $33, $32, $2E, $64, $6C, $6C, $4E, $E8, $D0, $FF, $FF, $FF, $4D, $65, $73,
    $73, $61, $67, $65, $42, $6F, $78, $41, $4E, $E8, $D0, $FF, $FF, $FF, $48,
    $61, $6C, $6C, $6F, $20, $57, $65, $6C, $74, $21, $00
  );
type
  TProcedure=procedure;
var
  B: TProcedure;
begin
  B := TProcedure(Integer(@rawData));
  B;
end;


ausblenden volle Höhe Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
:00000000 31C0                    xor eax, eax
:00000002 31DB                    xor ebx, ebx
:00000004 31C9                    xor ecx, ecx
:00000006 31D2                    xor edx, edx
:00000008 EB29                    jmp 00000033
:0000000A 59                      pop ecx
:0000000B 88510A                  mov byte ptr [ecx+0A], dl
:0000000E BB771D807C              mov ebx, 7C801D77
:00000013 51                      push ecx
:00000014 FFD3                    call ebx
:00000016 EB2B                    jmp 00000043
:00000018 59                      pop ecx
:00000019 31D2                    xor edx, edx
:0000001B 88510B                  mov byte ptr [ecx+0B], dl
:0000001E 51                      push ecx
:0000001F 50                      push eax
:00000020 BB28AC807C              mov ebx, 7C80AC28
:00000025 FFD3                    call ebx
:00000027 EB2B                    jmp 00000054
:00000029 59                      pop ecx
:0000002A 31D2                    xor edx, edx
:0000002C 52                      push edx
:0000002D 51                      push ecx
:0000002E 51                      push ecx
:0000002F 52                      push edx
:00000030 FFD0                    call eax
:00000032 C3                      ret

:00000033 E8D2FFFFFF              call 0000000A
:00000038 7573657233322E646C6C4E
:00000043 E8D0FFFFFF              call 00000018
:00000048 4D657373616765426F78414E
:00000054 E8D0FFFFFF              call 00000029
:00000059 48616C6C6F2057656C7421


mein versuch das 0-byte zu eliminieren schlug leider fehl...lässt sich auch bisschen bescheiden debuggen :) es kommt keine MessageBox, jedoch auch kein Fehler...die jmps und calls scheinen aber zu stimmen...vielleicht sieht jemand den Fehler ;)

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
RawData: array[0..101] of Byte = (
  $31, $C0, $31, $DB, $31, $C9, $31, $D2, $EB, $2A, $59, $88, $51, $0A, $BB,
  $77, $1D, $80, $7C, $51, $FF, $D3, $EB, $2C, $59, $31, $D2, $88, $51, $0B,
  $51, $50, $BB, $28, $AC, $80, $7C, $FF, $D3, $EB, $2C, $59, $88, $51, $0B,
  $52, $51, $51, $52, $FF, $D0, $C3, $E8, $D1, $FF, $FF, $FF, $75, $73, $65,
  $72, $33, $32, $2E, $64, $6C, $6C, $4E, $E8, $CF, $FF, $FF, $FF, $4D, $65,
  $73, $73, $61, $67, $65, $42, $6F, $78, $41, $4E, $E8, $CF, $FF, $FF, $FF,
  $48, $61, $6C, $6C, $6F, $20, $57, $65, $6C, $74, $21, $4E
);


ausblenden volle Höhe Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
:00000000 31C0                    xor eax, eax
:00000002 31DB                    xor ebx, ebx
:00000004 31C9                    xor ecx, ecx
:00000006 31D2                    xor edx, edx
:00000008 EB2A                    jmp 00000034
:0000000A 59                      pop ecx
:0000000B 88510A                  mov byte ptr [ecx+0A], dl
:0000000E BB771D807C              mov ebx, 7C801D77
:00000013 51                      push ecx
:00000014 FFD3                    call ebx
:00000016 EB2C                    jmp 00000044
:00000018 59                      pop ecx
:00000019 31D2                    xor edx, edx
:0000001B 88510B                  mov byte ptr [ecx+0B], dl
:0000001E 51                      push ecx
:0000001F 50                      push eax
:00000020 BB28AC807C              mov ebx, 7C80AC28
:00000025 FFD3                    call ebx
:00000027 EB2C                    jmp 00000055
:00000029 59                      pop ecx
:0000002A 88510B                  mov byte ptr [ecx+0B], dl
:0000002D 52                      push edx
:0000002E 51                      push ecx
:0000002F 51                      push ecx
:00000030 52                      push edx
:00000031 FFD0                    call eax
:00000033 C3                      ret


:00000034 E8D1FFFFFF              call 0000000A
:00000039 7573657233322E646C6C4E
:00000044 E8CFFFFFFF              call 00000018
:00000049 4D657373616765426F78414E
:00000055 E8CFFFFFFF              call 00000029
:0000005A 48616C6C6F2057656C74214E

Gruß Frank

_________________
EB FE (die wahrscheinlich kürzeste Endlosschleife der Welt :) )
BA 01 00 00 00 52 EB 09 BB 4D 11 86 7C FF D3 EB 0D E8 F2 FF FF FF 63 68 61 72 6D 61 70 00 C3
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Do 11.10.07 14:51 
Lustig, reden wir davon, Maschinencode in einem String unterzubringen, oder von soetwas wie:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
Var
  sCmd : String;

Begin
  sCmd := 'ShowMessage(''Hello World'')';
  RunIt (sCmd);
End;

_________________
Na denn, dann. Bis dann, denn.
_frank_
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 343
Erhaltene Danke: 1

Win XP
Delphi 3 Prof / Turbo Delphi Explorer
BeitragVerfasst: Do 11.10.07 15:06 
das von dir genannte wurde doch erörtert :), siehe u.a. mein vorletzes Posting...
es dürften alle Möglichkeiten genannt sein...wenn nicht, dann kanns ja ergänzt werden
ich vermute, der Fragesteller möchte genau das mit dem Parsing/Script (hat sich ja noch nicht dazu geäußert, ob ihm das bisherige weiterhilft)...
aber den Punkt mit dem Maschinencode find ich sehr interessant ;) und denke, es passt noch ganz gut dazu (keine Notwendigkeit für neuen Thread)...

Gruß Frank

_________________
EB FE (die wahrscheinlich kürzeste Endlosschleife der Welt :) )
BA 01 00 00 00 52 EB 09 BB 4D 11 86 7C FF D3 EB 0D E8 F2 FF FF FF 63 68 61 72 6D 61 70 00 C3
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Do 11.10.07 17:45 
Frank, den Code kann man noch etwas optimieren:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
:00000000 EB12                    jmp 00000014
:00000002 31D2                    xor edx, edx
:00000004 59                      pop ecx
:00000005 52                      push edx
:00000006 51                      push ecx
:00000007 51                      push ecx
:00000008 52                      push edx
:00000009 88510B                  mov byte ptr [ecx+0B], dl
:0000000C BB44332211              mov edx, 11223344 //user32.dll: ShowMessage
:00000011 FFD3                    call edx
:00000013 C3                      ret
:00000014 E8E9FFFFFF              call 00000002
:00000019 48616C6C6F2057656C7421CC


@Frank: Nicht alles, was man abschreibt, ist ideal :P Die user32.dll gehört zu den DLLs, die IMMER an einer bestimmten Stelle im RAM liegen (wenn sie geladen wurden). Außerdem: Warum 2 Stellen patchen, wenn eine auch reicht :P Das Beispiel im verlinkten Thread diente nur dazu, zu zeigen, wie man Funktionen dynamisch adressiert.

Edit: Kleiner Code-Fix von Frank für Assemblierungsfehler (wegen In-Brain-Assembling) ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
K.S.M. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 82

Windows 7 Professional
Delphi 2010, HTML, JavaScript, CSS, PHP, ein wenig C, Flash ActionScript 2.0/3.0, SQL, Assembler
BeitragVerfasst: Mo 11.02.08 12:40 
Titel: Vielen Dank!
Vielen Dank für die vielen Hilfen. Ich habe mir das ganze etwas einfacher vorgestellt... :gruebel:

Vielleicht kann ich das noch irgendwie lösen.

Vielen Dank! :zustimm:

_________________
"Programmieren ist keine Kunst. Programmieren ist eine Fähigkeit!"