2015-08-02 10 views
5

Ich habe ASLR deaktiviert. Nun, ich möchte die Adresse der Umgebungsvariablen "SHELL" erhalten, also verwende ich die C-Funktion getenv().Holen Sie die Umgebungsvariable Adresse

#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char *argv[]) 
{ 
    char* ptr = getenv("SHELL"); 
    printf("%p\n", ptr); 
} 

Die Adresse mit getenv erhalten()

$ ./getenv 
0xbffff752 

Die Adresse mit GDB erhalten:

gdb> x/4000s $esp 
... 
(gdb) x/s 0xbffff710 
0xbffff710:  "SHELL=/bin/bash" 
(gdb) x/s 0xbffff716 
0xbffff716:  "/bin/bash" 

Warum sind die verschiedenen Adressen? Wie bereits erwähnt, muss ich die korrekte Adresse in der mit GDB erhaltenen Adresse angeben.

+1

Woher wissen Sie, dass die richtige Adresse mit gdb ist? Sicherlich sind beide richtig –

+1

Beide leben in verschiedenen Umgebungen. –

+0

@EdHeal Wenn ich mit der mit der C-Funktion erhaltenen Adresse suche: (gdb) x/s 0xbffff752 0xbffff752: \t David

Antwort

0

[Linux]

Von man 3 getenv() (kursiv von mir):

Die Implementierung von getenv() wird nicht als einspringende erforderlich. Die Zeichenfolge , auf die der Rückgabewert von getenv() verweist, kann statisch zugewiesen sein und kann durch einen nachfolgenden Aufruf von getenv() geändert werden.

Dies bedeutet, dass der Wert abgefragt kopiert werden kann, und ein Verweis auf die Kopie zurückgegeben, so dass die Adresse zurück Macht von der Adresse unterscheiden, wo die ursprüngliche env-var-Tupel gespeichert wird.

+0

Was hat 'reentrant' mit der Frage zu tun? – user3629249

+0

@ user3629249: Bitte sehen Sie meine aktualisierte Antwort. – alk

+0

@alk Während die man-Seite das sagt, und einige wirklich alte Betriebssysteme das getan haben, tut das derzeit kein Betriebssystem. Diese Antwort ist * nicht * der Grund für das beobachtete Verhalten. –

1

Das Problem ist, dass Ihre Liste der Umgebungsvariablen kann abweichen, wenn Sie unter gdb und ohne es ausführen. Und das ist genug, um die Verschiebung der Adresse zu verursachen.

Etwas verkürzt Angebot ... (Ihr Programm)

$ gdb ./a.out 
(gdb) r 
Starting program: /home/mfranc/a.out 
0x7fffffffdd37 
(gdb) r 
Starting program: /home/mfranc/a.out 
0x7fffffffdd37 
(gdb) set environment a="hello world" 
(gdb) r 
Starting program: /home/mfranc/a.out 
0x7fffffffdd27 
(gdb) r 
Starting program: /home/mfranc/a.out 
0x7fffffffdd27 
(gdb) unset environment a 
(gdb) r 
Starting program: /home/mfranc/a.out 
0x7fffffffdd37 
(gdb) 

Generell sollten Sie in der ursprünglichen Umgebung debuggen und an den Prozess über gdb -p $ PID anhängen. Wenn Sie den Prozess auf eine etwas andere Art und Weise erzeugen und die Umgebung sich geringfügig unterscheidet, sehen Sie möglicherweise unterschiedliche Adressen.

+0

mm, wie Sie und @ user3629249 sagt, die Adressen sind unterschiedlich, weil mein Programm unter gdb läuft. Ich verstehe einen Debugger debuggen einen Prozess, aber der Prozess ist unabhängig (es ist ein "normaler" Prozess) und gdb nur stoppen, ändern, etc. es. Was ist genau passiert? gdb fügt keine Umgebungsvariablen hinzu. – David

+1

@David Die Sache, die passiert ist, ist, wenn Sie gdb ./program gdb ist das übergeordnete Element Ihres Prozesses. Wenn Sie absolute Unabhängigkeit wünschen, müssen Sie in der ursprünglichen Umgebung debuggen und über gdb -p $ PID an den Prozess anhängen. –

+0

Ok, ok. Kann ich das Programm nicht ausführen und den Prozess für attach after mit gdb erstellen? Als normales Debug mit gdb möchte ich sagen. Ich will das testen. – David

5

Warum sind die Adressen unterschiedlich?

Weil man unter gdb läuft und man nicht ist. Das Ausführen in einer anderen Umgebung führt zu einer anderen Umgebung. Buchstäblich.

Was ist die Ausgabe der printf()-Anweisung bei der Ausführung unter gdb?

Als Hinweis muss ich die richtige Adresse in der mit gdb erhalten.

Auf welche Informationen basiert diese Aussage?

Verwandte Themen