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;
}