Crashtest :D
-
hey

kompiliert mal bitte diesen CODE:
int main() { string satz[2] = {"World", "Hallo"}; for(int i = 2; i >= 0; --i) { cout<<satz[i]; } cout<<"\n"; return 0; }und dann aufrufen und schon seht ihr was ich meine xD
man sieht dann alle Windowsordner mit source(benötigt diesen Ressourcen editor zum nachprüfen)Guckt euch das mal an
mfg
-
Wie hast du das denn rausgefunden?
MfG
-
Warum so umständlich ?
int main() { char* satz = 0; cout<< *satz; return 0; }Macht dasselbe.
Gruß,
Simon2
-
hmm joa ... du greifst nur auf einen bereich zu in dem du nichts zu suchen hast ... std::string string[2] => string[2] net da
muss string[1] heißen 
-
Simon2 schrieb:
Warum so umständlich ?
int main() { char* satz = 0; cout<< *satz; return 0; }Macht dasselbe.
Gruß,
Simon2
oder so:
int main() { return *((int*)0); }
-
Ist wohl alles reine Glückssache. Beim obigen Code (Simon) z.B. stürzt das Programm auf meinem Rechner einfach ab. Ich hatte auch mal vor Ewigkeiten versehentlich nen Array überlaufen, und dessen Inhalt anzeigen lassen. Brachte ganz lustige Infos über die CPU (Stepping, Modell, Befehlssatz etc.), und ein paar Ordner sowie Benutzer (!) -daten zum Vorschein, bis das Programm abstürzte. Nen Screenshot existiert auch davon.
Ein uninitialisierter Pointer, der auf fremden Speicherbereich zeigt, produziert eine Access Violation, und somit ist das Verhalten undefiniert.
[EDIT:] Der Code von Marco zeigt hingegen tatsächlich einige Infos an, sehr ähnlich zum Screenshot. Mein PC piepste ein paar mal, und danach stürzte das Programm ab.
-
Schwach.
Thomas:~ Thomas$ cat > test.cpp #include <iostream> using namespace std; int main() { string satz[2] = {"World", "Hallo"}; for(int i = 2; i >= 0; --i) { cout<<satz[i]; } cout<<"\n"; return 0; } Thomas:~ Thomas$ g++ test.cpp -o test Thomas:~ Thomas$ ./test Segmentation fault Thomas:~ Thomas$ rm test*
-
Mh also ich hab mir den Thread hier jetzt grad durchgelesen und das dann selber sofort mal ausprobiert, und das funktioniert ja echt. Was passiert da den jetzt genau? Man greift auf eine string Adresse vom Betriebsystem zu oder? Aber warum steht in einem string so viel drin??? Wenn man das mit 4 probiert dann kommt bei mir noch viel mehr. Kann man soviel überhaupt in einen string reinschreiben? Und was ist das genau was da drin steht? Was passiert da, hat jemand eine Ahnung von?
CODE:
#include <iostream> using namespace std; int main() { string test[1]; cout << test[20] << endl; return 0; }Bei 2,4,11,14 und 20 kommen witzige Ergebnisse bei mir! Weiter hatte ich keinen bock mehr zu suchen.
Bei 13,15 und 19 z.B. kommt bei mir nicht mal n Error.
Also irgendwie fasziniert mich das jetzt
Dankeschön schon mal im Voraus.
-
Stromberg schrieb:
Man greift auf eine string Adresse vom Betriebsystem zu oder?
Nein, es hat nichts mit strings und dem Betriebssystem zu tun. Das OS kennt keine "strings" in dem Sinne, es ist nur eine simple Klasse. Hierbei handelt es sich viel mehr um Adressen. Um jetzt nicht noch genauer auf die überladenen Indexoperatoren der string-Klasse einzugehen, betrachten wir die string-Klasse einfach mal als einen rohen char* String, also eine Zeichenkette. Mit dem [] Operator greift man auf eine Speicheradresse zu. Vorher muss man sich diese Adressen reservieren, also dem Betriebssystem sagen, "hey, ich möchte z.B. 4 kb Speicher haben, gib mir den mal". Dieser angeforderte Speicher steht dir dann frei zur Verfügung, und kein anderes Programm darf darauf zugreifen (es sei denn, man verwendet ReadProcessMemory (), aber das ist wieder ne andere Geschichte). Selbiges gilt natürlich auch für dich. Du darfst nur in deinem eigenen Speicherbereich agieren, aber nicht auf fremden zugreifen, da es sonst einen Segmentation Fault gibt, und das Programm stürzt ab (Verursacht durch Windows persönlich!). Natürlich kann dich aber trotzdem niemand daran hindern, auf diese Bereiche zuzugreifen, wie es in den obigen Codebeispielen gezeigt wurde. In dem Fall wurde dem string nur ein bestimmter Speicherbereich reserviert, (z.B. 20 Zeichen), und du versuchst, auf das 25 Zeichen (nichts anderes als ne Speicheradresse) zuzugreifen. Da diese Adresse jedoch nicht deinem Programm zugewiesen wurde, kannst du zwar deren Inhalt auslesen und anzeigen lassen, jedoch lässt dann Windows das Programm abstürzen (da nicht gestattet!). Das ist eigentlich der ganze Zauber an der Sache. Du machst nichts anderes, als den Inhalt bestimmter Speicheradressen auszulesen.
Das mit den Stringgefummel ist übrigens nur ein Nebeneffekt. Um gezielt den Inhalt einer Speicheradresse auszulesen, kann man z.B. folgendes machen:
unsigned char addr = 0x04FF; unsigned char *inhalt = reinterpret_cast <unsigned char*> (addr); std::cout<<*inhalt;...Programmabsturz vorprogrammiert

Wer sich näher mit dem Thema beschäftigen möchte, dem seien Buffer Overflow Exploits ans Herz gelegt, denn dieses Märchen geht noch viel weiter

-
Was man hier ausliest ohne das das Programm abstürzt, ist kein prozessfremder Speicher sondern Speicher, der vom Betriebssystem in den Adressraum des eigenen Prozesses eingeblendet wird. Es ist also nicht so, als würde man verbotenen Speicher lesen (der Zugriff ist Programm-intern natürlich als nicht typsicher zu bezeichnen), sondern man liest Informationen aus, die das Betriebssystem einen sowieso zur Verfügung stellt und die man über geeignete API-Funktionen wesentlich typsicherer Abfragen kann. Der Grund warum das Betriebssystem es so macht ist, dass es einfach performanter ist, die Informationen in den Speicherbereich readonly (und shared) für alle Prozesse einzublenden, anstatt das das Programm jedesmal einen langsamen Betriebssystem-Aufruf machen muss.
Also muss ich eure Begeisterung bremsen, damit kommt man unter Windows NT nicht an geheime Informationen.