Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Compiler ändert asm Code ? (https://www.delphipraxis.net/140239-compiler-aendert-asm-code.html)

TKC 14. Sep 2009 10:47


Compiler ändert asm Code ?
 
Hallo,

ich benutze folgende Funktion um meinen Hook zu überspringen.

Delphi-Quellcode:
function xPostMessage(hWnd: hWnd; Msg: UINT; wParam: wParam; lParam: lParam): BOOL; stdcall;
asm
      mov edi, edi
      push ebp
      mov ebp, esp
      jmp OldDllFunc
end;
Warum macht der Compiler dann folgenden Code daraus, bzw. wie kann ich verhindern das er es macht ?

Code:
003A5C60 G> $  55                push   ebp
003A5C61    . 8BEC             mov    ebp, esp
003A5C63    . 89FF             mov    edi, edi
003A5C65    . 55                push   ebp
003A5C66    . 89E5              mov    ebp, esp
003A5C68    . FF25 70FF3A00     jmp    near dword ptr [3AFF70]
Wie man sieht hat er einiges geändert.

Apollonius 14. Sep 2009 10:53

Re: Compiler ändert asm Code ?
 
Ich finde das auch extrem lästig. In C++ würde man das mit __declspec(naked) lösen; in Delphi gibt es das nicht. Als hässlichen Workaround kannst du die Parameter sowie das stdcall weglassen. Wenn du die Funktion dann aus Delphi-Code aufrufen willst, nimmst du @xPostMessage und castest in einen entsprechenden Funktionszeigertypen, sodass du die Funktion mit Parametern aufrufen kannst.

Muetze1 14. Sep 2009 11:07

Re: Compiler ändert asm Code ?
 
Schlüsselwort [oh]assembler;[/oh] vor stdcall; angeben.

gammatester 14. Sep 2009 11:32

Re: Compiler ändert asm Code ?
 
Was ist der Sinn von mov edi, edi?
Meinst Du mov edi, [edi]?

Apollonius 14. Sep 2009 11:38

Re: Compiler ändert asm Code ?
 
mov edi, edi steht auch am Anfang der meisten WinAPI-Funktionen und erleichtert erneutes Hooken - zumindest, wenn sich vor der Funktion noch fünf ungenutzte Bytes befinden.

sirius 14. Sep 2009 12:19

Re: Compiler ändert asm Code ?
 
Zitat:

Zitat von Muetze1
Schlüsselwort [oh]assembler;[/oh] vor stdcall; angeben.

Und in welchen Delphi-Versionen funktioniert das? In D7 schon mal nicht.

TKC 14. Sep 2009 13:32

Re: Compiler ändert asm Code ?
 
Zitat:

Zitat von Muetze1
Schlüsselwort [oh]assembler;[/oh] vor stdcall; angeben.

Also in Delphi 2010 funktioniert das auch nicht !

TKC 14. Sep 2009 13:32

Re: Compiler ändert asm Code ?
 
Zitat:

Zitat von Apollonius
Ich finde das auch extrem lästig. In C++ würde man das mit __declspec(naked) lösen; in Delphi gibt es das nicht. Als hässlichen Workaround kannst du die Parameter sowie das stdcall weglassen. Wenn du die Funktion dann aus Delphi-Code aufrufen willst, nimmst du @xPostMessage und castest in einen entsprechenden Funktionszeigertypen, sodass du die Funktion mit Parametern aufrufen kannst.

Klingt etwas umständlich aber ich werde es einmal versuchen.

TKC 14. Sep 2009 13:36

Re: Compiler ändert asm Code ?
 
Also ich hab jetzt ne einfache Möglichkeit gefunden.

wenn ich es so mache ...
Delphi-Quellcode:
function xPostMessage(hWnd: hWnd; Msg: UINT; wParam: wParam; lParam: lParam): BOOL; stdcall;
 asm
      mov edi, edi
      jmp OldDllFunc
end;
wird daraus ...

Code:
003A5C60 G> $  55                push   ebp
003A5C61    . 8BEC             mov    ebp, esp
003A5C63    . 89FF             mov    edi, edi
003A5C65    . FF25 70FF3A00     jmp    near dword ptr [3AFF70]
und es funktioniert.

Apollonius 14. Sep 2009 13:44

Re: Compiler ändert asm Code ?
 
Das ändert am zugrunde liegenden Problem rein gar nichts. Nebenbei bemerkt kannst du dein mov edi, edi jetzt tatsächlich ersatzlos streichen.

Neutral General 14. Sep 2009 13:45

Re: Compiler ändert asm Code ?
 
Hi,

Zitat:

wird daraus ...

Delphi-Quellcode:
003A5C60 G> $  55                push   ebp
003A5C61    . 8BEC             mov    ebp, esp
003A5C63    . 89FF             mov    edi, edi
003A5C65    . FF25 70FF3A00     jmp    near dword ptr [3AFF70]

Ich weiß nicht warum das noch niemand so direkt gesagt hat. Aber der Compiler ändert gar nichts ;)

Das

Delphi-Quellcode:
push ebp
mov ebp, esp
gehört zu der stdcall Aufrufkonvention und wird vom compiler automatisch erzeugt. Also das hat schon alles so seine Richtigkeit ;)

TKC 14. Sep 2009 13:52

Re: Compiler ändert asm Code ?
 
Zitat:

Zitat von Apollonius
Das ändert am zugrunde liegenden Problem rein gar nichts. Nebenbei bemerkt kannst du dein mov edi, edi jetzt tatsächlich ersatzlos streichen.

Stimmt natürlich ... hatte ich eben selbst gemerkt :wink:

Zitat:

Zitat von Neutral General
Hi,
gehört zu der stdcall Aufrufkonvention und wird vom compiler automatisch erzeugt. Also das hat schon alles so seine Richtigkeit ;)

Naja wenn ich stdcall weglasse schauts immer noch so aus !

Apollonius 14. Sep 2009 13:55

Re: Compiler ändert asm Code ?
 
Zitat:

Zitat von Neutral General
Das gehört zu der stdcall Aufrufkonvention und wird vom compiler automatisch erzeugt. Also das hat schon alles so seine Richtigkeit ;)

Quatsch. Das ist ein Detail der Implementation, während die Aufrufkonvention zum Contract gehört. Wenn ich den Stackframe nicht haben will, dann soll der Compiler auch keinen generieren.

TKC 14. Sep 2009 14:02

Re: Compiler ändert asm Code ?
 
Zitat:

Zitat von Apollonius
Wenn ich den Stackframe nicht haben will, dann soll der Compiler auch keinen generieren.

Sehe ich auch so.

gammatester 14. Sep 2009 14:15

Re: Compiler ändert asm Code ?
 
Zitat:

Zitat von TKC
Zitat:

Zitat von Apollonius
Wenn ich den Stackframe nicht haben will, dann soll der Compiler auch keinen generieren.

Sehe ich auch so.

Zitat:

Zitat von Delphi Hilfe
The compiler only generates stack frames for nested routines, for routines that have local parameters, or for routines that have parameters on the stack.


Apollonius 14. Sep 2009 14:17

Re: Compiler ändert asm Code ?
 
So what? In einer reinen Assembler-Routine sind Parameter auf dem Stack kein Grund, einen Stackframe zu generieren.

gammatester 14. Sep 2009 14:45

Re: Compiler ändert asm Code ?
 
Da im Originalbeitrag
Delphi-Quellcode:
function xPostMessage(hWnd: hWnd; Msg: UINT; wParam: wParam; lParam: lParam): BOOL; stdcall;
asm
      mov edi, edi
      push ebp
      mov ebp, esp
      jmp OldDllFunc
end;
überhaupt nicht auf die Parameter zu gegriffen wird und auch via jmp eh nicht der Stackframe abgebaut wird kann man doch eigentlich gleich schreiben?

Delphi-Quellcode:
function xPostMessage: BOOL; stdcall;
asm
      mov edi, edi
      push ebp
      mov ebp, esp
      jmp OldDllFunc
end;
Dann wird auch kein Stackframe erzeugt.

Apollonius 14. Sep 2009 14:51

Re: Compiler ändert asm Code ?
 
Das war doch praktisch mein Vorschlag aus #2. Aber dann wird es eben hässlich, wenn man xPostMessage aus Delphi aufrufen will.

TKC 14. Sep 2009 15:24

Re: Compiler ändert asm Code ?
 
Zitat:

Zitat von Apollonius
Das war doch praktisch mein Vorschlag aus #2. Aber dann wird es eben hässlich, wenn man xPostMessage aus Delphi aufrufen will.

Stimmt ist etwas umständlich aber es funktioniert auch.

sirius 14. Sep 2009 15:38

Re: Compiler ändert asm Code ?
 
Aber den Stack sollte man trotzdem hinterher aufräumen. (oder man nimmt cdecl)

Apollonius 14. Sep 2009 15:43

Re: Compiler ändert asm Code ?
 
Wenn du aus der Funktion herausjumpst, kann das die Zielfunktion übernehmen. Im Prinzip ist das ein Tailcall, auch wenn das manuelle Aufsetzen eines Stackframes etwas merkwürdig ist.

sirius 14. Sep 2009 16:06

Re: Compiler ändert asm Code ?
 
ach, ich dachte der jump war nur so ein test

TKC 27. Apr 2010 19:56

Re: Compiler ändert asm Code ?
 
Zitat:

Zitat von Apollonius
Ich finde das auch extrem lästig. In C++ würde man das mit __declspec(naked) lösen; in Delphi gibt es das nicht. Als hässlichen Workaround kannst du die Parameter sowie das stdcall weglassen. Wenn du die Funktion dann aus Delphi-Code aufrufen willst, nimmst du @xPostMessage und castest in einen entsprechenden Funktionszeigertypen, sodass du die Funktion mit Parametern aufrufen kannst.

Hallo,
ich muss das jetzt doch noch einmal ausgraben .. kann mir jemand an einem Beispiel zeigen wie ich so einen Typecast machen muss ?

Danke

TKC 9. Mai 2010 10:08

Re: Compiler ändert asm Code ?
 
Hi,
muss das leider nochmal hochholen. Wär klasse wenn mir jemand nen beispiel hat.
Danke.

jaenicke 9. Mai 2010 11:00

Re: Compiler ändert asm Code ?
 
Delphi-Quellcode:
procedure TestMe();
begin

end;

type
  TTestFunc = function(hWnd: hWnd; Msg: UINT; wParam: wParam; lParam: lParam): BOOL; stdcall;
var
  TestFunc: TTestFunc;
begin
  TestFunc := @TestMe;
  TestFunc(0, 0, 0, 0);
end;
So sollte es gehen.

himitsu 9. Mai 2010 11:18

Re: Compiler ändert asm Code ?
 
Der automatisch erzeugte Eintritts- und Austrittscode (genannt Stack-Frame):
Delphi-Quellcode:
PUSH   EBP            // Vorhanden wenn Locals <> 0 oder Params <> 0
MOV    EBP, ESP       // Vorhanden wenn Locals <> 0 oder Params <> 0
SUB    ESP, Locals    // Vorhanden wenn Locals <> 0
PUSH   ECX            // -
...
MOV    EAX, [EBP-4]   // Vorhanden wenn nachdem Result etwas zugewiesen wurde auch noch EAX
                        // etwas zugewiesen wird, in diesem Fall wird für Result [EBP-4] statt
                        // EAX verwendet - wenn Result <= Integer
POP    ECX            // -
MOV    ESP, EBP       // Vorhanden wenn Locals <> 0
POP    EBP            // Vorhanden wenn Locals <> 0 oder Params <> 0
RET    Params         // Immer vorhanden
Dazu kommt dann noch die Behandlung von
{$W+} oder {$STACKFRAMES ON}
[equote="OH satgt zu ''Stack-Frames (Delphi)''"]Die Direktive $W steuert die Erzeugung von Stack-Frames für Prozeduren und Funktionen. Im Status {$W+} werden Stack-Frames für Prozeduren und Funktionen auch dann erzeugt, wenn sie nicht benötigt werden. Im Status {$W-} werden Stack-Frames nur generiert, wenn die Verwendung lokaler Variablen durch die Routine dies erforderlich macht. [/equote]

TKC 9. Mai 2010 11:59

Re: Compiler ändert asm Code ?
 
Zitat:

Zitat von jaenicke
Delphi-Quellcode:
procedure TestMe();
begin

end;

type
  TTestFunc = function(hWnd: hWnd; Msg: UINT; wParam: wParam; lParam: lParam): BOOL; stdcall;
var
  TestFunc: TTestFunc;
begin
  TestFunc := @TestMe;
  TestFunc(0, 0, 0, 0);
end;
So sollte es gehen.

Vielen Dank ich werde es gleich mal probieren und Bericht erstatten.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:58 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz