AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Mache ich den Stack kaputt, wenn ich eine Funktion ohne Parameter mit aufrufe?

Mache ich den Stack kaputt, wenn ich eine Funktion ohne Parameter mit aufrufe?

Ein Thema von Pippa · begonnen am 23. Sep 2018 · letzter Beitrag vom 24. Sep 2018
Antwort Antwort
Pippa

Registriert seit: 22. Sep 2018
2 Beiträge
 
#1

Mache ich den Stack kaputt, wenn ich eine Funktion ohne Parameter mit aufrufe?

  Alt 23. Sep 2018, 00:12
Hallo liebe Praxis.

Der Titel ließ mir leider nicht sehr viel Platz für mein 'Problem'.

Folgende Situation:

Ich injecte meine DLL in einen 64 Bit Prozess, der regelmäßig Updates bekommt. Vorweg kann ich sagen, dass es sich hier um kein Multiplayer-Spiel o.Ä. handelt (ehrlich ).
Für den Fall das ich mal zu faul sein sollte, alle meine Offsets an den neuen Build anzupassen, habe ich zunächst eine Liste erstellt. In dieser Liste setze ich alle Funktions-Offsets, die ich in der Zielanwendung aufrufen möchte.
Delphi-Quellcode:
procedure TGlobals.AddOffset(OffsetIdent: TOffset; Offset: NativeUInt; Build: Integer);
var
  OffsetRec: TOffsetRec;
begin
  OffsetRec.OffsetName := OffsetIdent;
  OffsetRec.OffsetBuild := Build;
  OffsetRec.Offset := FExeModule + Offset;

  FOffsets.Add(OffsetRec);

  if (Build <> FAppBuild) and (Assigned(PipeClient)) then
    PipeClient.SendMsgToLoader('Offset %s is not compatible with current build', [GetEnumName(TypeInfo(TOffset), Ord(OffsetIdent))], true);
end;
Den Build lese ich direkt aus den Exe-Informationen aus. Sollte der Build nicht mit dem festgelegten Build in meiner DLL übereinstimmen, setze ich das Offset der Anwendung auf eine "Null Funktion".
Delphi-Quellcode:
function TGlobals.GetOffset(OffsetIdent: TOffset; OffsetType: TOffsetType): Pointer;
var
  i: Integer;
begin
  for i := 0 to FOffsets.Count -1 do
  begin
    if (FOffsets[i].OffsetName = OffsetIdent) and (FOffsets[i].OffsetBuild = FAppBuild) then
      exit(Pointer(FOffsets[i].Offset));
  end;

  case OffsetType of
    OT_FUNCTION:
      result := @NullOffsetFunction;
    OT_DETOUR:
      result := nil;
    OT_POINTER:
      result := @NullOffsetPointer
    else
      result := nil;
  end;
end;
Gehört das gewünschte Offset also zu einer Funktion, dass Offset ist jedoch noch nicht geupdatet, setze ich den Pointer auf eine Funktion die einfach nichts tut. Möchte ich in der Zielanwendung z.B. etwas loggen und das Offset ist nicht up2date, wird NullOffsetFunction aufgerufen, ggf. mit Parametern.
Delphi-Quellcode:
function NullOffsetFunction(): Pointer;
begin
  result := nil;
end;
Das könnte dann so aussehen.
Delphi-Quellcode:
var
  ExternalAppDoSomething: procedure(const S: String);

procedure TGlobals.RegisterOffsets();
begin
  @ExternalAppDoSomething := GetOffset(OFF_FUNC_DOSOMETHING, OT_FUNCTION);
end;
ExternalAppDoSomething würde jetzt irgendwo anders im Code aufgerufen, das Offset ist veraltet und GetOffset hat es auf NullOffsetFunction gesetzt. Bei jedem Aufruf wird jedoch ein Parameter übergeben, NullOffsetFunction hat keinen.
Delphi-Quellcode:
proecedure Pipapo();
begin
  ExternalAppDoSomething('hello from dll');
end;
-> NullOffsetFunction wird aufgerufen.

Mit dem Szenario möchte ich etliche try ... except vermeiden.

Wie gesagt, ist das ganze für x64. Eigentlich sollte es da kein Problem geben, da der Caller (unter x64) ja den Stack aufräumt und die Anzahl der übergebenen Parameter die nicht verarbeitet werden irrevant sein müsste, oder täusche ich mich da?

Über die anderen Probleme bin ich mir im Klaren, ein Aufruf erwartet "null" als Rückgabewert und NullOffsetFunction gibt ebenfalls null zurück, dies ist im gesamten Code aber bisher nicht von Relevanz Im Zweifelsfall könnte dann noch immer überprüft werden, ob das Offset auf NullOffsetFunction zeigt, bei anderen Aufrufen würde ich Checks aber gerne vermeiden.

Liebe Grüße

Geändert von Pippa (23. Sep 2018 um 01:23 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#2

AW: Mache ich den Stack kaputt, wenn ich eine Funktion ohne Parameter mit aufrufe?

  Alt 23. Sep 2018, 18:58
Siehe hier:
https://en.wikipedia.org/wiki/X86_ca...ing_convention
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Pippa

Registriert seit: 22. Sep 2018
2 Beiträge
 
#3

AW: Mache ich den Stack kaputt, wenn ich eine Funktion ohne Parameter mit aufrufe?

  Alt 24. Sep 2018, 12:27
Wenn ich den Artiel richtig verstehe sollte es da also keine Probleme geben, der Caller räuft ja immer auf und eine Funktion die nichts tut, sollten die überflüssigen Parameter auch nicht interessieren. Probleme gab es bisher auch keine, jedoch ist die Implementierung recht frisch und ich hatte Bedenken ob ich nicht doch etwas zerschieße.

Zumindest fand ich es schöner eine DLL zu haben die die Anwendung nicht in den Tot reißt, wenn sie nicht angepasst ist, sondern die Core Funktionen wie die Pipe noch funktionieren.
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 13:17 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