Zugriff auf den Programm-Stack in C++

Wie bekomme ich unter C++ Zugriff auf den Programmstack ?
Ich möchte die Adresse der aufrufenden Funktion ermitteln (vielleicht auch die Adresse der Übergabeparameter)

thx
 
Hallo,
die Adressen der Übergabeparameter zu ermitteln sollte ja kein Problem sein, einfach &parameter (oder *, schon lange her das ich in C programmiert habe).

Wie man nun die Rücksprungadresse bekommt, kann ich dir leider nicht beantworten, evt. hilft aber folgender Link schon etwas:
API-Hooking
 
Direktzugriff auf den Stack ist nicht unmittelbar im Sprachumfang von C(++) vorgesehen.
Dennoch ist er möglich.
Fakt ist aber - egal, wie man es angeht - daß dies in mehrfacher Hinsicht spezifisch ist:

1. nach CPU
2. nach Compiler-Hersteller
3. nach Compiler-Optionen
4. nach Debug-Modi

Was auch immer Du also tust: Du opferst jede Portabilität.

Das gesagt, gibt es viele Varianten:
- Von Microsoft- und Borland-Compilern für 80x86-CPUs kenne ich das direkte Ansprechen der CPU-Register über reservierte Bezeichner.
- Von sämtlichen Compilern kenne ich das Einbinden von Assembler-Code. Die Syntax des unterstützten Inline-Assemblers ist aber vollkommen CPU- und Hersteller-spezifisch.
- Man KANN auch ganz ohne Assembler über wohlplazierte Variablen auf dem Stack an den Stackframe herankommen: Wo der Compiler eine konkrete lokale Variable in den Stack einhängt, ändert sich zwar nicht von Compilation zu Compilation und auch nicht von Funktion zu Funktion, solange deren Parameterlisten gleich bleiben, ist ansonsten aber vollkommen von eben den Parameterlisten, noch viel mehr Compileroptionen und allem möglichen Kickifax drumherum abhängig.

Der effektivste Weg dürfte sein, Inline-Assembler zu verwenden.

Falls Du mit MSVC oder ähnlichem hantierst: Schau auch mal hier:
http://msdn2.microsoft.com/en-us/library/system.diagnostics.stackframe.aspx
 
@Harry: ich denke, es geht darum:
stdio.h/msvcrt.dll abändern/rekompilieren möglich?
;)
@topic
wobei es hier wirklich auf den kompiler ankommt.Meistens begint eine Funktion so:
Code:
push EBP
mov EBP,ESP
... init lokale variablen/array -> ändere ESP
... code

LEAVE
ret
Ich würde nach KIS Prinzip (Keep it simple ;) ) einmal im Debugger nachschauen, was der Compiler so treibt und dann mit Inline-Asm die Adressen auslesen(gilt für den obigen Stackframeaufbau):
Code:
mov ret_adresse,[ebp+4]
mov erster_param_addr,[EBP+8] //setzt voraus, dass die Parameter nicht byValue übergeben werden
mov zweiteR_param_addr,[EBP+12]
...
aufrufadresse ist i.R ret_adresse-6 bei indirekten calls (CALL DWORD PTR[adresse]) und ret_adresse-5 bei direkten calls (CALL adresse). Sollte man im Zweifelsfall auch nachschauen.
 
Ahhh...

Gut, damit haben wir den Anwendungsfall eingegrenzt und auch die Kompatibilitätsbedingungen festgelegt: Prinzipiell stört hier nichts, weil es explizit um einen speziellen Patch für einen speziellen PC geht.

Und offenbar möchte lorelei den Patch nur wirken lassen, wenn das spezielle Anwendungsprogramm aufgerufen hat. DAS ist allerdings weniger eine Sache des Stacks, sondern eine Sache der Ermittlung des aktuell laufenden Prozesses, oder?

Mit GetCurrentProcess (http://msdn2.microsoft.com/en-us/library/ms683179(VS.85).aspx) bekommt man den.

Mit dem Handle kann man weitere schlimme Sachen abfragen, wie
GetEnvironmentStrings (http://msdn2.microsoft.com/en-us/library/ms683187(VS.85).aspx)
QueryFullProcessImageName
http://msdn2.microsoft.com/en-us/library/ms684919(VS.85).aspx

Beides müßte in diesem Fall zielführend helfen können...
 
Danke für eure sehr hilfreichen Antworten!

Die Vermutung ist schon richtig: ich möchte erkennen, welches Programm die Funktion aufruft, aber das reicht noch nicht, denn diese Funktion wird von vielen Stellen im Programm aufgerufen. Also muss ich noch genauer sehen, von welcher Stelle im Programm der Aufruf kommt - nur von einer ganz speziellen Stelle aus aufgerufen, muss ich eingreifen, da hier der fehlerhafte Parameter übergeben wird.

Meine Idee dazu war: Schau doch einfach auf dem Programm-Stack, von wo (innerhalb des Programms) die Funktion aufgerufen wurde.

Kennt ihr vielleicht die Lösung?
 
Eventuell hilft "StackTrace" noch etwas weiter, obwohl es den erstmal nur unter der .NET-Laufzeitumgebung gibt - also wieder etwas abhängiger von Microsofts systeminternen Spielereien (Du wirst sicher kein 100 MByte-Paket installieren wollen, NUR um die Stackframes eines Moduls verfolgen zu können). Aber eventuell hilft die Dokumentation weiter, um an die passenden Stichworte zu kommen, um dann mit Google passende Treffer zu landen.

Mir ist deutlich danach, daß es auch im ganz normalen WinAPI seit seeligen Win3.x - Zeiten schon Funktionen zum Verfolgen von Stackframes gab. Allerdings liegt mir momentan die alte Doku nicht vor und über Google bist Du sicher genauso schnell...

http://msdn2.microsoft.com/en-us/library/system.diagnostics.stacktrace.aspx
 
Zurück
Oben