逆向基础学习 C++编写dll文件 编写导出函数

ゝ一世哀愁。 2022-03-20 03:22 820阅读 0赞

一、创建DLL文件

利用VS2017新建dll项目,得到三个cpp文件

其中dll1.cpp定义dll文件的导出函数

20190210122621968.png

核心入口函数:dllmain.cpp

  1. // dllmain.cpp : 定义 DLL 应用程序的入口点。
  2. #include "stdafx.h"
  3. //核心入口函数 DLL文件 动态链接库入口函数
  4. BOOL APIENTRY DllMain( HMODULE hModule,
  5. //DLL模块的句柄
  6. DWORD ul_reason_for_call,
  7. //DLLMain函数被调用的原因
  8. LPVOID lpReserved
  9. //保留项,也就是Windows的保留参数。
  10. //保留参数:不是不使用的参数,而是Windows不想让我们指导作用的参数
  11. )
  12. {
  13. switch (ul_reason_for_call)
  14. {
  15. case DLL_PROCESS_ATTACH:
  16. //当DLL被进程加载时DLLMain被调用
  17. case DLL_THREAD_ATTACH:
  18. //有线程被创建时DLLMain被调用
  19. case DLL_THREAD_DETACH:
  20. //有线程结束时DLLMain被调用
  21. case DLL_PROCESS_DETACH:
  22. //当DLL被进程卸载时DLLMain被调用
  23. break;
  24. }
  25. return TRUE;
  26. }

因为DLLMain函数不止一次的被调用,每次调用可能执行不同的代码,比如进程加载dll时,可能在DLL中要申请一些资源,在进程卸载DLL时,DLL则要释放自己申请的资源。

例1:

  1. // dllmain.cpp : 定义 DLL 应用程序的入口点。
  2. #include "stdafx.h"
  3. VOID aaa(){
  4. }
  5. VOID over(){
  6. }
  7. //核心入口函数 DLL文件 动态链接库入口函数
  8. BOOL APIENTRY DllMain( HMODULE hModule,
  9. //DLL模块的句柄
  10. DWORD ul_reason_for_call,
  11. //DLLMain函数被调用的原因
  12. LPVOID lpReserved
  13. //保留项,也就是Windows的保留参数。
  14. //保留参数:不是不使用的参数,而是Windows不想让我们指导作用的参数
  15. )
  16. {
  17. switch (ul_reason_for_call)
  18. {
  19. case DLL_PROCESS_ATTACH:
  20. //当DLL被进程加载时DLLMain被调用
  21. aaa();
  22. case DLL_THREAD_ATTACH:
  23. //有线程被创建时DLLMain被调用
  24. case DLL_THREAD_DETACH:
  25. //有线程结束时DLLMain被调用
  26. case DLL_PROCESS_DETACH:
  27. //当DLL被进程卸载时DLLMain被调用
  28. over();
  29. break;
  30. }
  31. return TRUE;
  32. }

二、导出函数的编写

导出:提供给外界调用

一、extern “C”

  1. //声明导出函数->把这个ccc函数导出去
  2. extern "C" __declspec(dllexport) void ccc();
  3. //用作导出的函数
  4. void ccc() {
  5. }

在dllmain.cpp里加上以上代码,声明ccc()为导出函数

生成之后dll文件夹里会出现以下文件:

20190210140717577.png

extern “C”的主要作用就是为了能够正确实现C++代码调用其他C语言代码,加上extern “C”后,会指示编译器这部分代码按C语言的进行编译,而不是C++。由于C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名,而C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般只包括函数名。

为了更好的支持原来的C代码和已经写好的C语言库,需要在C++中尽可能的支持C,而extern “C”就是其中一个策略。就是防止编译后的函数名被编译器修改或者粉碎。

所以extern “C”主要用在以下的情况:

  1. C++代码调用C语言代码
  2. 在C++的头文件中使用

二、 __declspec(dllexport)

声明导出函数,将该函数从本DLL开放提供给其他应用程序组使用

Dllexport、Dllimport参考https://docs.microsoft.com/zh-cn/cpp/cpp/dllexport-dllimport?view=vs-2017

__declspec参考https://docs.microsoft.com/zh-cn/cpp/cpp/declspec?view=vs-2017

用于指定存储类信息使用的扩展的特性语法 __declspec关键字,这指定给定类型的实例是与下面列出特定于 Microsoft 的存储类特性一起存储。Dllexportdllimport存储类特性是 C 和 c + + 语言的 Microsoft 专用扩展。 可以使用它们从 DLL 中导出或向其中导入函数、数据和对象。

发表评论

表情:
评论列表 (有 0 条评论,820人围观)

还没有评论,来说两句吧...

相关阅读

    相关 dll 导出函数

    今天在帮同事弄DLL导出的函数的时候,发现一个问题,因为他之前的函数有重载,我原计划希望他原来所有的函数都不动, 而重载的函数都新建一个函数代替使用到,这样既保持了向下兼容向

    相关 编写可变参数c函数

    前言:本文在很大程度上改编自网友kevintz的“C语言中可变参数的用法”一文,在行文之前先向这位前辈表示真诚的敬意和感谢。 一、什么是可变参数 我们在C语言编程中有时会遇

    相关 摘: VS2010 C++ 调用 DLLC++编写

    一、为什么需要dll 代码复用是提高软件开发效率的重要途径。一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用。 比较常见的例子是