2013年3月24日 星期日

學習開發DLL筆記


最近學習用VC來開發Win32 DLL,學了這幾天,來作個總結。
一、生成DLL
1、用VC建立一個Win32DLL工程--DllTest,選上「導出符號」;
2、在DllTest.cpp中編寫導出函數Fun(),這個函數是別的程序要調用的函數:
int fun(int i)
{
return i*i;
}
3、在DllTest.h中聲明導出這個函數:
__declspec(dllexport) int fun(int i);
4、第三步也可以用DEF文件來指定要導出的函數,這樣做可以在程序運行過程中顯式的加載DLL。關於在程序運行過程中顯式的加載DLL見 二、調用DLL
添加一個DEF文件到工程,寫入如下內容:
EXPORTS
Fun
5、編譯這個工程,生成DllTest.dll,同時也生成了DllTest.lib文件。這個文件是供程序開發用的導入庫
二、調用DLL
調用DLL有兩種方法:
裝載期間動態鏈接--模塊可以向調用本地函數一樣調用從其他模塊導出的函數。裝載期間鏈接必須使用DLL的導入庫,也就是.lib文件。它為系統提供了加載這個DLL和定位DLL中的導出函數所需要的信息。
運行期間動態鏈接--程序運行期間可以使用LoadLibrary加載這個DLL,然後調用GetProcAddress函數取得DLL導出函數的地址,然後通過函數地址調用DLL中的函數。
1、裝載期間動態鏈接。
新建一個Win32 Console Application工程--DllApp。把剛才建立的那個工程中的DllTest.dll、DllTest.h和DllTest.lib拷貝到DllApp目錄下。在DllApp.cpp文件中寫入:
#include <windows.h>
#include <stdio.h>
#include "DllTest.h"
//要鏈接到的DllTest.lib庫
#pragma comment(lib,"DllTest.lib")
void main()
{
int a = Fun(2);
printf("The result is %d/n",a);
}
2、運行期間動態加載
新建一個Win32 Console Application工程--DllApp2。把建立的DllTest.dll拷貝到DllApp2目錄中--一定要用在生成DLL部分按照第四步產生的DLL文件,否則程序無法運行。在DllApp2.cpp中寫入:
#include <windows.h>
#include <stdio.h>
typedef void (*PFUN)(int);//聲明函數原型
void main()
{
HMODULE hModule = ::LoadLibrary("DllTest.dll");//加載DLL庫
PFUN newfun = (PFUN)::GetProcAddress(hModule,"fun");//取得fun函數的地址
int i = newfun(2);
printf("The result is %d",i);
::FreeLibrary(hModule);
}

2013年3月21日 星期四

C Tutorial - XOR Encryption

First of all, XOR encryption alone is very easy to create and can be easily broken (especially if a weak key is used). This tutorial assumes no responsibility for the quality of encryption.

Now, the first thing to now about XOR encryption is what exactly an XOR operation is. XOR stands for exclusive-or, it is a logical operand. XOR returns true if one and only one of the two arguments is true. A few examples:

1 xor 0 = 1
0 xor 1 = 1
1 xor 1 = 0
0 xor 0 = 0

Notice that if you were to xor the result against the key you will end up with the original value. This is how decrypting XOR encryption works. XOR is a symmetrical operation, so if you encrypt a file and then encrypt it again with the same key you will receive the original plaintext.

Now the XOR encryption uses this operand to cycle through each bit of plaintext and XOR's it against a key. The longer and more random a key is, the stronger the encryption.

The algorithm itself is the focus of this tutorial. The remainder of the program (I/O, etc) will be posted at the bottom but not explained outside of comments.


void encrypt_data(FILE* input_file, FILE* output_file, char* key)
{
 int key_count = 0; //Used to restart key if strlen(key) < strlen(encrypt)
 int encrypt_byte;

 //Loop through each byte of file until EOF
 while( (encrypt_byte = fgetc(input_file)) != EOF) 
 {
  //XOR the data and write it to a file
  fputc(encrypt_byte ^ key[key_count], output_file);

  //Increment key_count and start over if necessary
  key_count++;
  if(key_count == strlen(key))
   key_count = 0;
 }
}

In C (and many other languages) the ^ is the character that represents XOR.

encrypt_data() takes an input and output file and a key to encrypt with. fgetc() returns the next character from the input stream (our file). We XOR the current character of the file against the corresponding index of key. We then use fputc (it places the given character into an output stream) to place the XOR'ed data into out output file. Finally, we loop key to the index of 0 if we have reached the end of key. 

Again, your encryption is only as strong as your key. I would not recommend this for any serious encryption (there are MANY MANY better methods of encryption). I have written this purely as a learning resource and an introduction to cryptography. Below is the source code in whole:


//XOR Encryption

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_SIZE 256

void strip_newline(char* to_strip);
void encrypt_data(FILE* input_file, FILE* output_file, char *key);

int main(int argc, char* argv[])
{
 //Check for valid number of arguments
 if (argc != 3)
 {
  printf("Invalid number of arguments. %d arguments were supplied.\n", argc);
  printf("Usage: %s inputfile outputfile\n", argv[0]); //Usage: ./xortest inputfile outputfile
  exit(0);
 }
 
 FILE* input;
 FILE* output;

 //Open input and output files
 input = fopen(argv[1], "r");
 output = fopen(argv[2], "w");
  

 //Check input file
 if (input == NULL)
 {
  printf("Input file cannot be read.\n");
  exit(0);
 }
  
 //Check output file
 if (output == NULL)
 {
  printf("Output file cannot be written to.\n");
  exit(0);
 }

 //Key strings
 char *key = malloc(MAX_SIZE);

 //Prompt for key
 printf("Passphrase: ");

 //Read in key
 fgets(key, MAX_SIZE, stdin);

 printf("Encrypting %s\n", argv[1]);

 //strip newlines
 strip_newline(key);

 //XOR data and write it to file
 encrypt_data(input, output, key);
 
 printf("Encrypted data written to %s\n", argv[2]);

 //Release memory
 free(key);

 //Close files
 fclose(input);
 fclose(output);

 return 0;

}


void encrypt_data(FILE* input_file, FILE* output_file, char* key)
{
 int key_count = 0; //Used to restart key if strlen(key) < strlen(encrypt)
 int encrypt_byte;
 
 while( (encrypt_byte = fgetc(input_file)) != EOF) //Loop through each byte of file until EOF
 {
  //XOR the data and write it to a file
  fputc(encrypt_byte ^ key[key_count], output_file);

  //Increment key_count and start over if necessary
  key_count++;
  if(key_count == strlen(key))
   key_count = 0;
 }
}

void strip_newline(char* to_strip)
{
 //remove newlines
 if (to_strip[strlen(to_strip) - 1] == '\n')
 {
  to_strip[strlen(to_strip) - 1] = '\0';
 }
}


To decrypt your data, you simply "encrypt" the encrypted file with the same key.