PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C++ Filehandling



inmate
09.07.2010, 11:07
Hallo, ich wollte einen einfachen Scantime Crypter schreiben, doch ich stoße auf ein Problem. Die "Crypted.exe" wird nicht erstellt. Mein aktueller Source soll einfach nur die Datei einlesen und in die "Crypted.exe" im Pfad des Crypters schreiben. Der Source ist kommentiert, vllt kann der ein oder andere ja noch was davon lernen. Falls etwas falsch ist "sry".




#include <iostream> // benötigt für cout und cin
#include <windows.h> // benötigt für die API´s
#include <string.h> // benötigt für strcat

using namespace std;

#define splitchr "?0)8/6%4§2_1!" //SplitString der die Dateien wieder voneinander trennt.
#define stubpath "Stub.exe" //Der Pfad zur Stub Datei
#define mutex "[000]" //Mutex welcher erzeugt wird, damit der Crypter nicht 2x geöffnet werden kann.
#define cryptedfile "\\Crypted.exe" //Output file

int main()
{
char filebuffer[150]; // Dateibuffer
char directorybuffer[1024]; // Pfadbuffer
char pfad[MAX_PATH]; // Pfad zur Datei die eingelesen werden soll.
FILE * f; // Datei handle


CreateMutex(0, false, mutex); // Mutex wird erzeugt.

if (GetLastError() == ERROR_ALREADY_EXISTS){ // Wenn der letzte zurückgegbene Fehler "ERROR_ALREADY_EXISTS" ist, dann beende den Crypter

ExitProcess(1); // Crypter wird beendet.

}

cout << "Bitte geben sie den Pfad an:\n"; // User wird aufgefordert den Pfad anzugeben in dem die zu cryptende Datei liegt.
cin >> pfad; // Pfad wird gelesen.

if (pfad != ""){
f = fopen(pfad, "br"); // Datei wird binär und zum lesen geöffnet (b = binäry, r = read)
fseek(f, 0, SEEK_SET); // Pointer wird an den Anfang der Datei gesetzt.
fread(filebuffer, sizeof(filebuffer), 1, f); // Datei wird eingelesen.
fclose(f);

GetCurrentDirectory(1024, directorybuffer); // Aktueller Pfad wird ermittelt

f = fopen(strcat(directorybuffer, cryptedfile), "bw"); // die Output Datei wird erstellt, durch strcat werden 2 Char Variablen miteinander Verknüpft. (b = binäry, w = write)
fseek(f, 0, SEEK_SET); // Pointer wird an den Anfang der erstellten Datei gesetzt.
fwrite(filebuffer, 1, sizeof(filebuffer), f); // Dateibuffer wird in die Datei geschrieben.
fclose(f);



cout << "Datei erfolgreich verschlüsselt\n"; // Ausgabe damit der Benutzer weiß das alles funktioniert hat.
// Console weiterhin offen laßen.
} else {

cout << "Der Pfad existiert nicht!\n"; // Fehlermeldung wenn der Dateipfad welcher eingegeben werden muss leer ist.

}

getchar();

}
Vielleicht kann mir ja einer sagen wo mein Fehler liegt. Bitte mit Erklärung ;)

Edit: Getchar() weggemacht ;)

mfG

wacked
09.07.2010, 11:29
Du checkst kein einziges mal ob eine Funktion funktioniert hat. (f==NULL ?)
2 der getchars() sind unnötig und c. benutze lieber cin.get().
fopen(), fread() und fwrite() sind c. benutze lieber fstream.
das getcurrentdirectory() ist unnötig. wenn kein pfad angeben wird wird immer im momentanen gespeichert.
fseek(0,SEEK_SET); ist unnötig wenn das file grade erst geöffnet wurde. aber du solltest ja sowieso lieber fstream benutzen...

inmate
09.07.2010, 12:05
Okay danke, wieder was dazugelernt =)

mfG

G36KV
09.07.2010, 12:24
Man merkt, dass du ein VB oder Skript Programmierer bist, das hier ist ganz böse in C/C++:

if (pfad != ""){

inmate
09.07.2010, 12:41
Man merkt, dass du ein VB oder Skript Programmierer bist, das hier ist ganz böse in C/C++:

:D Joa ich habe leider immernoch Teile der VB Syntax drin :-/

Wie sollte ichs besser machen ? So:


if (pfad != NULL){ ?

mfG

blackberry
09.07.2010, 12:52
Hallo, ich wollte einen einfachen Scantime Crypter schreiben, doch ich stoße auf ein Problem. Die "Crypted.exe" wird nicht erstellt. Mein aktueller Source soll einfach nur die Datei einlesen und in die "Crypted.exe" im Pfad des Crypters schreiben. Der Source ist kommentiert, vllt kann der ein oder andere ja noch was davon lernen. Falls etwas falsch ist "sry".



f = fopen(strcat(directorybuffer, cryptedfile), "bw"); // die Output Datei wird erstellt, durch strcat werden 2 Char Variablen miteinander Verknüpft. (b = binäry, w = write)

Das tut mir echt weh...
Zudem bleibt zu sagen, dass die Datei nicht erstellt werden kann, weil das "binary" als Suffix gedacht ist.
D.h. du musst "wb" und nicht "bw" an fopen übergeben. Das ist nicht die einzige Stelle in deinem Code, an der du das machst, aber damit sollte das Problem gelöst sein.



Wie sollte ichs besser machen ? So:


if (pfad != NULL){

Das zeigt, dass du nie ein C/C++ Buch gelesen hast, geschweigedenn Zeiger und C-Strings verstanden hast.

In C ist ein C-String ein Zeiger auf den ersten Buchstaben in einer Zeichenkette im Speicher.
NULL ist kein eigenes Sprachkonstrukt, sondern ein #define für entweder ((void *) 0), oder einfach nur 0.

Du fragst also:
Ist die ADRESSE, auf die pfad zeigt null?
Da Pfad bei dir noch nicht mal ein echter Pointer, sondern ein Array (der Unterschied ist in C(++) klein, aber vorhanden) ist hat pfad IMMER eine Adresse die ungleich NULL ist, da er auf einen festen Speicherblock zeigt.

In C/C++ macht das vergleichen von Pointern also nur sinn, wenn du wissen willst ob auf GENAU DIE SELBE ADRESSE gezeigt wird.
Das wäre hier nie der Fall.

Was du machen willst ist abgleichen, ob an den beiden Adressen der selbe Inhalt ist.
Das wiederum kann man selber machen, oder man greift auf Funktionen aus der Standardbibliothek zurück (die da wären strcmp, strncmp, usw.).

Willst du lediglich checken, ob ein String leer ist oder nicht, kannst du dir auch zunutze machen, dass C-Strings mit einem NULL-Byte abgeschlossen werden (da diese ja keinerlei Größenangabe besitzen muss man ja irgendwie das Ende markieren - bei C-Strings ist das immer "\x00").
Dabei kannst du eine der folgenden Methoden benutzen:

if (pfad[0] != 0) // via Indexoperator
if (*pfad != 0) // via Zeiger-Dereferenzierung
if (*pfad) // hier wird ausgenutzt, dass 0 := false, alles ungleich null := true

inmate
09.07.2010, 12:56
Ich lerne ja noch. Außerdem lese ich grade n C++ Buch :D

Als wenn du keine Fehler gemacht hast und C++ schon von anfang an konntest.

Ja und dann hab ich halt binary mit "ä" geschrieben, schonmal geguckt was hier andere User für Rechtschreibfehler machen ? Da sagste auch nie was.

Edit: Danke für deine Erklärung. Nur wie soll ichs dann sonst machen ?

mfG

blackberry
09.07.2010, 13:05
Nächstes Edit ist drin.


Als wenn du keine Fehler gemacht hast und C++ schon von anfang an konntest.

Zu sagen, dass du Zeiger nicht verstanden hast war mehr eine Feststellung, als eine Anfeindung.
Ich bin mir des weiteren Sicher, dass dein Buch strcmp irgendwo mal erwähnt - oder ganz nach dem C++ Konzept mit der string-Klasse arbeitet, bei der ein Vergleich mit einem String-Literal (beispielsweise: "" <--- hier mal mit Anführungszeichen) durchaus möglich ist.
Dies funktioniert jedoch nur, weil in der string-Klasse aus der STL von C++ der Vergleichsoperator überladen wurde und bei so einem Vergleich eine Funktion in der string-Klasse aufgerufen wird, die das ganze abgleicht.


Ja und dann hab ich halt binary mit "ä" geschrieben, schonmal geguckt was hier andere User für Rechtschreibfehler machen ? Da sagste auch nie was.

Stimmt - da sage ich oft nichts. Aber nicht weil ich die nicht nerven will, sondern weil ich sonst nichts weiteres dazu zu sagen hätte.
Hier habe ich das das Problem angesprochen, dir einen Korrekturvorschlag gemacht und halt weils in der selben Zeile war auch noch das angemerkt :)

l0dsb
09.07.2010, 16:37
Noch ein Tipp am Rande: ExitProcess zu verwenden ist insofern ungünstig, da du so diverse Cleanup-Routinen umgehst (atexit, Destruktoren). Willst du dein Programm beenden, "return"e einfach aus der main-Funktion.