zoukankan      html  css  js  c++  java
  • 简述装载过程。

    1.创建PDE,page directory entry,用来存放virtual memory <--> physical memory之间的映射关系

    2.创建virtual memory跟可执行文件(.exe,.dll...)之间的映射关系,缺页的时候需要从文件里那数据放到内存里的

    3.对CPU的PC寄存器设置为可执行文件入口地址

    这样就ok了,后续用到什么memory,MMU会分配/释放相应的物理内存,并填写PTE(page directory entry).

    装载过程中一个重要的步骤是配置IAT(Import Address Table).

    PE文件Optional Header中有两个Directory Entry特别重要,IMAGE_DIRECTORY_ENTRY_EXPORT,IMAGE_DIRECTORY_ENTRY_IMPORT.

    /************************* To get the exported API's RVA *******************************/

    对于Export Entry,它提供了这个module想要export的API的RVA,我们可能希望知道怎么去拿到这些API对应的RVA.
    1. Get RVA of IMAGE_DIRECTORY_ENTRY_EXPORT from optional header

    1 struct data_directory
    2  { 
    3     long VirtualAddress;
    4     long Size;
    5  }

    2. Parse the Export based on this structure

     1 struct IMAGE_EXPORT_DIRECTORY {
     2     DWORD Characteristics;
     3     DWORD TimeDateStamp;
     4     WORD MajorVersion;
     5     WORD MinorVersion;
     6     DWORD Name;
     7     DWORD Base;
     8     DWORD NumberOfFunctions;
     9     DWORD NumberOfNames;
    10     DWORD *AddressOfFunctions;
    11     DWORD *AddressOfNames;
    12     DWORD *AddressOfNameOrdinals;
    13 }

    3. Get NumberOfNames, AddressOfNames, AddressOfNameOrdinals, AddressOfFunctions
    compare function "xxxx" with *AddressOfNames, to get its index(hint).
    Based on the index(hint) to get its ordinals (AddressOfNameOrdinals[hint])

    based on the ordinals to get the function's address(AddressOfFunctions[ordinals]).

    /********************************************************/
    对于 Import Entry,我们可能会想知道怎么去拿到Imported API的地址。
    1. Get RVA of IMAGE_DIRECTORY_ENTRY_IMPORT from optional header

    1 struct data_directory
    2  { 
    3     long VirtualAddress;
    4     long Size;
    5  }

    2. Parse the import array structure, it is an array ended by an Zero-Entry

    1 struct IMAGE_IMPORT_DESCRIPTOR {
    2     DWORD *OriginalFirstThunk;
    3     DWORD TimeDateStamp;
    4     DWORD ForwarderChain;
    5     DWORD Name; // module name
    6     DWORD *FirstThunk;
    7 }

    每个结构都会对应一个library,compare if name is the module we want.

    3. 得到我们想了解的library对应的内容之后,有两个结构的内容特别重要*OriginalFirstThunk,*FirstThunk。

    在loader填IAT之前,OriginalFirstThunk跟FirstThunk的内容是一样的,都是一个array ended by an Zero-Element.

    每个值都对应一个结构体

    1 struct IMAGE_IMPORT_BY_NAME {
    2         short Hint;
    3         char Name[1];
    4 }

    name是函数的名字,hint是这个name在library的Export Entry中很有可能的hint值,用来优化加载时间.如果hint对应的api name跟我们想要的不一样,那么就需要二分遍历它的name array。

    4. Loader根据Name,Hint去对应的Library中可以拿到这个API相应的address.

        Loader会把这个address填写到FirstThunk指向的那个数组,于是,从此之后FirstThunk的内容就跟OriginalFirstThunk不一样了

    5.  以后这个Module想要call相应的API的时候,就是个相对寻址, call ptr [FirstThunk]。

        所以FirstThunk指向的数组最终保存了import API的virtual address. 

    如果想要做个hook在Module访问其他module的API时,只要在loader之后修改FirstThunk中的数据就能达到目的了:)

  • 相关阅读:
    2020-01月-02月
    Work needing Technologies
    gcc和 gdb工具(转)
    pyenv and grunt-contrib-testem
    Statistics Books
    HTML5学习--SVG全攻略(基础篇)
    一个完整的学院网站实现过程
    JavaScript 常用单词整理
    一张图教会CSS3倒影
    Python大数据处理案例
  • 原文地址:https://www.cnblogs.com/zzSoftware/p/3414614.html
Copyright © 2011-2022 走看看