手动修复输入表时的发现---对于IID输入表和IAT和INT对应关系及程序载入DLL

来源:互联网 发布:淘宝联盟微信推广 编辑:程序博客网 时间:2024/06/06 02:14

IMAGE_IMPORT_DESCRIPTOR struct
     union {
        DWORD OriginalFirstThunk;               4Byte
     };
     TimeDateStamp         DWORD     ;04h           4Byte
     ForwarderChain        DWORD     ;08h           4Byte
     Name                  DWORD     ;0Ch;          4Byte
     FirstThunk            DWORD     ;10h;          4Byte
IMAGE_IMPORT_DESCRIPTOR ends

以上是输入表结构,5个部分,由这5个部分引出导入地址表(IAT)和导入名称表(INT)。。。。

首先明白函数名和DLL名的在程序中的排列:

WORD   String 
HINT号 函数名
……
……
模块名1
HINT号 函数名
……
……
模块名2
……
//---------------------------------------------------------------------------

     也就是说2个字节代表HINT号,后面紧跟的就是函数名,函数名以0x00结尾。在所有函数都罗列完毕后,紧跟的就是这些函数所在的模块名。然后又是函数名,又是模块名……

 

 

第一个IID成员:OriginalFirstThunk,是一个RVA,以例子形式表现,假如OriginalFirstThunk存放的是地址1111,我去地址1111处看一下是什么;

地址1111:地址2222,也就是说在地址1111里面放的是地址2222,那再去地址2222里面看看放的是什么;

地址2222:0001 GetModuleHandleA,也就是说地址2222中放和是Hint和函数名称字符串,这个Hint是指函数在某DLL中和次序;值得说明的是这个函数是某个DLL中导入本程序的第一个函数,其他是**** 函数名2  。。。。一直到DLL名字字符串结束,这时从这个DLL中导入程序的函数就完全了;     其他DLL的函数导入也是这样。

 

第二个IID成员和第三个IID成员一般用不上,为00000000(DWORD)。

 

第四个IID成员:Name,是一个RVA,Name中存放的是地址3333,那去看一下地址3333中存放的内容,

地址3333:kernel32.DLL,显然是一个DLL名字符串,,和第一个成员解释中对应

 

第五个IID成员:FirstThunk ,是一个RVA,FirstThunk 中存放的是地址有两种情况,1111(和OriginalFirstThunk中相同)或者4444,出现第一种情况是标准程序中见到的,这是Windows导入函数的一种方式,出现第二种情况是在脱壳程序中看到,我讨论4444这种情况,看一下地址4444中的内容,

地址4444:BD 2F 81 7C,倒过来看就是一个函数地址。。。这是另一种导入库函数的方式,当第一种方式失效时就用第二种方式。

 

 

切入正题。。。。。。。。。。。

 手动修复输入表时,我把得到 的API地址单独放置在6E50处,这些API地址有在kernel32.DLL中的,还有Shell32.DLL中的,有user32.DLL等各种不确定DLL中的,反正不是 一个DLL中的,都说在IAT中不同的DLL中的函数地址要放在一起,问题是这种说法对吗?我得到的结论是否定这种说法。。。

只要DLL中有一个函数导入了,DLL中其他函数地址也能被程序找到就OK了,正是如此的!

手动修复过程中遇到初始化失败问题,最后出现了,一个是IAT地址和大小没有写,另一个是OriginalFirstThunk中的值写的不对,假如OriginalFirstThunk中的值是地址5555,那么地址5555处的数据是地址6666,那么地址6666处的数据一定要是0才行,如果不是0会有两种错误出现:

第一种,6666没有超过程序的最大偏移,并且地址6666里的数据为该DLL中的一个函数名比如user32中的MessageBoxA(相应6666处为 00 00(不能少了序号) MessageBoxA),不会提示错误,

第二种,如果地址6666处是另一个DLL中的函数名或者其他数据,会显示如下错误

第三种,如果地址5555(OriginalFirstThunk)处的数据不是6666,而是一个很大的地址,比如00900000,900000这个地址超过程序的范围了,会出现如下错误

 

 

结论,总共两点:

第一点,OriginalFirstThunk的内容问题

第二点,DLL导入和API调用问题

 

原创粉丝点击