2. 动态链接库(dll)
windows动态库(dll)与linux动态库(so)相比,其中2个不同点在于:
(1)linux动态库默认导出所有全局符号,windows动态库必须使用“__declspec(dllexport)”关键字指示导出符号,否则该符号将不被导出(外部不可见)。
(2)linux动态库的导出符号只有“按名字导出”,windows动态库的导出符号有“按名字导出”和“按序号导出”两种方法。
下文介绍windows动态库的“按名字导出”和“按序号导出”这2种导出符号的方法。
2.1 按名字导出
(1)示例代码
(a)Math.c
__declspec(dllexport) double Add(double a, double b)
{
return a+b;
}
__declspec(dllexport) double Sub(double a, double b)
{
return a-b;
}
__declspec(dllexport) double Mul(double a, double b)
{
return a*b;
}
__declspec(dllexport) double Div(double a, double b)
{
return a/b;
}
(b)TestMath.c
#include <stdio.h>
#if 1
__declspec(dllimport) double Mul(double a, double b);
__declspec(dllimport) double Div(double a, double b);
__declspec(dllimport) double Add(double a, double b);
__declspec(dllimport) double Sub(double a, double b);
#endif
int main(int argc, char **argv)
{
double result = 0.0;
result = Add(3.0, 2.0);
result = Sub(3.0, 2.0);
result = Mul(3.0, 2.0);
result = Div(3.0, 2.0);
printf("result = %f\n", result);
return 0;
}
(2)编译方法
cl /c /Za /MDd Math.c
link /DLL /out:Math.dll Math.obj
cl /c /Za /MDd TestMath.c
link TestMath.obj Math.lib
(3)导入导出分析
c使用lordpe工具查看Math.dll的导出表:
使用lordpe工具查看TestMath.exe中Math.dll的导入表:
下面使用一张图来总结运行TestMath.exe时Testmath.exe模块和Math.dll模块在进程地址空间中导入导出表的内容,以及加载器解析符号后的IAT表内容:
可以看到,加载器将TestMath.exe模块中的IAT表中内容解析为了正确的符号地址。
使用OllyDbg进行调试验证,可以看到IAT表(地址:0x4020B0处)中的内容已经被加载器修改为正确的符号地址。
2.2 按序号导出
(1)示例代码
(a)Math.c
double Add(double a, double b)
{
return a+b;
}
double Sub(double a, double b)
{
return a-b;
}
double Mul(double a, double b)
{
return a*b;
}
double Div(double a, double b)
{
return a/b;
}
(b)TestMath.c
#include <stdio.h>
#if 1
__declspec(dllimport) double Mul(double a, double b);
__declspec(dllimport) double Div(double a, double b);
__declspec(dllimport) double Add(double a, double b);
__declspec(dllimport) double Sub(double a, double b);
#endif
int main(int argc, char **argv)
{
double result = 0.0;
result = Add(3.0, 2.0);
result = Sub(3.0, 2.0);
result = Mul(3.0, 2.0);
result = Div(3.0, 2.0);
printf("result = %f\n", result);
return 0;
}
(c)Math.def
LIBRARY Math
EXPORTS
Add @1
Mul @2
Sub @3
Div @5
(2)编译方法
cl /c /Za /MDd Math.c
link /DLL /DEF:Math.def /out:Math.dll Math.obj
cl /c /Za /MDd TestMath.c
link TestMath.obj Math.lib
(3)导入导出分析
使用lordpe工具查看Math.dll的导出表:
使用lordpe工具查看TestMath.exe中Math.dll的导入表:
下面使用一张图来总结运行TestMath.exe时Testmath.exe模块和Math.dll模块在进程地址空间中导入导出表的内容,以及加载器解析符号后的IAT表内容:
可以看到,加载器将TestMath.exe模块中的IAT表中内容解析为了正确的符号地址。
使用OllyDbg进行调试验证,可以看到IAT表(地址:0x4020B0处)中的内容已经被加载器修改为正确的符号地址。