zoukankan      html  css  js  c++  java
  • 动态链接库DLL

    1、Windows应用程序编程接口提供的所有函数都包含在DLL中,三个重要DLL:

    Kernel32.dll:包含的函数用来管理内存、进程和线程;

    User32.dll:包含的函数用来执行与用户界面相关的任务,如创建窗口和发送消息;

    GDI32.dll:包含的函数用来绘制图像和显示文字。

    2、如果编译器看到一个变量、函数或C++类是用_declspec(dllexport)修饰的,那么她就知道应该在生成的DLL模块中导出该变量、函数或C++类。

    3、extern ”C“修饰符用来告诉编译器不要对变量名或函数名进行改编,这样用C、C++或任何编程语言编写的可执行模块都可以访问该变量或函数。

    4、为了让线程能够调用DLL模块中的一个函数,我们必须将DLL的文件映像映射到调用线程所在进程的地址空间中,可以通过两种达到该目的:

    隐式链接:直接让应用程序的源代码引用DLL中所包含的符号,使得加载程序会在应用程序运行的时候隐式地载入(并链接)所需的DLL;

    显示链接:应用程序在运行的过程中,线程调用LoadLibrary(Ex)将DLL载入到进程的地址空间中,并调用GetProcAddress来与想要的输出符号进行链接。

    5、FreeLibrary或FreeLibraryAndExitThread:显式地卸载DLL模块

    6、每个DLL在进程中有一个与之对应的使用计数,LoadLibrary递增该计数,FreeLibrary递减该计数。如果同一个进程的线程再调用LoadLibrary来载入同一个DLL文件映像时,系统不会再次将DLL的文件映像映射到进程的地址空间中,只会将对应的使用计数递增。

    7、GetModuleFileName:获取DLL的全路径,第一个参数为空时,返回应用程序的可执行文件的文件名。

    8、DllMain:DLL的入口点函数,用来执行一些与进程或线程有关的初始化和清理工作。

    9、进程的主线程将调用每个DLL的DllMain函数,并传入DLL_PROCESS_ATTACH值,如果任何一个DLL的DllMain函数返回FALSE,初始化失败,那么系统会把所有的文件映像从地址空间清除,终止整个进程。显式载入DLL时,调用LoadLibrary的线程会调用DLL的DllMain函数,并传入DLL_PROCESS_ATTACH值,若返回FALSE,则撤销对DLL文件映像的映射,并让LoadLibrary返回NULL。

    10、当系统将一个DLL从进程的地址空间中撤销映射,会调用DLL的DllMain函数,并传入DLL_PROCESS_DETACH值。只有当每个DLL都处理完DLL_PROCESS_DETACH通知后,操作系统才会真正的终止进程。

    11、当进程创建一个新线程时,系统会检查所有已经被映射到进程的地址空间的DLL,并用DLL_THREAD_ATTACH来调用每个DLL的DllMain函数。新创建的线程负责执行所有DLL的DllMain函数中的代码,执行相关的初始化。

    12、系统调用ExitThead终止线程时,系统会让该进程用DLL_THREAD_DETACH来调用所有已映射DLL的DllMain函数。

     若调用TerminateProcess终止进程/线程,系统将不会用DLL_PROCESS_DETACH / DLL_THREAD_DETACH来调用DLL的DllMain函数,这意味着已映射到进程地址空间中的任何DLL将没有机会执行任何清理代码,可能导致数据丢失。

    13、DllMain函数只应该执行简单的初始化,避免在DllMain中调用LoadLibrary和FreeLibrary,并且不要在DllMain中调用WaitForSingleObject函数。

    14、DLL重定向:强制操作系统的加载程序首先从应用程序的目录中载入模块。必须将一个文件放到应用程序的目录中,该文件的文件名必须是xxxxx.local,如SuperApp.exe.local。

    15、构建可执行模块时,链接器会将模块的首选基地址设为0x00400000,对于DLL模块,则为0x10000000。

    16、线程局部存储区TLS:将数据与一个正在执行的指定线程关联起来。

    17、应用程序需要跨越进程边界来访问另一个进程的地址空间的情况:

    从另一个进程创建的窗口派生子类窗口;

    辅助调试,例如确定另一个进程正在使用哪些DLL;

    给另一个进程安装挂钩。

    18、用注册表注入DLL:

      首先在HKEY_LOCAL_MACHINESoftwareMicrosoftWindows NTCurrentVersionWindows注册表项下,AppInit_Dlls键值会包含一个DLL文件名或一组DLL的文件名(DLL应该放到Windows的系统目录中,这样不必指定路径)。其次必须创建一个名为LoadAppInit_Dlls,类型为DWORD的注册表项,将其值设为1。

      缺点:

      DLL只会被映射到使用了User32.dll的进程中,所有基于GUI的应用程序都使用了User32.dll;

      DLL会被映射到每个基于GUI的应用程序中,应该将DLL映射到尽可能少的进程中;

      DLL映射到应用程序中后,在应用程序终止前,它将一直存在于进程的地址空间中,应该只在需要时才注入DLL。

    19、使用Windows挂钩注入DLL:

      

  • 相关阅读:
    Unity NGUI 2D场景添加按钮
    EaseType缓动函数
    在没有网络的情况下用安卓手机和数据线让台式电脑上网
    面向对象编程
    static与C#中的static
    C#基础
    iSensor APP 之 摄像头调试 OV5642
    iSensor APP 之 摄像头调试 OV9655
    USB3.0之高速视频传输测试 双目相机(mt9p031、mt9m001)带宽高达300M测试 配合isensor测试 500万像素15fps
    模拟摄像头解码模块最新测试 TVP5150模块 FPGA+SDRAM+TVP5150+VGA 实现PAL AV输入 VGA视频输出
  • 原文地址:https://www.cnblogs.com/yapp/p/11801294.html
Copyright © 2011-2022 走看看