Back home
中文
H7 / SECURITY RESEARCH NOTES

C Dynamic-Link Library Development

References

- http://c.biancheng.net/cpp/u/dll/

Writing a DLL

// filename: main.c
#include <windows.h>
#include <stdio.h>

_declspec(dllexport) int add(int a, int b) {
	return a + b;
}

_declspec(dllexport) int sub(int a, int b) {
	return a - b;
}

BOOL WINAPI DllMain(
     HINSTANCE hinstDLL,  // handle to DLL module
     DWORD fdwReason,     // reason for calling function
     LPVOID lpReserved)  // reserved
{
     // Perform actions based on the reason for calling.
     switch (fdwReason)
     {
     case DLL_PROCESS_ATTACH:
          // Initialize once for each new process.
          // Return FALSE to fail DLL load.
          printf("dll is loaded!\n");
          break;

     case DLL_THREAD_ATTACH:
          // Do thread-specific initialization.
          break;

     case DLL_THREAD_DETACH:
          // Do thread-specific cleanup.
          break;

     case DLL_PROCESS_DETACH:
          // Perform any necessary cleanup.
          break;
     }
     return TRUE;  // Successful DLL_PROCESS_ATTACH.
}

// 注意:工程名为dllDemo,所以编译后会生成dllDemo.dll和dllDemo.lib两个文件(这两个文件很重要)

Explicit Loading

// 什么是显式加载?
// 显式加载又叫运行时加载,指主程序在运行过程中需要DLL中的函数时再加载。显式加载是将较大的程序分开加载的,程序运行时只需要将主程序载入内存,软件打开速度快,用户体验好。

// filename:main.c
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>  

typedef int (*FUNADDR)(int, int);  

int main() {
     int a = 10, b = 5, x;

     HINSTANCE dllDemo = LoadLibrary(L"E:\\CProjects\\DllPractice\\x64\\Debug\\DllPractice.dll");
     FUNADDR add, sub;

     if (dllDemo) {
          add = (FUNADDR)GetProcAddress(dllDemo, "add");
          sub = (FUNADDR)GetProcAddress(dllDemo, "sub");
     }
     else {
          x = GetLastError();
          printf("error code: %d\n", x);
          exit(1);
     }
     printf("a+b=%d\n", add(a, b));
     printf("a-b=%d\n", sub(a, b));
     return 0;
}

// 注意:编译时不需要dllDemo.lib文件,直接独立编译。

Implicit Loading

// 什么是隐式加载?
// 隐式加载又叫载入时加载,指在主程序载入内存时搜索DLL,并将DLL载入内存。隐式加载也会有静态链接库的问题,如果程序稍大,加载时间就会过长,用户不能接受。

// filename: main.c
#include <stdio.h>
#include "dllDemo.h"

int main(void) {
	int a = 10, b = 5;
	printf("a + b = %d\n", add(a, b));

	return 0;
}

// dllDemo.h
#ifndef _DLLDEMO_H
#define _DLLDEMO_H

#pragma comment(lib, "dllDemo.lib")
_declspec(dllexport) int add(int, int);

#endif

// 注意:编译的时候需要dllDemo.lib文件放在一起进行编译。