Reconstruction of des.exe/undes.exe

This commit is contained in:
2026-09-09 23:28:46 +02:00
parent b90136f137
commit 5aa37bf374
64 changed files with 13344 additions and 2 deletions
+205
View File
@@ -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 );
}