使用.def文件導出DLL的好處是可以隱藏函數名,提高安全性。
首先新建DLL工程,編寫函數,因爲使用def導出,所以編寫函數聲明和定義和普通exe的編寫方式一樣。
MyDll.h
// MyDll.h: interface for the MyDll class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_MYDLL_H__A5062BAC_C3AD_45FE_8909_494D8EBE125E__INCLUDED_)
#define AFX_MYDLL_H__A5062BAC_C3AD_45FE_8909_494D8EBE125E__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
int Max(int x, int y);
int Min(int x, int y);
int Add(int x, int y);
int Sub(int x, int y);
#endif // !defined(AFX_MYDLL_H__A5062BAC_C3AD_45FE_8909_494D8EBE125E__INCLUDED_)
MyDll.cpp
#include "stdafx.h"
#include "MyDll.h"
int Max(int x, int y)
{
return x > y ? x : y;
}
int Min(int x, int y)
{
return x < y ? x : y;
}
int Add(int x, int y)
{
return x + y;
}
int Sub(int x, int y)
{
return x - y;
}
然後添加一個 test.def 文件到項目中(如果VC6打開文件或添加文件崩潰,請安裝FileTool.dll 補丁)
編寫如下內容
EXPORTS
Max @12
Min @15 NONAME
Add @13
Sub @16
說明:@後面的數字是函數導出序號,在DLL的導出表裏有一個 AddressOfNameOrdinals 地址表,裏面存的值加上導出表裏的Base就是這裏的導出序號了。
編譯生成的DLL拿到 dependency walker 裏,可以看到如下結果:
註明了 NONAME 的 Min 函數,其函數名已經隱藏起來了。
另一個關鍵點是,我們在 def 中指定的導出序號是不連續的,windows 計算導出函數總數是用最大序號 - 最小序號 +1,因此得到了 16 - 12 + 1 = 5 個函數,其中序號14是不存在的,所以它的入口點是NULL。