我们都知道PE文件包含一个引入函数表,我们可以通过遍历IMPORT_THUNK_DATA找到引入函数名称或者序号。但是当PE文件被装载到内存中一后,似乎就不是这样了,这时候IMAGE_THUNK_DATA似乎是一条汇编的JMP指令和函数代码的地址。另外在PE磁盘文件中的代码块里,初始化变量数据块后面有一块数据全都是汇编的JMP指令,我想问的问题是:
1、PE文件被装载到内存的时候,装载器对引入函数是经过了怎样的处理,这个过程是怎样的?
2、上面提到的代码块中的JMP指令块的作用是什么?

解决方案 »

  1.   

    我也不知道,但我觉得应该是一样的,否则那些APIHook怎么工作的?
      

  2.   

    对于每个导入的dll,PE有两个IMAGE_THUNK_DATA 结构数组,每个IMAGE_THUNK_DATA 是指向一个IMAGE_IMPORT_BY_NAME 结构的RVA,IMAGE_IMPORT_BY_NAME 结构包含指向导入函数名的RVA。PE文件被装载时,PE Loader根据导入函数名和dll名,从dll的导出表中算出导入函数的实际地址,其中一个IMAGE_THUNK_DATA 结构数组将放置导入函数的实际地址。
    IMAGE_THUNK_DATA应该是4字节的吧。JMP指令要5字节?
      

  3.   

    TO  paul2002:
    你说的没错,呵呵,不过装载器修改的不是IMAGE_THUNK_DATA.
    难道没人能帮我解决问题吗?
      

  4.   

    http://61.153.195.10:8080/list.asp?part1=1
    这里面有个PE文件的格式,不知道对你有没有用。
      

  5.   

    改动的应该是IMAGE_THUNK_DATA吧,你上面说的情况就像这样:
    //IMPORTFUN();
    //ASSEMBLE CODE
    CALL 0x004XXXXX

    0x004XXXXX:
    JMP       DWORD PTR [0x004YYYYY]
    这是由于你客户隐式链接的时候头文件中没有明确提示导入函数(没有__declspec(dllimport)修饰)。这里YYYYY应该是FirstThunk的RVA,而FirstThunk指向一个IMAGE_THUNK_DATA(4字节union)结构数组(就是IAT),这个数组的成员在PE文件被装载时将放置导入函数的实际线性地址。
      

  6.   

    To paul2002:
    多谢捧场哈,:)
    装载器修改的是IMAGE_THUNK_DATA指向的IMAGE_IMPORT_BY_NAME,FirstThunk是指向IMAGE_THUNK_DATA的指针,也就是说:
          *FirstThunk=IMAGE_THUN_DATA=&IMAGE_IMPORT_BY_NAME
    呵呵,你可以去验证一下。
    不过我的问题是,装载器是怎么完成这个修改过程的。呵呵,走题了哈
      

  7.   

    "装载器修改的是IMAGE_THUNK_DATA指向的IMAGE_IMPORT_BY_NAME"?
    really?
      

  8.   

    装载进入内存中以后,好像找的是mzheader,....sectiontable,
    3个区的表,那里分别存放有下一个区的详细信息。