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:

      

  • 相关阅读:
    随机森林算法参数调优
    BAYES和朴素BAYES
    阿里云 金融接口 token PHP
    PHP mysql 按时间分组 表格table 跨度 rowspan
    MySql按周,按月,按日分组统计数据
    PHP 获取今日、昨日、本周、上周、本月的等等常用的起始时间戳和结束时间戳的时间处理类
    thinkphp5 tp5 会话控制 session 登录 退出 检查检验登录 判断是否应该跳转到上次url
    微信 模板消息
    php 腾讯 地图 api 计算 坐标 两点 距离 微信 网页 WebService API
    php添加http头禁止浏览器缓存
  • 原文地址:https://www.cnblogs.com/yapp/p/11801294.html
Copyright © 2011-2022 走看看