As I've stated before, my C skills are rusty and my C++ skills are
nonexistent. I've been struggling with this problem for a while, I thought
now would be a good time to ask for help.
I am trying to create a DLL from an Encryption/Decryption exe that I
created using CryptoPP. I can create a DLL with the basic input/outputs
that I need but when I start to include my Encryption/Decryption code I run
into problems. I believe that my problem is in my Makefile but I don;t
know what it might be. Any assistance would be appreciated.
I am using Mingw on W2K machine.
The following is the source of all the files that are used.
I just need to know how to replace the Encrypt and Decrypt function in my
dll with the functions in my tdes7 code.
----------------------------------------------------------------------------------
cdll.cpp
----------------------------------------------------------------------------------
#include "cdll.h"
#include <windows.h>
#include <string.h>
#include <time.h>
DLLIMPORT int dll_int_square (int i) {
return i * i;
}
DLLIMPORT double dll_double_square (double d) {
return d * d;
}
DLLIMPORT float dll_float_square (float f) {
return f * f;
}
DLLIMPORT void dll_set_global_int_var (int new_value) {
dll_global_int_var = new_value;
}
DLLIMPORT int dll_get_global_int_var () {
return dll_global_int_var;
}
DLLIMPORT void setIVString(char * myString) {
IV_String = (char *) malloc( strlen(myString) * sizeof(char) );
strcpy(IV_String, myString);
}
DLLIMPORT void setEncryptedString(char * myString) {
Encrypted_String = (char *) malloc( strlen(myString) * sizeof(char)
);
strcpy(Encrypted_String, myString);
}
DLLIMPORT void setDecryptedString(char * myString) {
Decrypted_String = (char *) malloc( strlen(myString) * sizeof(char)
);
strcpy(Decrypted_String, myString);
}
DLLIMPORT void setErrorString(char * myString) {
Error_String = (char *) malloc( strlen(myString) * sizeof(char) );
strcpy(Error_String, myString);
}
DLLIMPORT char * getEncryptedString() {
return Encrypted_String;
}
DLLIMPORT char * getDecryptedString() {
return Decrypted_String;
}
DLLIMPORT char * getErrorString() {
return Error_String;
}
DLLIMPORT int Encrypt() {
setEncryptedString(Decrypted_String);
setErrorString("Encryption Success");
return 0;
}
DLLIMPORT int Decrypt() {
setDecryptedString(Encrypted_String);
strcpy(Error_String, "Decryption Success");
return 0;
}
----------------------------------------------------------------------------------
cdll.h
----------------------------------------------------------------------------------
#ifndef cdll_h_included
#define cdll_h_included
/*
* When building the DLL code, you should define BUILDING_DLL so that
* the variables/functions are exported correctly. When using the DLL,
* do NOT define BUILDING_DLL, and then the variables/functions will
* be imported correctly.
*
* You need to be using egcs-1.1.1 or newer.
*
* Building the DLL:
* - define BUILDING_DLL, which defines DLLIMPORT
__attribute__((dllexport))
* Building the client code:
* - DO NOT define BUILDING_DLL, which defines DLLIMPORT to be one
* __attribute__((dllimport))
*/
#if BUILDING_DLL
# define DLLIMPORT __declspec (dllexport)
#else /* Not BUILDING_DLL */
# define DLLIMPORT __declspec (dllimport)
#endif /* Not BUILDING_DLL */
DLLIMPORT int dll_int_square (int) ;
DLLIMPORT double dll_double_square (double);
DLLIMPORT float dll_float_square (float);
DLLIMPORT int dll_global_int_var;
DLLIMPORT void dll_set_global_int_var (int);
DLLIMPORT int dll_get_global_int_var ();
DLLIMPORT char * IV_String;
DLLIMPORT char * Encrypted_String;
DLLIMPORT char * Decrypted_String;
DLLIMPORT char * Error_String;
DLLIMPORT void setIVString(char *);
DLLIMPORT void setEncryptedString(char *);
DLLIMPORT void setDecryptedString(char *);
DLLIMPORT void setErrorString(char *);
DLLIMPORT char * getEncryptedString();
DLLIMPORT char * getDecryptedString();
DLLIMPORT char * getErrorString();
DLLIMPORT int Encrypt();
DLLIMPORT int Decrypt();
#endif /* cdll_h_included */
----------------------------------------------------------------------------------
dllinit.cpp
----------------------------------------------------------------------------------
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#include <stdio.h>
BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
/*
*----------------------------------------------------------------------
*
* DllMain --
*
* This routine is called by the Mingw32, Cygwin32 or VC++ C run
* time library init code, or the Borland DllEntryPoint routine. It
* is responsible for initializing various dynamically loaded
* libraries.
*
* Results:
* TRUE on sucess, FALSE on failure.
*
* Side effects:
*
*----------------------------------------------------------------------
*/
BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) {
switch (reason) {
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
----------------------------------------------------------------------------------
usedll.cpp
----------------------------------------------------------------------------------
#include <stdio.h>
#include "cdll.h"
int main () {
printf ("dll_int_square (3) = %d\n", dll_int_square(3));
printf ("dll_float_square (3.0) = %f\n", dll_float_square(3.0));
printf ("dll_double_square (3.0) = %f\n", dll_double_square(3.0));
printf ("Global integer variable: Should be 99\n");
printf (" directly : %d\n", dll_global_int_var);
printf (" via DLL accessor function : %d\n", dll_get_global_int_var());
printf ("Global integer variable: Setting value to -31 directly\n");
dll_global_int_var = -31;
printf ("Global integer variable:\n");
printf (" directly : %d\n", dll_global_int_var);
printf (" via DLL accessor function : %d\n", dll_get_global_int_var());
printf ("Global integer variable: Setting value to 27 in-directly\n");
dll_set_global_int_var (27);
printf ("Global integer variable:\n");
printf (" directly : %d\n", dll_global_int_var);
printf (" via DLL accessor function : %d\n", dll_get_global_int_var());
printf (" ");
printf (" ");
char * myString = "This is a test.";
setDecryptedString(myString);
printf ("Set the Decrypted String to -%s-\n", getDecryptedString() );
printf ("Encrypt = %d.\n", Encrypt() );
printf ("Encrypted String is -%s-\n", getEncryptedString() );
return 0;
}
----------------------------------------------------------------------------------
tdes7.cpp
----------------------------------------------------------------------------------
#include "../DonCC/modes.h"
#include "../DonCC/des.h"
#include "../DonCC/hex.h"
#include <windows.h>
#include <iostream>
#include <time.h>
USING_NAMESPACE(CryptoPP)
USING_NAMESPACE(std)
const byte key[24] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xba, 0xbb,
0xa1, 0x2b, 0xc3, 0x4e, 0xf5, 0x99, 0x98, 0x97 };
const byte iv[8] = {0x8d, 0x15, 0x41, 0x5e, 0x66, 0xef, 0x2f, 0x5c};
void padString(char[], int);
char * encrypt(char *);
char * decrypt(char *);
int main(int argc, char *argv[]) {
char plaintext[1024];
char * cipherText;
char * plainText;
cout << "\nText to encrypt: ";
cin.getline(plaintext, 1024);
cout << "plaintext size is: " << sizeof(plaintext) << endl;
cout << "plaintext length is: " << strlen(plaintext) << endl;
cout << plaintext << "-" << endl;
padString(plaintext, 8);
cout << "plaintext size is: " << sizeof(plaintext) << endl;
cout << "plaintext length is: " << strlen(plaintext) << endl;
cout << plaintext << "-" << endl;
cipherText = encrypt(plaintext);
cout << "Cipher Text: " << cipherText << endl;
plainText = decrypt(cipherText);
cout << "Plain Text: " << plainText << endl;
free(cipherText);
byte * result;
delete [] result;
return 0;
}
void padString(char myString[], int size) {
int stringSize = strlen(myString);
int padSize = size - (stringSize % size);
int i=0;
if (padSize < size) {
for (i=0; i<padSize; i++)
myString[stringSize + i] = ' ';
myString[stringSize + i] = '\0';
}
}
char * encrypt(char * plainText) {
int i=0;
unsigned int outputLength;
byte * cipherText;
// Convert the plaintext to a byte array
byte bPlainText[strlen(plainText)];
for (i=0; i<strlen(plainText); i++)
bPlainText[i] = (byte)plainText[i];
// Do the Encryption
CBC_Mode<DES_EDE3>::Encryption ecbEncryption(key,
DES_EDE3::DEFAULT_KEYLENGTH, iv);
StreamTransformationFilter encryptor(ecbEncryption, NULL,
StreamTransformationFilter::NO_PADDING);
encryptor.Put(bPlainText, sizeof(bPlainText));
encryptor.MessageEnd();
outputLength = encryptor.MaxRetrievable();
cipherText = new byte[outputLength];
encryptor.Get(cipherText, outputLength);
// Encode the Cipher Text to Hex
HexEncoder hexEncoder3;
hexEncoder3.Put(cipherText, outputLength);
hexEncoder3.MessageEnd();
byte hCipherText[outputLength*2];
hexEncoder3.Get(hCipherText, outputLength*2);
// Convert the Hex Cipher Text array to a character array
char * tCipherText = (char *)malloc(outputLength*2+1);
if (tCipherText != NULL) {
for (i=0; i<(outputLength*2); i++)
tCipherText[i] = (char)hCipherText[i];
tCipherText[i] = '\0';
return tCipherText;
}
else
return "ERROR";
}
char * decrypt(char * cipherText) {
int i=0;
unsigned int outputLength;
byte * plainText;
// Convert the ciphertext to a byte array
byte bCipherText[strlen(cipherText)];
for (i=0; i<strlen(cipherText); i++)
bCipherText[i] = (byte)cipherText[i];
// Decode the Cipher Text from Hex
HexDecoder hexDecoder;
hexDecoder.Put(bCipherText, strlen(cipherText));
hexDecoder.MessageEnd();
byte hCipherText[strlen(cipherText)/2];
hexDecoder.Get(hCipherText, strlen(cipherText)/2);
//Do the Decryption
CBC_Mode<DES_EDE3>::Decryption ecbDecryption(key,
DES_EDE3::DEFAULT_KEYLENGTH, iv);
StreamTransformationFilter decryptor(ecbDecryption, NULL,
StreamTransformationFilter::NO_PADDING);
decryptor.Put(hCipherText, sizeof(hCipherText));
decryptor.MessageEnd();
outputLength = decryptor.MaxRetrievable();
plainText = new byte[outputLength];
decryptor.Get(plainText, outputLength);
char cPlainText[outputLength*2+1];
for (i=0; i<(outputLength*2); i++)
cPlainText[i] = (char)plainText[i];
cPlainText[i] = '\0';
return(strcat(cPlainText, ""));
}
----------------------------------------------------------------------------------
Makefile
----------------------------------------------------------------------------------
CXX = g++
ARFLAGS = -cr # ar needs the dash on OpenBSD
RANLIB = ranlib
LDLIBS = -lws2_32
DEBUG = -g -Wall #-O2
CXXFLAGS = $(DEBUG)
CFLAGS = $(DEBUG)
CPPFLAGS = -I.
AS = as
DLLTOOL = dlltool
DLLWRAP = dllwrap
DLL_NAME = cdll.dll
DLL_EXP_LIB = libcdll.a
DLL_EXP_DEF = cdll.def
all: cdll.dll usedll.exe tdes7.exe
SRCS = $(wildcard *.cpp)
OBJS = $(SRCS:.cpp=.o)
DLL_CFLAGS = -DBUILDING_DLL=1
DLL_LDFLAGS =
DLL_LDLIBS =
DLL_SRCS = cdll.cpp dllinit.cpp
DLL_OBJS = $(DLL_SRCS:.cpp=.o)
MYOBJS07 = tdes7.o
DLLWRAP_FLAGS = --export-all \
--output-def $(DLL_EXP_DEF) \
--implib $(DLL_EXP_LIB) \
--driver-name $(CXX)
$(DLL_NAME) $(DLL_EXP_DEF) $(DLL_EXP_LIB): $(DLL_OBJS)
$(DLLWRAP) $(DLLWRAP_FLAGS) -o $(DLL_NAME) $(DLL_OBJS) $(DLL_LDFLAGS)
$(DLL_LDLIBS)
tdes7.exe: $(MYOBJS07)
$(CXX) -o $@ $(CXXFLAGS) $(MYOBJS07) -L. -lcryptopp $(LDFLAGS)
$(LDLIBS)
usedll.exe: usedll.o $(DLL_EXP_LIB)
$(CXX) -o $@ $(CFLAGS) $(LDFLAGS) usedll.o -L./ -lcdll
.SUFFIXES: .cpp
.cpp.o:
$(CXX) -c $(DLL_CFLAGS) $(CPPFLAGS) $(CXXFLAGS) -o $@ $<
usedll.o: %o: %cpp
$(CXX) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<
tdes7.o: %o: %cpp
$(CXX) -c -o $@ $<
clean:
$(RM) *.o
----------------------------------------------------------------------------------
----------------------------------------------------------------------------------
Don Bergstrom