Segmentation fault(core dumped)



  • Hi!

    Ich habe wieder mal ein Problem 🙂

    Mein Programm läuft alles so wie es sein soll.
    Am Ende wird jedoch "Segmentation fault(core dumped)" angezeigt.

    Nach meiner ansicht greife ich auf keine Konsolen Parameter oder Inhalte außerhalb der Adressgrenzen meines Programms zu.

    Was löst sonst dieses Problem aus?

    Danke

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <signal.h>
    #include <getopt.h>
    #include <string.h>
    #include <unistd.h>
    #include "pdfparser.h"
    #include "pdfcrack.h"
    #include "benchmark.h"
    
    #define PRINTERVAL 20 /** Print Progress Interval (seconds) */
    #define CRASHFILE "savedstate.sav"
    #define VERSION_MAJOR 0
    #define VERSION_MINOR 16
    
    #define _FILE_OFFSET_BITS 64
    
    /** alarmInterrupt is used to print out the progress at specific intervals */
    static void
    alarmInterrupt() {
      if(!printProgress())
        alarm(PRINTERVAL);
    }
    
    /** autoSave is used to save down the current state when interrupted */
    __attribute__ ((noreturn)) static void
    autoSave(int sig) {
      FILE *file;
    
      if(sig)
        fprintf(stderr,"Caught signal %d!\nTrying to save state...\n",sig);
      if((file = fopen(CRASHFILE, "w")) == 0) {
        fprintf(stderr,"Could not open %s for writing\n", CRASHFILE);
      }
      else{
        saveState(file);
        fclose(file);
        fprintf(stderr,"Successfully saved state to %s!\n",CRASHFILE);
      }
      exit(sig);
    }
    
    int
    main() {
      int ret = 0, minpw = 0, maxpw = 32;
      struct sigaction act1, act2;
      FILE *file = NULL, *wordlist = NULL;
      bool recovery = false, quiet = false,
        work_with_user = true, permutation = false;
      uint8_t *userpassword = NULL;
      char *charset = NULL, *inputfile = NULL, *wordlistfile = NULL;
      EncData *e;
    
      inputfile="1.pdf";
    
      if(!inputfile || minpw < 0 || maxpw < 0) {
        ret = 1;
        goto out3;
      }
    
      if((file = fopen(inputfile, "rb")) == 0) {
        fprintf(stderr,"Error: file %s not found\n", inputfile);
        ret = 2;
        goto out3;
      }
    
      e = calloc(1,sizeof(EncData));
    
      if(recovery) {
        if(wordlistfile) {
          free(wordlistfile);
          wordlistfile = NULL;
        }
        if(!loadState(file, e, &wordlistfile, &work_with_user)) {
          fprintf(stderr, "Error: Not a savefile or savefile is damaged\n");
          ret = 3;
          goto out1;
        }
    
        if(!quiet)
          printf("Loaded state for %s\n", inputfile);
      }
      else { /** !recovery */
        if(!openPDF(file,e)) {
          fprintf(stderr, "Error: Not a valid PDF\n");
          ret = 3;
          goto out1;
        }
    
        ret = getEncryptedInfo(file, e);
        if(ret) {
          if(ret == EENCNF)
    	fprintf(stderr, "Error: Could not extract encryption information\n");
          else if(ret == ETRANF || ret == ETRENF || ret == ETRINF)
    	fprintf(stderr, "Error: Encryption not detected (is the document password protected?)\n");
          ret = 4;
          goto out1;
        }
        else if(e->revision < 2 || (strcmp(e->s_handler,"Standard") != 0 || e->revision > 5)) {
          fprintf(stderr, "The specific version is not supported (%s - %d)\n", e->s_handler, e->revision);
          ret = 5;
          goto out1;
          }
      }
    
      if(fclose(file)) {
        fprintf(stderr, "Error: closing file %s\n", inputfile);
      }
    
      if(minpw > maxpw) {
        fprintf(stderr, "Warning: minimum pw-length bigger than max\n");
      }
    
      if(wordlistfile) {
        if((wordlist = fopen(wordlistfile, "r")) == 0) {
          fprintf(stderr,"Error: file %s not found\n", wordlistfile);
          ret = 6;
          goto out2;
        }
      }
    
      act2.sa_handler = autoSave;
      sigfillset(&act2.sa_mask);
      act2.sa_flags = 0;
      sigaction(SIGINT, &act2, 0);
    
      if(!quiet) {
        printEncData(e);
        act1.sa_handler = alarmInterrupt;
        sigemptyset(&act1.sa_mask);
        act1.sa_flags = 0;
        sigaction(SIGALRM, &act1, 0);
        alarm(PRINTERVAL);
      }
    
      /** Try to initialize the cracking-engine */
      if(!initPDFCrack(e, userpassword, work_with_user, wordlistfile,
    		   wordlistfile?Wordlist:Generative, wordlist, charset,
    		   (unsigned int)minpw, (unsigned int)maxpw, permutation)) {
        cleanPDFCrack();
        fprintf(stderr, "Wrong userpassword, '%s'\n", userpassword);
        ret = 7;
        goto out2;
      }
    
      /** Do the actual crunching */
      runCrack();
    
      /** cleanup */
      cleanPDFCrack();
      freeEncData(e);
    
      if(wordlistfile) {
        fclose(wordlist);
        free(wordlistfile);
      }
      if(inputfile)
        free(inputfile);
      if(charset)
        free(charset);
      if(userpassword)
        free(userpassword);
    
      return 0;
    
     out1:
      if(fclose(file))
        fprintf(stderr, "Error: closing file %s\n", inputfile);
     out2:
      freeEncData(e);
     out3:
      if(inputfile)
        free(inputfile);
      if(charset)
        free(charset);
      if(userpassword)
        free(userpassword);
    
      exit(ret);
    }
    


  • Kleine Ergänzung:

    Falls jemand irgendwelche eingebundene Dateien benötigt, kann ich sie gerne hochladen (nach: Den richtigen Code posten: reduziertes kompilierbares Beispiel)

    Danke



  • Ist lange her, dass ich zuletzt was mit Signalhandlern zu tun hatte - aber IIRC war es keine gute Idee, in einem Signalhandler Funktionen aus stdio.h zu verwenden.



  • Also sollte ich die Funktionen "alarmInterrupt()" und "autoSave(int sig)" löschen und deren Aufruf?



  • Ja, versuch das mal.



  • SG1 schrieb:

    Ja, versuch das mal.

    Danke SG1

    Das habe ich schon gemacht aber dafür eine Reihe von Fehler bekommen.

    Zum Beispiel "free(): invalid pointer: 0x000055862d9ba438

    und anschließend ein Dutzend von verweise (soll ich dir/Ihnen ein Screenshot schicken?)



  • Ich habe die Datei/ das Projekt von pdfcrack in der Version 0.16.
    Mein Zeil war/ist dies als Funktionsaufruf umzuschreiben



  • Das ist kein compilierbarer Stand und obendrein schlimmes Gehacke.
    Die Header fehlen, evtl. fehlen auch noch Libs?
    Wenn die Lizenzbedingungen es hergeben, lade es in Github hoch und hoffe, dass sich dann jemand des Problems annimmt.



  • Wutz schrieb:

    Das ist kein compilierbarer Stand und obendrein schlimmes Gehacke.
    Die Header fehlen, evtl. fehlen auch noch Libs?
    Wenn die Lizenzbedingungen es hergeben, lade es in Github hoch und hoffe, dass sich dann jemand des Problems annimmt.

    Danke, hast bestimmt Recht 🙂

    Hier einpaar Links voher ich es habe (Version 0.16)

    http://pdfcrack.sourceforge.net/
    https://sourceforge.net/projects/pdfcrack/files/

    Mein Ziel ist/war, das so umzuschreiben, dass ich es per Funktionsaufruf "starten" kann.



  • Zeile 55 passt nicht zu Zeile 160/175.
    Selbst wenn das die Lösung war bleibt der Code stupides Gehacke.



  • Ich habe den Müll des Originalautors mal in brauchbare Bahnen gelenkt.
    Es passiert häufig, dass Grobmotoriker mit blasphemischen Neigungen C missbrauchen, so wie hier:

    - globale Variablen inkl. Gebrauch 'void funktion(void)' Unsinn
    - Makros
    - stdout-Ausgaben in tieferen Berechnungsschichten
    - unsinnige Mikrooptimierungen mit Compilerfeatures die die Plattformunabhängigkeit verhindern
    - ...

    Stattdessen hätte er mal zu OMP ohne ähnlichem greifen sollen, aber da hätte er ja vernünftig designen müssen (Verzicht auf globale Variablen u.ä.)

    So könnte also eine in eigenen Programmen wiederverwendbare Funktion aussehen:(statt 400 Zeilen nur 100, dafür aber superportabel)

    #define _CRT_SECURE_NO_WARNINGS 1
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <string.h>
    
    #include "pdfparser.h"
    #include "pdfcrack.h"
    
    #define _FILE_OFFSET_BITS 64 /* in VStudio einfach als 64-Bit compilieren, das bewirkt diesbezgl. dasselbe */
    
    enum {	PWD_NOTFOUND = -1, 
    		PWD_FOUND, 
    		INVALID_ARGS, 
    		FILE_NOTFOUND, 
    		PDF_NOTVALID, 
    		NOT_ENCRYPTED, 
    		ENCRYPTION_NOTDETECTED, 
    		VERSION_NOTSUPPORTED, 
    		WRONGUSERPASSWORD };
    
    int getPwdPDF(const char *inputfilename, const char *charset, int minpwdlen, int maxpwdlen, char *password)
    {
    	EncData e = { 0 };
    	FILE *f;
    
    	if (!inputfilename || minpwdlen < 1 || maxpwdlen<1 || minpwdlen>maxpwdlen)
    		return INVALID_ARGS;
    
    	if ((f = fopen(inputfilename, "rb")) == 0)
    		return FILE_NOTFOUND;
    
    	if (!openPDF(f, &e))
    		return fclose(f), PDF_NOTVALID;
    
    	int ret = getEncryptedInfo(f, &e);
    	if (ret) {
    		if (ret == EENCNF)
    			return fclose(f), NOT_ENCRYPTED;
    		else if (ret == ETRANF || ret == ETRENF || ret == ETRINF)
    			return fclose(f), ENCRYPTION_NOTDETECTED;
    	}
    	else if (e.revision < 2 || (strcmp(e.s_handler, "Standard") != 0 || e.revision > 5))
    		return fclose(f), VERSION_NOTSUPPORTED;
    
    	fclose(f);
    
    	if (!initPDFCrack(&e, 0, 1, 0,
    		Generative, 0, charset,
    		minpwdlen, maxpwdlen, 1)) {
    		cleanPDFCrack();
    		return WRONGUSERPASSWORD;
    	}
    
    	/* hierfür muss static in pdfcrack.c entfernt werden */
    	extern uint8_t *currPW;
    	extern unsigned int currPWLen;
    
    	if (runCrack()) /* diese Funktion muss leicht geändert werden und statt void einen int liefern */
    	{
    		sprintf(password, "%.*s", currPWLen, currPW);
    		return cleanPDFCrack(), PWD_FOUND;
    	}
    
    	cleanPDFCrack();
    	return PWD_NOTFOUND;
    }
    
    int main(int argc, char**argv)
    {
    	char pwd[100];
    	int ret = getPwdPDF(argv[1], "abcdefghijklmnopqrstuvwxyz", 6, 6, pwd);
    	if (ret < 0)
    	{
    		puts("Passwort nicht gefunden");
    	}
    	else
    		if (ret > 0)
    		{
    			fprintf(stderr, "Fehlercode: %d", ret);
    		}
    		else
    			printf("Passwort: %s", pwd);
    
    	return 0;
    }
    

Anmelden zum Antworten