Reconstruction of des.exe/undes.exe
This commit is contained in:
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* DES V1.1.0 - reconstructed from des.exe
|
||||
* Original executable: (C) 1998 H.N.M. Dijkema, GPL
|
||||
*
|
||||
* IMPORTANT: despite the program name, the executable selects
|
||||
* CRYPT_ALGO_3DES + CRYPT_MODE_CBC, i.e. two-key triple DES in CBC mode.
|
||||
*
|
||||
* This is reconstructed source, not the original source text. Control flow,
|
||||
* constants, CRYPTLIB calls and file-format behaviour are derived from the
|
||||
* 16-bit Turbo C executable and verified against CRYPTLIB 0.99 source.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <io.h>
|
||||
#include "crypt.h"
|
||||
#include "des_common.h"
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
char *password;
|
||||
char *inputName;
|
||||
char *outputName;
|
||||
FILE *input;
|
||||
FILE *output;
|
||||
unsigned char *buffer;
|
||||
unsigned char *payload;
|
||||
BYTE key[ CRYPT_MAX_KEYSIZE ];
|
||||
BYTE iv[ CRYPT_MAX_IVSIZE ];
|
||||
BYTE passwordBlock[ CRYPT_MAX_KEYSIZE ];
|
||||
CRYPT_INFO cryptInfo;
|
||||
CRYPT_QUERY_INFO queryInfo;
|
||||
CRYPT_ALGO algorithm = CRYPT_ALGO_3DES;
|
||||
CRYPT_MODE mode = CRYPT_MODE_CBC;
|
||||
DES_INT32 fileVersion = DES_FILE_VERSION;
|
||||
int keySize;
|
||||
int ivSize;
|
||||
int bytesRead;
|
||||
int firstTime;
|
||||
int inputFd;
|
||||
int i;
|
||||
|
||||
if( argc == 2 )
|
||||
{
|
||||
if( strcmp( argv[ 1 ], "--copyright" ) == 0 )
|
||||
{
|
||||
printf( "%s\n\n", desProgramVersion );
|
||||
printf( "%s", desCopyrightText );
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
if( strcmp( argv[ 1 ], "--version" ) == 0 )
|
||||
{
|
||||
printf( "%s\n", desProgramVersion );
|
||||
exit( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if( argc != 4 )
|
||||
{
|
||||
fprintf( stderr,
|
||||
"usage: des <passwd> <file in> <file out>\n"
|
||||
" des --copyright\n"
|
||||
" des --version\n"
|
||||
" '-' for file --> stdin/stdout\n" );
|
||||
exit( argc == 1 ? 0 : 2 );
|
||||
}
|
||||
|
||||
password = argv[ 1 ];
|
||||
inputName = argv[ 2 ];
|
||||
outputName = argv[ 3 ];
|
||||
|
||||
if( strcmp( inputName, "-" ) != 0 &&
|
||||
strcmp( inputName, outputName ) == 0 )
|
||||
{
|
||||
fprintf( stderr, "<file in> and <file out> cannot be the same\n" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
input = ( strcmp( inputName, "-" ) == 0 ) ?
|
||||
stdin : fopen( inputName, "rb" );
|
||||
output = ( strcmp( outputName, "-" ) == 0 ) ?
|
||||
stdout : fopen( outputName, "wb" );
|
||||
|
||||
checkOpen( input, inputName );
|
||||
checkOpen( output, outputName );
|
||||
|
||||
/* The executable writes exactly four bytes here. */
|
||||
fwrite( &fileVersion, 4, 1, output );
|
||||
|
||||
algorithm = CRYPT_ALGO_3DES;
|
||||
mode = CRYPT_MODE_CBC;
|
||||
|
||||
buffer = (unsigned char *) malloc( DES_BUFFER_SIZE );
|
||||
if( buffer == NULL )
|
||||
{
|
||||
fprintf( stderr, "Cannot allocate buffer\n" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
payload = buffer + DES_PREFIX_SIZE;
|
||||
|
||||
initLibrary();
|
||||
|
||||
queryAlgoModeInformation( algorithm, mode, &queryInfo );
|
||||
keySize = queryInfo.keySize; /* 14 bytes for 3DES-CBC in 0.99 */
|
||||
ivSize = queryInfo.ivSize; /* 4 bytes for 3DES-CBC in 0.99 */
|
||||
|
||||
i = 0;
|
||||
while( i < keySize && password[ i ] != '\0' )
|
||||
{
|
||||
key[ i ] = (BYTE) password[ i ];
|
||||
i++;
|
||||
}
|
||||
while( i < keySize )
|
||||
key[ i++ ] = 0;
|
||||
|
||||
initCryptContext( &cryptInfo, algorithm, mode );
|
||||
loadCryptContext( &cryptInfo, key, keySize );
|
||||
|
||||
firstTime = TRUE;
|
||||
inputFd = fileno( input );
|
||||
|
||||
bytesRead = read( inputFd, payload, DES_PAYLOAD_SIZE );
|
||||
checkRead( bytesRead );
|
||||
|
||||
while( bytesRead != 0 )
|
||||
{
|
||||
DES_INT32 marker;
|
||||
|
||||
if( bytesRead == DES_PAYLOAD_SIZE )
|
||||
{
|
||||
marker = negativeMarker( payload );
|
||||
if( marker == 0 )
|
||||
marker = (DES_INT32) -1;
|
||||
|
||||
memcpy( buffer, &marker, 4 );
|
||||
marker = negativeMarker( payload + 4 );
|
||||
memcpy( buffer + 4, &marker, 4 );
|
||||
}
|
||||
else
|
||||
{
|
||||
marker = (DES_INT32) bytesRead;
|
||||
memcpy( buffer, &marker, 4 );
|
||||
marker = negativeMarker( payload );
|
||||
memcpy( buffer + 4, &marker, 4 );
|
||||
}
|
||||
|
||||
/* The executable always encrypts the complete 16 KiB buffer. */
|
||||
encryptBuffer( &cryptInfo, buffer, DES_BUFFER_SIZE );
|
||||
|
||||
if( firstTime )
|
||||
{
|
||||
/*
|
||||
* CRYPTLIB generates the IV on the first encryptBuffer() call.
|
||||
* Therefore it can only be retrieved after that call.
|
||||
*/
|
||||
queryContextInformation( &cryptInfo, &queryInfo );
|
||||
ivSize = queryInfo.ivSize;
|
||||
retrieveIV( &cryptInfo, iv );
|
||||
|
||||
fwrite( iv, ivSize, 1, output );
|
||||
checkWrite( output );
|
||||
fflush( output );
|
||||
|
||||
/*
|
||||
* Only keySize bytes are assigned. The remaining bytes of this
|
||||
* 256-byte stack buffer are intentionally left as they were in the
|
||||
* original executable; UNDES compares only the first keySize bytes.
|
||||
*/
|
||||
for( i = 0; i < keySize; i++ )
|
||||
passwordBlock[ i ] = key[ i ];
|
||||
|
||||
encryptBuffer( &cryptInfo, passwordBlock, CRYPT_MAX_KEYSIZE );
|
||||
fwrite( passwordBlock, CRYPT_MAX_KEYSIZE, 1, output );
|
||||
checkWrite( output );
|
||||
fflush( output );
|
||||
|
||||
firstTime = FALSE;
|
||||
}
|
||||
|
||||
fwrite( buffer, DES_BUFFER_SIZE, 1, output );
|
||||
checkWrite( output );
|
||||
fflush( output );
|
||||
|
||||
bytesRead = read( inputFd, payload, DES_PAYLOAD_SIZE );
|
||||
checkRead( bytesRead );
|
||||
}
|
||||
|
||||
/* Courtesy close call used by CRYPTLIB block-cipher examples. */
|
||||
encryptBuffer( &cryptInfo, buffer, 0 );
|
||||
|
||||
destroyCryptContext( &cryptInfo );
|
||||
endLibrary();
|
||||
|
||||
free( buffer );
|
||||
|
||||
if( input != stdin )
|
||||
fclose( input );
|
||||
if( output != stdout )
|
||||
fclose( output );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
Reference in New Issue
Block a user