2010-12-03 11 views
1

Ich frage mich, ob es eine Möglichkeit gibt, das EBP eines Threads in einem anderen Prozess (in C++ unter Windows) als "GetThreadContext" zu erhalten. Ich vermute, dass diese Methode zu viel Zeit braucht (ich benutze sie sehr oft) und wenn ich nur die EBP und nicht alle Werte von CONTEXT bekommen könnte, wäre es schneller.
Ich dachte daran, "ReadProcessMemory" zu verwenden und dann die EBP mit dem Rest des Callstacks zu bekommen, aber ich weiß nicht, wo der Stack sein sollte und woher soll ich ihn bekommen.
Wenn jemand einen besseren Weg kennt, würde ich mich freuen, davon zu hören.
danke :)Das EBP eines Threads in einem anderen Prozess erhalten

+1

Was schreibst du, ein Profiler? Vielleicht, wenn Sie Ihr Problem erklären, kann Ihnen jemand einen schnelleren Weg geben. –

+0

ja, ein Profiler :) – Idov

Antwort

3

Der laufende Wert von EBP eines anderen Threads ist natürlich im EBP-Register, wenn der Thread läuft. Wenn es nicht läuft, wird es vom Scheduler im Kernel gespeichert. GetThreadContext ruft ab, was im Kernel ist; nichts anderes wird schneller sein.

Die Performance-Situation ist schlimmer, als ich es verstand, als ich dies schrieb. Wenn der Thread ausgeführt wird, verwendet der Kernel den APC-Mechanismus, um einen aktuellen Wert für Sie abzurufen. Dies ist nicht schnell, aber es gibt keine andere alternative API.

+0

Nein, das ist falsch. NtGetContextThread reiht immer einen APC an den Zielthread an, wenn es nicht der aktuelle Thread ist. Es wartet dann auf den APC, um abzuschließen. Nicht sehr schnell. – wj32

+0

Ich würde mich schlechter fühlen, wenn es tatsächlich eine andere schnellere Alternative gäbe. Ist dort eines? – bmargulies

+0

Nein. Wenn ein Thread läuft, sind seine Register ... in den Registern, was nicht sehr hilfreich ist. Wenn es nicht ausgeführt wird, werden die Register in seinem KTHREAD-Objekt gespeichert. Der beste Weg, um sicherzustellen, dass die Register des Threads gespeichert werden, damit wir sie tatsächlich lesen können, besteht darin, einen APC an ihn zu hängen, was einen Interrupt auf dem Prozessor dieses Threads verursacht. – wj32

1

GetThreadContext wird der einzige Weg sein, weil EBP ein Register ist; Der Prozessor speichert es bei einem Kontextwechsel. Die einzige Möglichkeit, die Register eines Threads zu lesen, ist GetThreadContext.

Natürlich gibt es keine Garantie dafür, dass EBP den Wert hat, den Sie wollen ... Funktionen, die mit Auslassung des Frame-Zeigers kompiliert wurden, werden EBP nicht zuverlässig auf den Frame-Zeiger des aktuellen Call-Frames setzen.

Wenn Sie nur nach einem Stack-Trace suchen (der häufigste Grund, mit dem ein EBP beginnen soll), könnte ich Ihnen vorschlagen, StackWalk64?