Speicher eines anderen Prozesses in OS X lesen?

Lesezeit: 10 Minuten

Benutzer-Avatar
Jeremy

Ich habe versucht zu verstehen, wie man den Speicher anderer Prozesse unter Mac OS X liest, aber ich habe nicht viel Glück. Ich habe viele Beispiele online mit gesehen ptrace mit PEEKDATA und so, aber es hat diese Option nicht auf BSD [man ptrace].

int pid = fork();
if (pid > 0) {
    // mess around with child-process's memory
}

Wie ist es möglich, unter Mac OS X aus dem Speicher eines anderen Prozesses zu lesen und zu schreiben?

  • Ich interessiere mich besonders für den Fall, in dem ich den anderen Prozess nicht kontrolliere — dh im Programm eines anderen herumstochern, um zu sehen, was es tut. (Vermutlich nach dem Deaktivieren von ASLR.)

    – Jeremy

    1. Oktober 2013 um 2:15 Uhr

  • Ich verstehe nicht, welchen Teil des Prozesses Sie lesen möchten. Soll der Adressraum des Wall-Prozesses wie in Core-Dump-Dateien abgerufen werden? Sie benötigen Code, um Threads und (manchmal) gemeinsam genutzte Bibliotheken zu handhaben. Sie benötigen diesen Code (meistens) nicht, wenn Sie beispielsweise nur die Programmbinärdatei im RAM suchen.

    – Benutzer2284570

    8. Oktober 2013 um 0:47 Uhr


  • @ user2284570 Ich bin daran interessiert, den Arbeitsspeicher eines Prozesses zu beobachten oder zu manipulieren, nicht den ausführbaren Code.

    – Jeremy

    8. Oktober 2013 um 1:38 Uhr

  • „Manipulation des Arbeitsgedächtnisses“ Ihr Beitrag enthält nur das Wort „gelesen“. Meinst du, du musst auch in den Adressraum des Prozesses schreiben? In diesem Fall benötigen Sie wahrscheinlich einen Hex-Heditor. Es funktioniert genauso für Dateien, aber Sie verwenden einen Prozess als Parameter. Ich werde versuchen zu sehen, ob es für XNU/darwin oder bsd4.3 existiert (da Apple sein Betriebssystem auf diesem BSD basiert)

    – Benutzer2284570

    8. Oktober 2013 um 18:54 Uhr

  • @ user2284570 Das Schreiben in den Adressraum des Prozesses wäre eine sehr schöne Sache. Ich habe schon früher von Möglichkeiten gehört, unter Linux auf den Prozessspeicher zuzugreifen, aber ich war mir nicht sicher, ob sie für BSD gelten, und insbesondere bin ich mir nicht sicher, wie viel von OS X entfernt wurde, das in anderen BSD-Distributionen verfügbar ist. Vielen Dank für Ihre Vorschläge.

    – Jeremy

    8. Oktober 2013 um 20:12 Uhr

Verwenden task_for_pid() oder andere Methoden, um den Task-Port des Zielprozesses zu erhalten. Danach können Sie den Adressraum des Prozesses direkt mit manipulieren vm_read(), vm_write()und andere.

  • Es gibt auch vm_remap Dadurch können Sie einen fremden Prozessspeicher in Ihre eigene VM abbilden.

    – Sergej L.

    3. Oktober 2013 um 14:37 Uhr

  • Wie erhalte ich nach dem Abrufen des Task-Ports des Prozesses seinen Adressraum? und wie suche ich weiter im Adressraum nach einer bestimmten Zeichenfolge? Kannst du ein Beispiel geben?

    – Schlangennin

    26. März 2014 um 7:08 Uhr

Benutzer-Avatar
Derek Park

Matasano Chargen hatte vor einiger Zeit einen guten Beitrag über die Portierung von Debugging-Code auf OS X, der unter anderem das Lesen und Schreiben von Speicher in einem anderen Prozess beinhaltete.

Es muss funktionieren, sonst würde GDB nicht funktionieren:

Es stellte sich heraus, dass Apple in seiner unendlichen Weisheit ausgeweidet hatte ptrace(). Die OS X-Manpage listet die folgenden Anforderungscodes auf:

  • PT_ATTACH — um einen Prozess zum Debuggen auszuwählen
  • PT_DENY_ATTACH – damit Prozesse sich selbst daran hindern können, debuggt zu werden
    […]

Keine Erwähnung des Lesens oder Schreibens von Speicher oder Registern. Was entmutigend gewesen wäre, wenn die Manpage nicht auch erwähnt hätte PT_GETREGS, PT_SETREGS, PT_GETFPREGSund PT_SETFPREGS im Abschnitt Fehlercodes. Also, ich habe es überprüft ptrace.h. Dort fand ich:

  • PT_READ_I — Anweisungswörter lesen
  • PT_READ_D — um Datenworte zu lesen
  • PT_READ_U — um U-Bereichsdaten zu lesen, wenn Sie alt genug sind, um sich daran zu erinnern, was der U-Bereich ist
    […]

Ein Problem ist gelöst. Ich kann Speicher für Breakpoints lesen und schreiben. Aber ich kann immer noch nicht auf Register zugreifen, und ich muss in der Lage sein, mit EIP herumzuspielen.

Ich weiß, dass dieser Thread 100 Jahre alt ist, aber für Leute, die von einer Suchmaschine hierher kommen:

xnum macht genau das, wonach Sie suchen, manipuliert und liest den Interprozessspeicher.

// Create new xnu_proc instance
xnu_proc *Process = new xnu_proc();

// Attach to pid (or process name)
Process->Attach(getpid());

// Manipulate memory
int i = 1337, i2 = 0;
i2 = process->memory().Read<int>((uintptr_t)&i);

// Detach from process
Process->Detach();

  • Dieser Link ist ein 404. Ich glaube, er wurde verschoben github.com/gordio/xnumem

    – P ich

    6. März 2018 um 11:09 Uhr

Wenn Sie Speicherblöcke zwischen Prozessen teilen möchten, sollten Sie sich shm_open(2) und mmap(2) ansehen. Es ist ziemlich einfach, in einem Prozess einen Teil des Speichers zuzuweisen und den Pfad (für shm_open) an einen anderen weiterzugeben, und beide können dann zusammen verrückt werden. Dies ist viel sicherer, als im Adressraum eines anderen Prozesses herumzustöbern, wie Chris Hanson erwähnt. Wenn Sie beide Prozesse nicht unter Kontrolle haben, wird Ihnen das natürlich nicht viel nützen.

(Beachten Sie, dass die maximale Pfadlänge für shm_open 26 Bytes zu sein scheint, obwohl dies nirgendwo dokumentiert zu sein scheint.)

// Create shared memory block
void* sharedMemory = NULL;
size_t shmemSize = 123456;
const char* shmName = "mySharedMemPath";        
int shFD = shm_open(shmName, (O_CREAT | O_EXCL | O_RDWR), 0600);
if (shFD >= 0) {
    if (ftruncate(shFD, shmemSize) == 0) {
        sharedMemory = mmap(NULL, shmemSize, (PROT_READ | PROT_WRITE), MAP_SHARED, shFD, 0);
        if (sharedMemory != MAP_FAILED) {
            // Initialize shared memory if needed
            // Send 'shmemSize' & 'shmemSize' to other process(es)
        } else handle error
    } else handle error
    close(shFD);        // Note: sharedMemory still valid until munmap() called
} else handle error

...
Do stuff with shared memory
...

// Tear down shared memory
if (sharedMemory != NULL) munmap(sharedMemory, shmemSize);
if (shFD >= 0) shm_unlink(shmName);





// Get the shared memory block from another process
void* sharedMemory = NULL;
size_t shmemSize = 123456;              // Or fetched via some other form of IPC
const char* shmName = "mySharedMemPath";// Or fetched via some other form of IPC
int shFD = shm_open(shmName, (O_RDONLY), 0600); // Can be R/W if you want
if (shFD >= 0) {
    data = mmap(NULL, shmemSize, PROT_READ, MAP_SHARED, shFD, 0);
    if (data != MAP_FAILED) {
        // Check shared memory for validity
    } else handle error
    close(shFD);        // Note: sharedMemory still valid until munmap() called
} else handle error


...
Do stuff with shared memory
...

// Tear down shared memory
if (sharedMemory != NULL) munmap(sharedMemory, shmemSize);
// Only the creator should shm_unlink()

Sie möchten Inter-Process-Communication mit dem Shared-Memory-Verfahren durchführen. Eine Zusammenfassung anderer Commons-Methoden finden Sie unter hier

Ich habe nicht lange gebraucht, um das zu finden, was Sie brauchen Buchen das alle APIs enthält, die heute allen UNIXen gemeinsam sind (viel mehr als ich dachte). Sie sollten es in Zukunft kaufen. Dieses Buch besteht aus (mehreren hundert) gedruckten Handbuchseiten, die selten auf modernen Maschinen installiert werden. Jede Handbuchseite beschreibt eine C-Funktion.

Ich brauchte nicht lange, um es zu finden schmat () shmctl(); shmdt() und shmget() drin. Ich habe nicht lange gesucht, vielleicht gibt es noch mehr.

Es sah ein bisschen veraltet aus, aber: JA, die grundlegende Benutzerbereichs-API des modernen UNIX-Betriebssystems zurück in die alten 80er Jahre.

Update: Die meisten im Buch beschriebenen Funktionen sind Teil der POSIX-C-Header, Sie müssen nichts installieren. Es gibt wenige Ausnahmen, wie bei “curses”, der ursprünglichen Bibliothek.

  • @JeremyBanks Ich muss eine weitere Antwort mit Ihrem Kommentar schreiben, aber ich habe ein paar Fragen: Wissen Sie, woraus die virtuelle Adressierung aus Sicht des Benutzerprozesses besteht (Hinweis: Wikipedia gibt keine wirklichen Erklärungen dazu)? Wissen Sie, was Prozessisolation ist und wie sie mit IPC umgeht? Es ist ein Basisdienst des Betriebssystems zu geben Speicherplatzisolierung: Stellen Sie sich vor, ein laufender Prozess ohne Administratorrechte könnte unverschlüsselte Passwörter auf einem anderen Prozess lesen. Starten eines Treibers in ring0 Dies zu erreichen war das Ziel der Piraten.

    – Benutzer2284570

    1. Oktober 2013 um 21:27 Uhr

  • @JeremyBanks: Ich habe etwas vergessen: Ja, Sie könnten es /dev/mem und /dev/kmem tun, aber ab der x86-Version von Mac OS X hat Apple diese Geräte aus vielen Gründen entfernt, einschließlich der Sicherheit. Linux hat etwas Ähnliches mit einer Config-Compile-Time-Option gemacht, die die meisten Linux-Ditros aktiviert haben: Es deaktiviert den vollen Zugriff auf /dev/mem (sogar für Root) und beschränkt ihn auf nur die Adressen, die Programme (wie Xorg) verwenden.

    – Benutzer2284570

    1. Oktober 2013 um 22:13 Uhr

  • Ich weiß nicht genug über virtuellen Speicher, um die Details zu kennen, wie dies in einem modernen Betriebssystem funktioniert, aber ich verstehe, dass dies gegen die Speicherisolation verstößt und wenn möglich Administratorrechte erfordern würde. Ich stellte mir den einfachsten Fall vor, sagen wir, a zu modifizieren static int in einem C-Programm, die (vielleicht?) dem gleichen Speicherplatz zugewiesen würden oder die auf irgendeine Weise lokalisiert werden könnten. Ich habe mir irgendwie vorgestellt, dass einige Spiel-Bots, die den Zustand des Spiels untersuchen, so funktionieren könnten. Ich war mir nicht ganz sicher, ob es möglich war.

    – Jeremy

    2. Oktober 2013 um 14:52 Uhr


  • @JeremyBanks: Ich habe das gefunden Dienstprogramm Quellcode

    – Benutzer2284570

    7. Oktober 2013 um 22:41 Uhr

Benutzer-Avatar
Glorfindel

Ich habe definitiv eine kurze Implementierung dessen gefunden, was Sie brauchen (nur eine Quelldatei (main.c)). Es wurde speziell für XNU entwickelt.

Es ist unter den Top-Ten-Ergebnissen der Google-Suche mit den folgenden Schlüsselwörtern «dump process memory os x»

Der Quellcode ist hier

aber aus einem strengen Punkt des virtuellen Adressraums sollten Sie sich mehr für diese Frage interessieren: OS X: Generieren Sie einen Core-Dump, ohne den Prozess herunterzufahren? (siehe auch Dies)

Wenn Sie sich den gcore-Quellcode ansehen, ist dies ziemlich komplex, da Sie sich mit Laufflächen und ihrem Zustand befassen müssen …

Bei den meisten Linux-Distributionen ist das gcore-Programm jetzt Teil des GDB-Pakets. Ich denke, die OSX-Version wird mit xcode/den Entwicklungstools installiert.

UPDATE: wxHexEditor ist ein Editor, der Geräte bearbeiten kann. IT KANN auch den Prozessspeicher auf die gleiche Weise bearbeiten wie normale Dateien. Es funktioniert auf allen UNIX-Rechnern.

  • @JeremyBanks Ich muss eine weitere Antwort mit Ihrem Kommentar schreiben, aber ich habe ein paar Fragen: Wissen Sie, woraus die virtuelle Adressierung aus Sicht des Benutzerprozesses besteht (Hinweis: Wikipedia gibt keine wirklichen Erklärungen dazu)? Wissen Sie, was Prozessisolation ist und wie sie mit IPC umgeht? Es ist ein Basisdienst des Betriebssystems zu geben Speicherplatzisolierung: Stellen Sie sich vor, ein laufender Prozess ohne Administratorrechte könnte unverschlüsselte Passwörter auf einem anderen Prozess lesen. Starten eines Treibers in ring0 Dies zu erreichen war das Ziel der Piraten.

    – Benutzer2284570

    1. Oktober 2013 um 21:27 Uhr

  • @JeremyBanks: Ich habe etwas vergessen: Ja, Sie könnten es /dev/mem und /dev/kmem tun, aber ab der x86-Version von Mac OS X hat Apple diese Geräte aus vielen Gründen entfernt, einschließlich der Sicherheit. Linux hat etwas Ähnliches mit einer Config-Compile-Time-Option gemacht, die die meisten Linux-Ditros aktiviert haben: Es deaktiviert den vollen Zugriff auf /dev/mem (sogar für Root) und beschränkt ihn auf nur die Adressen, die Programme (wie Xorg) verwenden.

    – Benutzer2284570

    1. Oktober 2013 um 22:13 Uhr

  • Ich weiß nicht genug über virtuellen Speicher, um die Details zu kennen, wie dies in einem modernen Betriebssystem funktioniert, aber ich verstehe, dass dies gegen die Speicherisolation verstößt und wenn möglich Administratorrechte erfordern würde. Ich stellte mir den einfachsten Fall vor, sagen wir, a zu modifizieren static int in einem C-Programm, die (vielleicht?) dem gleichen Speicherplatz zugewiesen würden oder die auf irgendeine Weise lokalisiert werden könnten. Ich habe mir irgendwie vorgestellt, dass einige Spiel-Bots, die den Zustand des Spiels untersuchen, so funktionieren könnten. Ich war mir nicht ganz sicher, ob es möglich war.

    – Jeremy

    2. Oktober 2013 um 14:52 Uhr


  • @JeremyBanks: Ich habe das gefunden Dienstprogramm Quellcode

    – Benutzer2284570

    7. Oktober 2013 um 22:41 Uhr

Benutzer-Avatar
Chris Hanson

Das Gedächtnis eines Prozesses hinter seinem Rücken zu manipulieren, ist eine schlechte Sache und voller Gefahren. Aus diesem Grund hat Mac OS X (wie jedes Unix-System) einen geschützten Speicher und hält Prozesse voneinander isoliert.

Natürlich geht das: Es gibt Einrichtungen für Shared Memory zwischen explizit kooperierenden Prozessen. Es gibt auch Möglichkeiten, die Adressräume anderer Prozesse zu manipulieren, solange der Prozess, der dies tut, das ausdrückliche Recht dazu hat (wie vom Sicherheitsframework gewährt). Aber das ist für Leute da, die Debugging-Tools schreiben. Es sollte kein normales – oder sogar seltenes – Ereignis für die überwiegende Mehrheit der Entwicklung unter Mac OS X sein.

  • Ich schätze, Sie hören viele Witze vom Typ „Bitte nehmen Sie Platz …“, oder? 😛

    – Pferdemensch

    13. Januar 2018 um 18:27 Uhr

1351900cookie-checkSpeicher eines anderen Prozesses in OS X lesen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy