dennis_himself Geschrieben 12. Februar 2009 Geschrieben 12. Februar 2009 Hallo zusammen, ich bin neu hier, also kurz etwas zu meiner Person: Ich lerne im Moment C auf eigene Faust, also Lehrbuch gekauft und losgebüffelt! Ich bin noch ein ziemlicher Anfänger und übe zugegeben nicht so oft wie ich es sollte! Beruflich habe ich leider gar nichts damit zu tun. Achja, ich programmiere auf einem Ubuntu System. Und jetzt brauch ich mal jemanden der mir zeigt was ich im moment falsch mache. Ich habe ein kleines Tool programmiert um nvclock einfacher und schneller bedienen zu können. Ist praktisch weil ich es oft verwende und eine gute Übung für mich als Anfänger! Wenn ich den Code (siehe unten) ausführe und den Punkt 5 (Individuell) wähle führt er zwar den Befehl korrekt aus, danach folgt aber ein Stack Smashing. Ich hätte gerne daß er ins "Menü" zurückkehrt. Ich komme einfach nicht darauf woran das liegt. Könnte mich bitte einer von euch erleuchten? :hells: Schon mal vielen dank im Voraus! Hier ist der Code: #include <stdio.h> #include <stdlib.h> #include <string.h> int eingabe; int ausgang(); int individuell(); int main(void) { char eins[] = "sudo nvclock -F 25 -f"; char zwei[] = "sudo nvclock -F 36 -f"; char drei[] = "sudo nvclock -F 50 -f"; char vier[] = "sudo nvclock -F 100 -f"; printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); printf("#######################################\n"); printf("# #\n"); printf("# Grafikkarten-Ventilator-Steuerung #\n"); printf("# #\n"); printf("#######################################\n"); while (1) { puts("\n\nChoose your destiny! (1-5)"); printf("\n1 - Ventilator auf 25% "); printf("\n2 - Ventilator auf 36% "); printf("\n3 - Ventilator auf 50% "); printf("\n4 - Ventilator auf 100% "); printf("\n5 - Individuell "); printf("\n6 - Exit \n\n"); printf("Eingabe: "); scanf("%d", &eingabe); switch (eingabe) { case 1: { system(eins); break; } case 2: { system(zwei); break; } case 3: { system(drei); break; } case 4: { system(vier); break; } case 5: { individuell(); break; } case 6: { ausgang(); } default: { puts("\n\nSo nicht! Bitte nur zwischen 1, 2, 3, 4, 5 und 6 auswählen!\n"); } } } } int ausgang() { printf("\n\nBis Bald ! \n\n\n\n\n"); exit(0); } int individuell() { char x[30]; char teil1[] = "sudo nvclock -F "; char teil2[] = " -f"; printf("\n\nBitte waehlen sie die Prozentzahl zwischen 10 und 100 Prozent!: "); scanf("%s", x); strcat(teil1, x); strcat(teil1, teil2); system(teil1); } [/PHP] Zitieren
Guybrush Threepwood Geschrieben 12. Februar 2009 Geschrieben 12. Februar 2009 (bearbeitet) char teil1[] = "sudo nvclock -F "; Damit legst du dir ein 17 Zeichen Array an, woran du aber nachher noch weitere Zeichen anfügst, das heißt du überschreibst anderen Speicher und zerstörst dir somit deinen Stack. PS: Außerdem solltest du bei scanf einen int Wert mit %i einlesen... PPS: Das Selbe passiert wenn der Benutzer hier scanf("%s", x); mehr als 29 Zeichen eingibt, dann wird ebensfalls anderer Speicher überschrieben. Sowas sind übrigens auch sehr beliebte Sicherheitslücken um Schadcode einzuschleusen und auszuführen. Das heißt überall wo du mit Arrays arbeitest musst du darauf achten das die Grenzen eingehalten werden und weder du noch der Benutzer irgendwo was überschreiben kann. Bearbeitet 12. Februar 2009 von Guybrush Threepwood Zitieren
dennis_himself Geschrieben 12. Februar 2009 Autor Geschrieben 12. Februar 2009 Stimmt, ich hab fälschlicherweise der x-Variable 30 Zeichen gegeben...wie dämlich. Vielen Dank ! Das mit dem int Wert habe ich nicht gemacht weil ich dachte es könnte zu Problemen führen wenn man mit strcat zwei char und einen int wert zusammenführt. Ist das grundsätzlich egal? Zitieren
Amstelchen Geschrieben 12. Februar 2009 Geschrieben 12. Februar 2009 den lerneffekt in allen ehren, aber ein via sudo ausgeführtes command mit einer GUI aufzupeppen, fällt für mich nicht unter "einfacher und schneller" bedienen; im gegenteil. wenn der aufrufende user kein sudoer ist, hauts das programm auf. wenn ein SIGINT oder SIGQUIT kommt, ist das system() egal. wenns die befehle sudo oder nvclock aufhaut, wird system() das eventuell nicht mitbekommen. system() ist sowieso nicht POSIX-konform, auf linux mag das funktionieren, das wars dann aber auch schon. nur meine 0,02 €. s'Amstel Zitieren
dennis_himself Geschrieben 12. Februar 2009 Autor Geschrieben 12. Februar 2009 Ich bin der einzige User, also sind sudo Befehle kein Problem. 1. Doppelklick -> Programm startet 2. Auswahl treffen, Passwort eingeben, fertig Geht schneller, ich erspar mir den kompletten Befehl einzugeben. Terminal öffnen und Passwort eingeben müsste ich ja so oder so. Ich will das Tool natürlich noch Stück für Stück erweitern, aber dafür muss ich erstmal etwas besser werden. Ist quasi ein Batch file mit Menü, dass ich das nicht vertreiben kann ist mir auch klar! PS: Ich weiss nicht mal was POSIX sein soll... Zitieren
Guybrush Threepwood Geschrieben 12. Februar 2009 Geschrieben 12. Februar 2009 Stimmt, ich hab fälschlicherweise der x-Variable 30 Zeichen gegeben...wie dämlich. Vielen Dank ! Das mit dem int Wert habe ich nicht gemacht weil ich dachte es könnte zu Problemen führen wenn man mit strcat zwei char und einen int wert zusammenführt. Ist das grundsätzlich egal? sorry aber ich glaube nicht das du meinen Post verstanden hast weil deine Antwort darauf keinen Sinn ergibt. Ich würde dir dringenst empfehlen dich nochmal intensiv mit Array (vorallem char Arrays) auseinanderzusetzten. Zitieren
dennis_himself Geschrieben 13. Februar 2009 Autor Geschrieben 13. Februar 2009 (bearbeitet) Natürlich habe ich das verstanden, da ich an das 17 Zeichen lange Array was anfüge, überschreibe ich Speicher der nicht reserviert ist. Teil1 + x + Teil2 = mehr als 17 Zeichen! Ich habe versehentlich der X- Variable 30 Zeichen gegeben die ich eigentlich Teil1 geben wollte... Was macht da jetzt keinen Sinn ??? Bearbeitet 13. Februar 2009 von dennis_himself Zitieren
Guybrush Threepwood Geschrieben 13. Februar 2009 Geschrieben 13. Februar 2009 Was glaubst du passiert hier? char teil1[] = "sudo nvclock -F "; Zitieren
dennis_himself Geschrieben 13. Februar 2009 Autor Geschrieben 13. Februar 2009 Es wird ein Speicherblock reserviert, dieser wird mit dem Inhalt 'sudo nvclock -F ' gefüllt. Zitieren
Guybrush Threepwood Geschrieben 13. Februar 2009 Geschrieben 13. Februar 2009 Ja aber das wichtige ist die Größe des Speicherblocks, bisher sieht das für mich so aus das du davon ausgehst der ist beliebig groß. Tatsächlich wird der aber nur so groß wie der String den du zuweißt. Das heißt hier char teil1[] = "sudo nvclock -F "; wären das 17 Bytes und hier char teil2[] = " -f"; 4 Bytes. Was aber nicht funktioniert ist sowas: char t[]; strcpy(t,"hallo"); [/PHP] Ich weiß jetzt nicht ob das einen Compilerfehler verursacht, aber im Besten Fall hat t so Platz für 0 Zeichen. Das heißt du hast 2 Möglichkeiten: 1. Du reservierst soviel Platz für deine Arrays wovon du ausgehst das es für den Programmbedarf ausreicht und begrenzt die Benutzereingaben so das nie ein Pufferüberlauf stattfinden kann. 2. Du arbeitest mit dynamisch reserviertem Speicher, was das Ganze aber sehr viel komplizierter macht und ich würde die erstmal zu Punkt 1 raten. Begrenzen kannst du die Benutzer eingabe per scanf so [PHP] scanf("%20s", t); Das heißt in folgendem Beispiel wärst du erstmal auf der sicheren Seite: char t[100]; char teil1 [] = "Hallo "; char teil2 [50]; scanf ("%49s", teil2); strcpy (t,teil1); strcat(t,teil2); [/PHP] Vorrausgesetzt natürlich du initialisierst teil1 nicht mit einem String länger als 50 Zeichen Zitieren
dennis_himself Geschrieben 13. Februar 2009 Autor Geschrieben 13. Februar 2009 Ok, das mit der Größe des Speicherblocks war mir schon klar, Ich dachte mir: Gib der Variable Teil1 einfach 30 Zeichen, das langt dicke wenn ich da noch die 2 anderen Streams hinzufüge. Ich runde immer auf, und zähl nicht genau wieviele Zeichen das maximal sein werden, schlechte Angewohnheit ich weiss. Dummerweise habe ich aber der variablen X die 30 Zeichen gegeben... aus Unachtsamkeit. Das mit der Begrenzung damit der Reservierte Speicher nicht "überläuft" ist mir neu. Aber gut zu wissen, ich werde künftig versuchen das zu beherzigen! :floet: Mein Programm läuft letzt jedenfalls einwandfrei, und ich hab noch vieles was ich verbessern und erweitern kann. So hab ich die nächsten Wochen wenigstens etws zu tun! Vielen Dank für die Aufklärung! Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.