【转】IAT 解析

关键:

 

typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
DWORD Characteristics;
DWORD OriginalFirstThunk;// 指向一个 IMAGE_THUNK_DATA 结构数组的RVA
}
DWORD TimeDateStamp;// 文件生成的时间
DWORD ForwarderChain;// 这个数据一般为0,可以不关心
DWORD Name1;  // RVA,指向DLL名字的指针,ASCII字符串
DWORD FirstThunk; //指向一个 IMAGE_THUNK_DATA 结构数组的RVA,这个数据与IAT所指向的地址一致
}IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR
IMAGE_THUNK_DATA 这是一个DWORD类型的集合。通常我们将其解释为指向一个 IMAGE_IMPORT_BY_NAME 结构的指针,其定义如下:
IMAGE_THUNK_DATA{
union {
PBYTE ForwarderString;
PDWORD Function;
DWORD Ordinal;//判定当前结构数据是不是以序号为输出的,如果是的话该值为0x800000000,此时PIMAGE_IMPORT_BY_NAME不可做为名称使用
PIMAGE_IMPORT_BY_NAME AddressOfData;
}u1;
} IMAGE_THUNK_DATA,*PIMAGE_THUNK_DATA;

typedef struct _IMAGE_IMPORT_BY_NAME{
WORD Hint;// 函数输出序号
BYTE Name1[1];//输出函数名称
} IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME



现在我们知道如何找到引入表了。Data Directory数组第二项的VirtualAddress包含引入表地址。引入表实际上是一个 IMAGE_IMPORT_DESCRIPTOR 结构数组。每个结构包含PE文件引入函数的一个相关DLL的信息。比如,如果该PE文件从10个不同的DLL中引入函数,那么这个数组就有10个成员。该数组以一个全0的成员结尾。下面详细研究结构组成:

IMAGE_IMPORT_DESCRIPTOR STRUCT 
union 
    Characteristics dd ? 
    OriginalFirstThunk dd ? 
ends 
TimeDateStamp dd ? 
ForwarderChain dd ? 
Name1 dd ? 
FirstThunk dd ? 
IMAGE_IMPORT_DESCRIPTOR ENDS

    结构第一项是一个union子结构。事实上,这个union子结构只是给 OriginalFirstThunk 增添了个别名,您也可以称其为"Characteristics"。 该成员项是指向一个指向一个DWORD 数组的RVA。数组里的每一个DWORD 事实上是一个IMAGE_THUNK_DATA union。那么,什么 IMAGE_THUNK_DATA又是什么呢? 每个IMAGE_THUNK_DATA union对应于一个输入函数,这个DWORD(即IMAGE_THUNK_DATA union)的内容视文件被加载与否(即:加载前后内容不同,原因后面会解释),以及函数被以名称输入或以序号输入而定(即:输入方式不同,内容不同)。以名称输入是比较共同的方式。当一个函数以序号输入,EXE 文件的IMAGE_THUNK_DATA DWORD 中的最高位(0x80000000)设立。例如,考虑一个IMAGE_THUNK_DATA,其值为0x80000112,放在GDI32.DLL 数组中。表示这IMAGE_THUNK_DATA 将输入GDI32.DLL 中的第112号输出(exported)函数。如果函数以名称输入,IMAGE_THUNK_DATA DWORD 就内含一个RVA(Relative Virtual Address),指向IMAGE_IMPORT_BY_NAME 结构,由于一个输入函数对应一个IMAGE_THUNK_DATA union,而当函数以名称输入的时候IMAGE_THUNK_DATA又指向一个IMAGE_IMPORT_BY_NAME 结构,所以此时一个输入函数对应一个IMAGE_IMPORT_BY_NAME 结构。现在让我们看看IMAGE_IMPORT_BY_NAME 结构里面有些什么东东,我们希望里面存有一个引入函数的相关信息。奥,原来它真的如我们所愿:

IMAGE_IMPORT_BY_NAME STRUCT 
Hint dw ? 
Name1 db ? 
IMAGE_IMPORT_BY_NAME ENDS

    Hint 指示本函数在其所驻留DLL的引出表中的索引号。该域被PE装载器用来在DLL的引出表里快速查询函数。 
Name1 含有引入函数的函数名。函数名是一个ASCIIZ字符串。现在请看这里: 假设程序中调用了N个输入函数,那么就对应着有N个 IMAGE_IMPORT_BY_NAME 结构,我们收集起这些结构的RVA 放在IMAGE_THUNK_DATA结构中组成一个数组,并以0结尾,然后再将此数组的RVA放入 OriginalFirstThunk。 这样一来我们就可以利用OriginalFirstThunk这条线把从某一个DLL中调用的函数全部給揪出来。

    奥,刚才我们被IMAGE_IMPORT_BY_NAME 结构给中断了一下,现在让我们返回IMAGE_IMPORT_DESCRIPTOR结构,继续看里面的其他域。为了和上面的讨论保持连贯性先让我们来看一下最后一个域FirstThunk,FirstThunk 与 OriginalFirstThunk 非常相似,也是一个RVA,它也是指向一个 IMAGE_THUNK_DATA 结构数组(当然这是另外一个IMAGE_THUNK_DATA 结构数组,不过这个IMAGE_THUNK_DATA结构数组和OriginalFirstThunk指向的IMAGE_THUNK_DATA结构数组内容是完全一样的)。好的让我们理顺一下:现在有几个 IMAGE_IMPORT_BY_NAME 结构,同时您又创建了两个结构数组,并同样存入指向那些 IMAGE_IMPORT_BY_NAME 结构的RVA,这样两个数组就包含相同数值了(可谓相当精确的复制啊)。最后您决定将第一个数组的RVA赋给 OriginalFirstThunk,第二个数组的RVA赋给 FirstThunk,这样一切都很清楚了。如果你对上面一堆的RVA和结构数组的关系感到头晕的话那么请往下看,或许下面这个图解能让你清醒一些:

OriginalFirstThunk                                        IMAGE_IMPORT_BY_NAME                                                      FirstThunk

 

IMAGE_THUNK_DATA           --->                          Function 1                             <---                               IMAGE_THUNK_DATA

IMAGE_THUNK_DATA           --->                          Function 2                             <---                               MAGE_THUNK_DATA

IMAGE_THUNK_DATA           --->                          Function 3                             <---                               IMAGE_THUNK_DATA

IMAGE_THUNK_DATA           --->                          Function 4                             <---                               IMAGE_THUNK_DATA

...                                                                            ...                                                                                 ...

IMAGE_THUNK_DATA           --->                          Function n                            <---                                IMAGE_THUNK_DATA

 

   现在您应该明白我的意思。不要被IMAGE_THUNK_DATA这个名字弄糊涂: 当以名字引入函数时,它仅是指向 IMAGE_IMPORT_BY_NAME 结构的RVA。 如果将 IMAGE_THUNK_DATA 字眼想象成RVA,就更容易明白了。OriginalFirstThunk 和 FirstThunk 所指向的这两个数组大小取决于PE文件从DLL中引入函数的数目。比如,如果PE文件从kernel32.dll中引入10个函数,那么IMAGE_IMPORT_DESCRIPTOR 结构的 Name1域包含指向字符串"kernel32.dll"的RVA,同时每个IMAGE_THUNK_DATA 数组有10个元素。


附WS2_32.dll函数导出表:

(该dll特殊,当exe导入时,不会导入函数名,而是函数序号,即

当一个函数以序号输入,EXE 文件的IMAGE_THUNK_DATA DWORD 中的最高位(0x80000000)设立。”

注意ordinal是序号)


File Type: DLL

 

  Section contains the following exports for WS2_32.dll

 

    00000000 characteristics

    4CE78957 time date stamp Sat Nov 20 16:39:51 2010

        0.00 version

           1 ordinal base

         500 number of functions

         167 number of names

 

    ordinal hint RVA      name

 

         25    0 0000E14D FreeAddrInfoEx

         26    1 0000E14D FreeAddrInfoExW

         27    2 00004B1B FreeAddrInfoW

         28    3 0001469B GetAddrInfoExA

         29    4 0000D1EA GetAddrInfoExW

         30    5 00004889 GetAddrInfoW

         31    6 000066AF GetNameInfoW

         32    7 00013ABF InetNtopW

         33    8 000139DC InetPtonW

         34    9 000145F7 SetAddrInfoExA

         35    A 0000F4F6 SetAddrInfoExW

        500    B 0001E764 WEP

         36    C 0001E39B WPUCompleteOverlappedRequest

         37    D 000068D6 WSAAccept

         38    E 0000331E WSAAddressToStringA

         39    F 00006CF6 WSAAddressToStringW

         40   10 00020509 WSAAdvertiseProvider

        102   11 0001736B WSAAsyncGetHostByAddr

        103   12 0001726A WSAAsyncGetHostByName

        105   13 0001744E WSAAsyncGetProtoByName

        104   14 0001754F WSAAsyncGetProtoByNumber

        107   15 000170A7 WSAAsyncGetServByName

        106   16 000171AE WSAAsyncGetServByPort

        101   17 0001B014 WSAAsyncSelect

        108   18 00017602 WSACancelAsyncRequest

        113   19 00015343 WSACancelBlockingCall

        116   1A 00003C5F WSACleanup

         41   1B 0000651F WSACloseEvent

         42   1C 0000CC3F WSAConnect

         43   1D 0001BFDD WSAConnectByList

         44   1E 0001C8B6 WSAConnectByNameA

         45   1F 0001C52F WSAConnectByNameW

         46   20 000064FB WSACreateEvent

         47   21 000161B6 WSADuplicateSocketA

         48   22 00016128 WSADuplicateSocketW

         49   23 00019FC1 WSAEnumNameSpaceProvidersA

         50   24 0001A021 WSAEnumNameSpaceProvidersExA

         58   25 0001A081 WSAEnumNameSpaceProvidersExW

         59   26 0000D8D3 WSAEnumNameSpaceProvidersW

         60   27 000031B1 WSAEnumNetworkEvents

         61   28 0001627F WSAEnumProtocolsA

         62   29 0000C8E1 WSAEnumProtocolsW

         63   2A 0000648F WSAEventSelect

        111   2B 000037AD WSAGetLastError

         64   2C 00007489 WSAGetOverlappedResult

         65   2D 00019B68 WSAGetQOSByName

         66   2E 0001AA00 WSAGetServiceClassInfoA

         67   2F 0001A849 WSAGetServiceClassInfoW

         68   30 0001A44D WSAGetServiceClassNameByClassIdA

         69   31 0001A651 WSAGetServiceClassNameByClassIdW

         70   32 00013B24 WSAHtonl

         71   33 00013C11 WSAHtons

         72   34 0001A981 WSAInstallServiceClassA

         73   35 0001A277 WSAInstallServiceClassW

         74   36 00002FE7 WSAIoctl

        114   37 000153BE WSAIsBlocking

         75   38 0001CA7D WSAJoinLeaf

         76   39 0000A642 WSALookupServiceBeginA

         77   3A 0000575A WSALookupServiceBeginW

         78   3B 00005239 WSALookupServiceEnd

         79   3C 0000A27B WSALookupServiceNextA

         80   3D 00004CBC WSALookupServiceNextW

         81   3E 0000EF85 WSANSPIoctl

         82   3F 00013B24 WSANtohl

         83   40 00013C11 WSANtohs

         84   41 0001B0A5 WSAPoll

         85   42 00020B79 WSAProviderCompleteAsyncCall

         86   43 0000C22E WSAProviderConfigChange

         87   44 00007089 WSARecv

         88   45 00019DBD WSARecvDisconnect

         89   46 0000CBA6 WSARecvFrom

         90   47 0001A362 WSARemoveServiceClass

         91   48 0000CDC3 WSAResetEvent

         92   49 00004406 WSASend

         93   4A 0001B281 WSASendDisconnect

         94   4B 0001B3CB WSASendMsg

         95   4C 0001B30C WSASendTo

        109   4D 0001543D WSASetBlockingHook

         96   4E 0000CDD4 WSASetEvent

        112   4F 000037D9 WSASetLastError

         97   50 0001AA92 WSASetServiceA

         98   51 0000F606 WSASetServiceW

         99   52 0000C82A WSASocketA

        100   53 00003CD3 WSASocketW

        115   54 00003AB2 WSAStartup

        117   55 0000ED31 WSAStringToAddressA

        118   56 00006DDD WSAStringToAddressW

        119   57 00020643 WSAUnadvertiseProvider

        110   58 000154C1 WSAUnhookBlockingHook

        120   59 0000650E WSAWaitForMultipleEvents

         24   5A 0001E546 WSApSetPostRoutine

        121   5B 0001D775 WSCDeinstallProvider

        122   5C 000193AC WSCEnableNSProvider

        123   5D 0000B8CF WSCEnumProtocols

        124   5E 0001DF81 WSCGetApplicationCategory

        125   5F 0001D961 WSCGetProviderInfo

        126   60 0000C64E WSCGetProviderPath

        127   61 000196A9 WSCInstallNameSpace

        128   62 00019859 WSCInstallNameSpaceEx

        129   63 0001D751 WSCInstallProvider

        130   64 00018793 WSCInstallProviderAndChains

        131   65 0001DB99 WSCSetApplicationCategory

        132   66 0001D1D1 WSCSetProviderInfo

        133   67 00019A11 WSCUnInstallNameSpace

        134   68 0001CE2D WSCUpdateProvider

        135   69 00019571 WSCWriteNameSpaceOrder

        136   6A 0001D099 WSCWriteProviderOrder

        137   6B 0000AA67 WahCloseApcHelper

        138   6C 0002272D WahCloseHandleHelper

        139   6D 00023261 WahCloseNotificationHandleHelper

        140   6E 00022772 WahCloseSocketHandle

        141   6F 000032C4 WahCloseThread

        142   70 000227C1 WahCompleteRequest

        143   71 00007E65 WahCreateHandleContextTable

        144   72 0000C3CB WahCreateNotificationHandle

        145   73 00023080 WahCreateSocketHandle

        146   74 0000F268 WahDestroyHandleContextTable

        147   75 000229FD WahDisableNonIFSHandleSupport

        148   76 0002284F WahEnableNonIFSHandleSupport

        149   77 0000AA97 WahEnumerateHandleContexts

        150   78 0000412B WahInsertHandleContext

        152   79 000232C3 WahNotifyAllProcesses

        153   7A 00008483 WahOpenApcHelper

        154   7B 000036A7 WahOpenCurrentThread

        155   7C 00022CB2 WahOpenHandleHelper

        156   7D 0000C1FA WahOpenNotificationHandleHelper

        157   7E 00022096 WahQueueUserApc

        158   7F 00002F20 WahReferenceContextByHandle

        159   80 000039B0 WahRemoveHandleContext

        160   81 0000C2F0 WahWaitForNotification

        161   82 00023665 WahWriteLSPEvent

        151   83 00006A8A __WSAFDIsSet

          1   84 000068B6 accept

          2   85 00004582 bind

          3   86 00003918 closesocket

          4   87 00006BDD connect

        162   88 00004B1B freeaddrinfo

        163   89 00004296 getaddrinfo

         51   8A 00016C01 gethostbyaddr

         52   8B 00017673 gethostbyname

         57   8C 0000A05B gethostname

        164   8D 000067B7 getnameinfo

          5   8E 00007147 getpeername

         53   8F 000168B3 getprotobyname

         54   90 000167C4 getprotobynumber

         55   91 00016EF3 getservbyname

         56   92 00016D62 getservbyport

          6   93 000030AF getsockname

          7   94 0000737D getsockopt

          8   95 00002D57 htonl

          9   96 00002D8B htons

         11   97 0000311B inet_addr

         12   98 0000B131 inet_ntoa

        165   99 00013A5A inet_ntop

        166   9A 00013969 inet_pton

         10   9B 00003084 ioctlsocket

         13   9C 0000B001 listen

         14   9D 00002D57 ntohl

         15   9E 00002D8B ntohs

         16   9F 00006B0E recv

         17   A0 0000B6DC recvfrom

         18   A1 00006989 select

         19   A2 00006F01 send

         20   A3 000034B5 sendto

         21   A4 000041B6 setsockopt

         22   A5 0000449D shutdown

         23   A6 00003EB8 socket

 

  Summary

 

        1000 .data

        2000 .reloc

        B000 .rsrc

       26000 .text

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值