windows动态链接机制(二)

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处)中的内容已经被加载器修改为正确的符号地址。
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值