www.pudn.com > wordunp.zip > WU.CPP


// wu.cpp        -- Unprotect Microsoft Word/Winword Document 
 
 
//	Marc Thibault  
 
// Word protects a document by XOR'ing a 16-byte key repetitively 
//	through the document file, starting at byte 40. The header (0x180 bytes) 
//	is filthy with zeros including what appears to be over 48 of them at 
//	the end of the header. This program hopes that the last 32 are zeros 
//	(it checks) and extracts the key from this area. Improvements can be 
//	made to this if it ever turns out that these bytes are used for 
//	something. 
 
// The encryption key is derived from the user's passphrase by some means 
//  I have not attempted to discover. It is unnecessary, since the 
//	encryption key can be directly discovered and applied. 
 
// Call: 
//			wu infile outfile 
 
// Exit Status: 
//	1	too few arguments 
//	2	can't open given file for input 
//	3	can't open given file for output 
//	4	can't find a key (last two rows of header aren't the same) 
//	5	too short to be a Word file 
//	6	Problem writing to output file 
 
 
#include  
#include  
#ifdef __TURBOC__ 
    #include  
#endif 
#ifdef __ZTC__ 
    #include  
#endif 
 
#define Version "1.2" 
#define VersionDate "26 January 1993" 
#define keyLength 0x10 
#define bufferLength 0x180 
#define headerLength 0x180 
 
 
int  findKey(unsigned char buffer[], unsigned char key[]); 
void fixHeader(unsigned char buffer[], unsigned char key[]); 
void fixBuffer(unsigned char buffer[], unsigned char key[]); 
 
#ifdef debug 
void showBuffer(unsigned char buf[]); 
#endif 
 
char *copyLeft[] = {"\nMarc Thibault \n", 
                    " Oxford Mills, Ontario \n", 
					" This work is released to the public domain. \n", 
					" It may be copied and distributed freely \n", 
					" with appropriate attribution to the author.\n"}; 
 
 
void main(int argc, char *argv[]) 
{ 
	unsigned char buffer[bufferLength];		// data buffer 
	unsigned char key[keyLength];			// encryption key 
	size_t count, check; 
    int i; 
 
	FILE *crypt, *plain; 
 
	// ---------------------- 
 
	if( argc < 3)                         	// file names must be present 
	{ 
		cout << "\n Word Unprotect -- Version " << Version; 
		cout << "\n   by Marc Thibault, " << VersionDate; 
		cout << "\n Syntax: wu infile outfile \n"; 
		exit (1); 
	} 
 
	// Open files 
 
	if( NULL == (crypt = fopen(argv[1], "rb"))) 
	{ 
		cout << "\n wu error: can't open the input file\n"; 
		exit (2); 
	} 
 
	if( NULL == (plain = fopen(argv[2], "wb"))) 
	{ 
		cout << "\n wu error: can't open the output file\n"; 
		exit (3); 
	} 
 
    // Read header from input file 
 
	count = fread(buffer,1,headerLength,crypt); 
	if(count != bufferLength) 
	{ 
		cout << "\n wu error: Input file too short to be a Word File\n"; 
		exit(5); 
	} 
 
    // Extract the encryption key 
 
	if(findKey(buffer,key)) 
	{ 
    	cout << "\n wu error: Couldn't find a key \n"; 
		exit(4); 
	} 
 
#ifdef debug 
	cout << "\n Key in hexadecimal is"; 
	for (i=0; i