Ich versuche, den Stapel eines untergeordneten Prozesses zu lesen, habe aber kein Glück. Ich weiß, dass dies möglich ist ptrace
, aber über ptrace
die Benutzeroberfläche können Sie jeweils nur ein Wort lesen, und ich versuche, einen größeren Teil des Stapels zu scannen.
Ich habe auch versucht, das /proc/$pid/mem
aus den Grenzen des Stapels zu lesen, wie es aus der /proc/$pid/maps
Datei extrahiert wurde, nachdem zuerst ptrace zum Anhängen verwendet wurde (wie hier vorgeschlagen ), aber das Lesen schlägt weiterhin fehl (selbst wenn es als Root ausgeführt wird), obwohl derselbe Code beim Versuch erfolgreich ist Lesen aus verschiedenen Teilen des Prozesses (z. B. Haufen).
Was mache ich falsch? Gibt es noch eine andere Möglichkeit?
waitpid
zwischenptrace(PTRACE_ATTACH,…)
und angerufenread
(sonst gibt es eine mögliche Rennbedingung)? Welcher Fehler kommtread
zurück? Tut das Kind etwas Besonderes an der Speicherzuordnung - können Sie Ihren Code mit einem einfachen Kind wie dem versuchensleep
?Antworten:
Dann benutze einfach eine Schleife. Ich verstehe ehrlich gesagt nicht, wie das ein Problem darstellt
ptrace
, ich nutze es die ganze Zeit, um aus der Ferne auf Prozesse zuzugreifen.Ich benutze so etwas:
quelle
Hier ist eine weitere Strategie, die möglicherweise optimiert werden muss, bei großen Datenmengen jedoch effizienter sein sollte. Die Idee ist, Syscalls im Remote-Prozess auszuführen, um den Stack-Inhalt abzurufen. Es wird einen bestimmten Architekturcode benötigen, aber wenn Sie nur x86 / x86_64 als Ziel festlegen, sollte dies nicht zu aufwändig sein.
"/tmp/fifo"
in Ihrem aufrufenden Prozess.PTRACE_SYSCALL
to step", umwaitpid()
zu warten undPTRACE_GETREGS
/ oderPTRACE_PEEKTEXT
den aktuell ausgeführten Opcode zu überprüfen.open("/tmp/fifo")
,write()
die Stack - Inhalte,close()
die Beschreiber.Es gibt vielleicht elegantere Alternativen zur Named Pipe, aber mir fällt gerade keine ein. Der Grund, warum ich nur Syscalls verwende, ist, dass die Ferncodeinspeisung auf modernen Systemen aufgrund verschiedener Sicherheitsmaßnahmen ziemlich unzuverlässig ist. Der Nachteil ist, dass es hängen bleibt, bis der Remote-Prozess einen Systemaufruf ausführt (was bei einigen Programmen, die meistens Berechnungen ausführen, ein Problem sein kann).
In dieser Quelldatei sehen Sie freien Code, der den größten Teil der Arbeit ausführt . Feedback zum Code ist willkommen!
quelle
Ein weiterer Vorschlag.
Wenn es im Hauptkernelbaum von Linux akzeptiert wird, können Sie Christopher Yeohs Cross Memory Attach- Patch verwenden. Siehe beispielsweise die Dokumentation zu process_vm_readv .
quelle
Mit dem proc-Dateisystem können Sie problemlos den Stapel eines anderen Prozesses lesen (Sie benötigen dafür root-Zugriff). Bevor Sie willkürlich aus dem / proc / pid / mem lesen, müssen Sie das / proc / pid / maps konsultieren. Ein einfaches Einlesen dieser Datei zeigt viele Einträge. Wir sind an dem als Stack gekennzeichneten Eintrag interessiert. Sobald Sie dies erhalten, müssen Sie die unteren und oberen Grenzen des Stapels lesen. Öffnen Sie nun einfach die Datei / proc / pid / mem, suchen Sie die untere Grenze des Stapels und lesen Sie die richtige Datengröße.
quelle
mems
und nichtmaps
? (Ich kann keinemems
Einträge unter meinem/proc
Dateisystem sehen.) Das OP hat bereits erwähnt, dass die Stapelgrenzen gelesen wurden/proc/$pid/maps
- was schlagen Sie vor, was sie anders machen?Sie könnten es mit lsstack versuchen . Es verwendet ptrace, genau wie jedes andere erfolgreiche Programm, das den Stack eines anderen Prozesses liest. Ich konnte ein Programm mit / proc / $ pid / mem nicht zum Laufen bringen. Ich glaube, dass Sie es nicht so machen können, obwohl Sie es logischerweise sollten.
quelle