windows PE Image 文件分析(3)--- .idata 节与 import table



现在我们来探讨一下 .idata 节与 import table

下面是 helloworld.exe 映像中使用了 import table 

import table
VirtualAddress
0x00018000
size
0x50

下面是 helloworld.exe 映像中的 .idata 节:

.idata 节
VirtualSize
0x00000AAE
VirtualAddress
0x00018000
SizeOfRawData
0x00000C00
PointerToRawData
0x00006000
PointerToRelocations
0
PointerToLinenumbers
0
NumberOfRelocations
0
NumberOfLinenumbers
0
Characteristics
0xC0000040

 

 

1. .idata 的 Raw 数据

.idata 节的 raw 数据在 image 文件中的 0x00006000 处,它占用 image 文件 0xC00 bytes 空间,从 0x00006000 - 0x00006BFF

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00006000  AC 81 01 00 00 00 00 00 00 00 00 00 4A 85 01 00  ?...........J…..
00006010  8C 83 01 00 04 81 01 00 00 00 00 00 00 00 00 00  ??..............
00006020  4C 86 01 00 E4 82 01 00 50 80 01 00 00 00 00 00  L?..??..P€......
00006030  00 00 00 00 1E 89 01 00 30 82 01 00 00 00 00 00  .....‰..0?......
00006040  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006050  10 89 01 00 00 89 01 00 EA 88 01 00 D8 88 01 00  .‰...‰..ê?..??..
00006060  CC 88 01 00 C0 88 01 00 A6 88 01 00 90 88 01 00  ì?..à?..|?...?..
00006070  7A 88 01 00 6A 88 01 00 50 88 01 00 40 88 01 00  z?..j?..P?..@?..
00006080  22 88 01 00 06 88 01 00 F2 87 01 00 DE 87 01 00  "?...?..ò?..T?..
00006090  CE 87 01 00 BC 87 01 00 B0 87 01 00 88 87 01 00  ??..??..°?..??..
000060A0  74 87 01 00 5E 87 01 00 4C 87 01 00 36 87 01 00  t?..^?..L?..6?..
000060B0  18 87 01 00 10 87 01 00 FA 86 01 00 9E 87 01 00  .?...?..ú?..??..
000060C0  EA 86 01 00 00 00 00 00 00 00 00 00 00 00 00 00  ê?..............
000060D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000060E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000060F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006100  00 00 00 00 F0 85 01 00 FA 85 01 00 02 86 01 00  ....e…..ú…...?..
00006110  0C 86 01 00 20 86 01 00 32 86 01 00 3E 86 01 00  .?.. ?..2?..>?..
00006120  5A 86 01 00 70 86 01 00 84 86 01 00 94 86 01 00  Z?..p?..??..”?..
00006130  A6 86 01 00 B0 86 01 00 BE 86 01 00 C6 86 01 00  |?..°?..??..??..
00006140  D0 86 01 00 E2 85 01 00 C8 85 01 00 BA 85 01 00  D?..a…..è…..o…..
00006150  A8 85 01 00 9E 85 01 00 92 85 01 00 7E 85 01 00  ¨…..?…..’…..~…..
00006160  68 85 01 00 56 85 01 00 DA 85 01 00 00 00 00 00  h…..V…..ú…......
00006170  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006180  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006190  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000061A0  00 00 00 00 00 00 00 00 00 00 00 00 3E 85 01 00  ............>…..
000061B0  2C 85 01 00 1C 85 01 00 0A 85 01 00 FC 84 01 00  ,…...…...…..ü?..
000061C0  F0 84 01 00 DE 84 01 00 CC 84 01 00 BE 84 01 00  e?..T?..ì?..??..
000061D0  AE 84 01 00 A2 84 01 00 94 84 01 00 80 84 01 00  ??..¢?..”?..€?..
000061E0  72 84 01 00 5E 84 01 00 50 84 01 00 38 84 01 00  r?..^?..P?..8?..
000061F0  24 84 01 00 10 84 01 00 2C 89 01 00 3C 89 01 00  $?...?..,‰..<‰..
00006200  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006210  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006220  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006230  10 89 01 00 00 89 01 00 EA 88 01 00 D8 88 01 00  .‰...‰..ê?..??..
00006240  CC 88 01 00 C0 88 01 00 A6 88 01 00 90 88 01 00  ì?..à?..|?...?..
00006250  7A 88 01 00 6A 88 01 00 50 88 01 00 40 88 01 00  z?..j?..P?..@?..
00006260  22 88 01 00 06 88 01 00 F2 87 01 00 DE 87 01 00  "?...?..ò?..T?..
00006270  CE 87 01 00 BC 87 01 00 B0 87 01 00 88 87 01 00  ??..??..°?..??..
00006280  74 87 01 00 5E 87 01 00 4C 87 01 00 36 87 01 00  t?..^?..L?..6?..
00006290  18 87 01 00 10 87 01 00 FA 86 01 00 9E 87 01 00  .?...?..ú?..??..
000062A0  EA 86 01 00 00 00 00 00 00 00 00 00 00 00 00 00  ê?..............
000062B0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000062C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000062D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000062E0  00 00 00 00 F0 85 01 00 FA 85 01 00 02 86 01 00  ....e…..ú…...?..
000062F0  0C 86 01 00 20 86 01 00 32 86 01 00 3E 86 01 00  .?.. ?..2?..>?..
00006300  5A 86 01 00 70 86 01 00 84 86 01 00 94 86 01 00  Z?..p?..??..”?..
00006310  A6 86 01 00 B0 86 01 00 BE 86 01 00 C6 86 01 00  |?..°?..??..??..
00006320  D0 86 01 00 E2 85 01 00 C8 85 01 00 BA 85 01 00  D?..a…..è…..o…..
00006330  A8 85 01 00 9E 85 01 00 92 85 01 00 7E 85 01 00  ¨…..?…..’…..~…..
00006340  68 85 01 00 56 85 01 00 DA 85 01 00 00 00 00 00  h…..V…..ú…......
00006350  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006360  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006370  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006380  00 00 00 00 00 00 00 00 00 00 00 00 3E 85 01 00  ............>…..
00006390  2C 85 01 00 1C 85 01 00 0A 85 01 00 FC 84 01 00  ,…...…...…..ü?..
000063A0  F0 84 01 00 DE 84 01 00 CC 84 01 00 BE 84 01 00  e?..T?..ì?..??..
000063B0  AE 84 01 00 A2 84 01 00 94 84 01 00 80 84 01 00  ??..¢?..”?..€?..
000063C0  72 84 01 00 5E 84 01 00 50 84 01 00 38 84 01 00  r?..^?..P?..8?..
000063D0  24 84 01 00 10 84 01 00 2C 89 01 00 3C 89 01 00  $?...?..,‰..<‰..
000063E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000063F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006400  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006410  AF 00 44 69 73 70 61 74 63 68 4D 65 73 73 61 67  ˉ.DispatchMessag
00006420  65 57 00 00 FC 02 54 72 61 6E 73 6C 61 74 65 4D  eW..ü.TranslateM
00006430  65 73 73 61 67 65 00 00 FA 02 54 72 61 6E 73 6C  essage..ú.Transl
00006440  61 74 65 41 63 63 65 6C 65 72 61 74 6F 72 57 00  ateAcceleratorW.
00006450  5D 01 47 65 74 4D 65 73 73 61 67 65 57 00 E5 01  ].GetMessageW.?.
00006460  4C 6F 61 64 41 63 63 65 6C 65 72 61 74 6F 72 73  LoadAccelerators
00006470  57 00 FA 01 4C 6F 61 64 53 74 72 69 6E 67 57 00  W.ú.LoadStringW.
00006480  4D 02 52 65 67 69 73 74 65 72 43 6C 61 73 73 45  M.RegisterClassE
00006490  78 57 00 00 EB 01 4C 6F 61 64 43 75 72 73 6F 72  xW..?.LoadCursor
000064A0  57 00 ED 01 4C 6F 61 64 49 63 6F 6E 57 00 11 03  W.í.LoadIconW...
000064B0  55 70 64 61 74 65 57 69 6E 64 6F 77 00 00 DF 02  UpdateWindow..?.
000064C0  53 68 6F 77 57 69 6E 64 6F 77 00 00 6E 00 43 72  ShowWindow..n.Cr
000064D0  65 61 74 65 57 69 6E 64 6F 77 45 78 57 00 37 02  eateWindowExW.7.
000064E0  50 6F 73 74 51 75 69 74 4D 65 73 73 61 67 65 00  PostQuitMessage.
000064F0  DC 00 45 6E 64 50 61 69 6E 74 00 00 0E 00 42 65  ü.EndPaint....Be
00006500  67 69 6E 50 61 69 6E 74 00 00 9C 00 44 65 66 57  ginPaint..?.DefW
00006510  69 6E 64 6F 77 50 72 6F 63 57 00 00 A6 00 44 65  indowProcW..|.De
00006520  73 74 72 6F 79 57 69 6E 64 6F 77 00 AC 00 44 69  stroyWindow.?.Di
00006530  61 6C 6F 67 42 6F 78 50 61 72 61 6D 57 00 DA 00  alogBoxParamW.ú.
00006540  45 6E 64 44 69 61 6C 6F 67 00 55 53 45 52 33 32  EndDialog.USER32
00006550  2E 64 6C 6C 00 00 21 01 5F 43 52 54 5F 52 54 43  .dll..!._CRT_RTC
00006560  5F 49 4E 49 54 57 00 00 1B 02 5F 63 6F 6E 66 69  _INITW...._confi
00006570  67 74 68 72 65 61 64 6C 6F 63 61 6C 65 00 C7 01  gthreadlocale.?.
00006580  5F 5F 73 65 74 75 73 65 72 6D 61 74 68 65 72 72  __setusermatherr
00006590  00 00 1A 02 5F 63 6F 6D 6D 6F 64 65 00 00 79 02  ...._commode..y.
000065A0  5F 66 6D 6F 64 65 00 00 C4 01 5F 5F 73 65 74 5F  _fmode..?.__set_
000065B0  61 70 70 5F 74 79 70 65 00 00 F2 01 5F 61 6D 73  app_type..ò._ams
000065C0  67 5F 65 78 69 74 00 00 DB 01 5F 5F 77 67 65 74  g_exit..?.__wget
000065D0  6D 61 69 6E 61 72 67 73 00 00 5D 02 5F 65 78 69  mainargs..]._exi
000065E0  74 00 4F 01 5F 58 63 70 74 46 69 6C 74 65 72 00  t.O._XcptFilter.
000065F0  09 02 5F 63 65 78 69 74 00 00 B4 05 65 78 69 74  .._cexit..′.exit
00006600  00 00 0C 05 5F 77 63 6D 64 6C 6E 00 37 01 5F 43  ...._wcmdln.7._C
00006610  72 74 53 65 74 43 68 65 63 6B 43 6F 75 6E 74 00  rtSetCheckCount.
00006620  26 01 5F 43 72 74 44 62 67 52 65 70 6F 72 74 57  &._CrtDbgReportW
00006630  00 00 E9 02 5F 69 6E 69 74 74 65 72 6D 00 EA 02  ..é._initterm.ê.
00006640  5F 69 6E 69 74 74 65 72 6D 5F 65 00 4D 53 56 43  _initterm_e.MSVC
00006650  52 31 30 30 44 2E 64 6C 6C 00 2D 02 5F 63 72 74  R100D.dll.-._crt
00006660  5F 64 65 62 75 67 67 65 72 5F 68 6F 6F 6B 00 00  _debugger_hook..
00006670  04 01 3F 74 65 72 6D 69 6E 61 74 65 40 40 59 41  ..?terminate@@YA
00006680  58 58 5A 00 1E 02 5F 63 6F 6E 74 72 6F 6C 66 70  XXZ..._controlfp
00006690  5F 73 00 00 EF 02 5F 69 6E 76 6F 6B 65 5F 77 61  _s..?._invoke_wa
000066A0  74 73 6F 6E 00 00 C8 04 5F 75 6E 6C 6F 63 6B 00  tson..è._unlock.
000066B0  7D 01 5F 5F 64 6C 6C 6F 6E 65 78 69 74 00 5A 03  }.__dllonexit.Z.
000066C0  5F 6C 6F 63 6B 00 02 04 5F 6F 6E 65 78 69 74 00  _lock..._onexit.
000066D0  54 02 5F 65 78 63 65 70 74 5F 68 61 6E 64 6C 65  T._except_handle
000066E0  72 34 5F 63 6F 6D 6D 6F 6E 00 EA 00 45 6E 63 6F  r4_common.ê.Enco
000066F0  64 65 50 6F 69 6E 74 65 72 00 EC 02 49 6E 74 65  dePointer.ì.Inte
00006700  72 6C 6F 63 6B 65 64 45 78 63 68 61 6E 67 65 00  rlockedExchange.
00006710  B2 04 53 6C 65 65 70 00 E9 02 49 6E 74 65 72 6C  2.Sleep.é.Interl
00006720  6F 63 6B 65 64 43 6F 6D 70 61 72 65 45 78 63 68  ockedCompareExch
00006730  61 6E 67 65 00 00 D3 02 48 65 61 70 53 65 74 49  ange..ó.HeapSetI
00006740  6E 66 6F 72 6D 61 74 69 6F 6E 00 00 63 02 47 65  nformation..c.Ge
00006750  74 53 74 61 72 74 75 70 49 6E 66 6F 57 00 11 05  tStartupInfoW...
00006760  57 69 64 65 43 68 61 72 54 6F 4D 75 6C 74 69 42  WideCharToMultiB
00006770  79 74 65 00 00 03 49 73 44 65 62 75 67 67 65 72  yte...IsDebugger
00006780  50 72 65 73 65 6E 74 00 67 03 4D 75 6C 74 69 42  Present.g.MultiB
00006790  79 74 65 54 6F 57 69 64 65 43 68 61 72 00 B1 03  yteToWideChar.±.
000067A0  52 61 69 73 65 45 78 63 65 70 74 69 6F 6E 00 00  RaiseException..
000067B0  4D 05 6C 73 74 72 6C 65 6E 41 00 00 45 02 47 65  M.lstrlenA..E.Ge
000067C0  74 50 72 6F 63 41 64 64 72 65 73 73 00 00 3F 03  tProcAddress..?.
000067D0  4C 6F 61 64 4C 69 62 72 61 72 79 57 00 00 C0 04  LoadLibraryW..à.
000067E0  54 65 72 6D 69 6E 61 74 65 50 72 6F 63 65 73 73  TerminateProcess
000067F0  00 00 C0 01 47 65 74 43 75 72 72 65 6E 74 50 72  ..à.GetCurrentPr
00006800  6F 63 65 73 73 00 D3 04 55 6E 68 61 6E 64 6C 65  ocess.ó.Unhandle
00006810  64 45 78 63 65 70 74 69 6F 6E 46 69 6C 74 65 72  dExceptionFilter
00006820  00 00 A5 04 53 65 74 55 6E 68 61 6E 64 6C 65 64  ..¥.SetUnhandled
00006830  45 78 63 65 70 74 69 6F 6E 46 69 6C 74 65 72 00  ExceptionFilter.
00006840  CA 00 44 65 63 6F 64 65 50 6F 69 6E 74 65 72 00  ê.DecodePointer.
00006850  A7 03 51 75 65 72 79 50 65 72 66 6F 72 6D 61 6E  §.QueryPerforman
00006860  63 65 43 6F 75 6E 74 65 72 00 93 02 47 65 74 54  ceCounter.“.GetT
00006870  69 63 6B 43 6F 75 6E 74 00 00 C5 01 47 65 74 43  ickCount..?.GetC
00006880  75 72 72 65 6E 74 54 68 72 65 61 64 49 64 00 00  urrentThreadId..
00006890  C1 01 47 65 74 43 75 72 72 65 6E 74 50 72 6F 63  á.GetCurrentProc
000068A0  65 73 73 49 64 00 79 02 47 65 74 53 79 73 74 65  essId.y.GetSyste
000068B0  6D 54 69 6D 65 41 73 46 69 6C 65 54 69 6D 65 00  mTimeAsFileTime.
000068C0  CF 02 48 65 61 70 46 72 65 65 00 00 CB 02 48 65  ?.HeapFree..?.He
000068D0  61 70 41 6C 6C 6F 63 00 4A 02 47 65 74 50 72 6F  apAlloc.J.GetPro
000068E0  63 65 73 73 48 65 61 70 00 00 14 02 47 65 74 4D  cessHeap....GetM
000068F0  6F 64 75 6C 65 46 69 6C 65 4E 61 6D 65 57 00 00  oduleFileNameW..
00006900  F1 04 56 69 72 74 75 61 6C 51 75 65 72 79 00 00  ?.VirtualQuery..
00006910  62 01 46 72 65 65 4C 69 62 72 61 72 79 00 4B 45  b.FreeLibrary.KE
00006920  52 4E 45 4C 33 32 2E 64 6C 6C 00 00 14 01 47 65  RNEL32.dll....Ge
00006930  74 43 6C 69 65 6E 74 52 65 63 74 00 D0 00 44 72  tClientRect.D.Dr
00006940  61 77 54 65 78 74 57 00 00 00 00 00 00 00 00 00  awTextW.........
00006950  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006960  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006970  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006980  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006990  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000069A0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000069B0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000069C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000069D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000069E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000069F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006A00  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006A10  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006A20  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006A30  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006A40  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006A50  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006A60  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006A70  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006A80  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006A90  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006AA0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006AB0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006AC0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006AD0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006AE0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006AF0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006B00  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006B10  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006B20  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006B30  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006B40  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006B50  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006B60  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006B70  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006B80  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006B90  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006BA0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006BB0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006BC0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006BD0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006BE0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00006BF0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

当 helloworld.exe 被加载运行时,.idata 被加载到 0x00418000

.idata 的属性是 0xC0000040,它等于 IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA,因此 .idata 节是 writeable/readable 的并且是已初始化的的数据

实际上 .idata 节就是 import table 节。

 

2. import table 的 raw 数据

helloworld.exe 使用的其中一个 data table 是 import table,由数据目录表 DataDriectory[1] 的 VirtualAddress 指出 import table 会被加载到 0x00418000ImageBase + VirtualAddress),大小为 0x50 bytes,这个地址正好是 .idata 节的地址

实际上,import table 就在 .idata 节开头的 0x50 bytes,与 .idata 重叠一起。下面是 import table 的数据,从 0x6000 - 0x604F(共 0x50 bytes):

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00006000  AC 81 01 00 00 00 00 00 00 00 00 00 4A 85 01 00  ?...........J…..
00006010  8C 83 01 00 04 81 01 00 00 00 00 00 00 00 00 00  ??..............
00006020  4C 86 01 00 E4 82 01 00 50 80 01 00 00 00 00 00  L?..??..P€......
00006030  00 00 00 00 1E 89 01 00 30 82 01 00 00 00 00 00  .....‰..0?......
00006040  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

 

3. import table 的结构

在 WinNT.h 中定义了 IMAGE_IMPORT_DESCRIPTOR 结构来描述 import table

typedef struct _IMAGE_IMPORT_DESCRIPTOR {
    union {
        DWORD   Characteristics;            // 0 for terminating null import descriptor
        DWORD   OriginalFirstThunk;         // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
    } DUMMYUNIONNAME;
    DWORD   TimeDateStamp;                  // 0 if not bound,
                                            // -1 if bound, and real date\time stamp
                                            //     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
                                            // O.W. date/time stamp of DLL bound to (Old BIND)

    DWORD   ForwarderChain;                 // -1 if no forwarders
    DWORD   Name;
    DWORD   FirstThunk;                     // RVA to IAT (if bound this IAT has actual addresses)
} IMAGE_IMPORT_DESCRIPTOR;

IMAGE_IMPORT_DESCRIPTOR 结构 5 个域,共 20 bytes,其中:

  • OriginalFirstThunk :这是一个间接层,指向一个 IMAGE_THUNK_DATA 结构
  • FirstThunk : 指向 IAT(Import Address Table)

Name 字段是一个指令 import 字符串的 RVA 值,下面是一张图表,给出 import table 与 hint/name table 的关系:

          import table

     +----------------------+                     import lookup table
 (0) | OriginalFirstThunk   | ----------------> +--------------------+
     +----------------------+                   |   hint/name RVA    | ------\         
     | TimeDataStamp        |                   +--------------------+       |
     +----------------------+            +----> |   hint/name RVA    | ---+  |  
     | ForwarderChain       |            |      +--------------------+    |  |
     +----------------------+            |                                |  |
     | Name                 | -----------+---+                            |  | 
     +----------------------+            |   |                            |  | 
     | FirstThunk           | ----\      |   |        DLL name            |  | 
     +----------------------+     |      |   +--> +---------------+       |  | 
 (1) | OriginalFirstThunk   | ----+------+        | "User32.dll"  |       |  |             hint/name table 
     +----------------------+     |               +---------------+       |  |
     | TimeDataStramp       |     |                                       |  +--->  +-------+-----------------+
     +----------------------+     |                                     +-|------>  | Hint  | function name   |
     | ForwarderChain       |     |                                     | +------>  +-------+-----------------+
     +--------------------- +     |                                     |  +----->  | Hint  | function name   |
     | Name                 |     |       Import Address Table          |  |        +-------+-----------------+
     +----------------------+     |    +----------------------------+   |  |        | Hint  | function name   |
     | FirstThunk           |--+  +--> |     hint/name RVA          | --+  |        +-------+-----------------+
     +----------------------+  |       +----------------------------+      |        | Hint  | function name   |
                               +-----> |     hint/name RVA          | -----+        +-------+-----------------+
                                       +----------------------------+

helloworld.exe 映像的 import table 如下:

00418000  AC 81 01 00       // OriginalFirstThunk
00418004  00 00 00 00       // TimeDataStamp
00418008  00 00 00 00       // ForwarderChain
0041800C  4A 85 01 00       // Name
00418010  8C 83 01 00       // FirstThunk

00418014  04 81 01 00       // OriginalFirstThunk
00418018  00 00 00 00       // TimeDataStamp 
0041801C  00 00 00 00       // ForwarderChain
00418020  4C 86 01 00       // Name 
00418024  E4 82 01 00       // FirstThunk

00418028  50 80 01 00       // OriginalFirstThunk 
0041802C  00 00 00 00       // TimeDataStamp
00418030  00 00 00 00       // ForwarderChain 
00418034  1E 89 01 00       // Name 
00418038  30 82 01 00       // FirstThunk

0041803C  00 00 00 00       // OriginalFirstThunk 
00418040  00 00 00 00       // TimeDataStamp 
00418044  00 00 00 00       // ForwarderChain 
00418048  00 00 00 00       // Name 
0041804C  00 00 00 00       // FirstThunk

实际使用了 3 个 import table 表项,注意上面的地址值我已经使用了 VA(Vritual Address)值,这是为了分析方便。

OriginalFirstThunk
Name
FirstThunk
0
0x000181AC
0x0001854A
0x0001838C
1
0x00018104
0x0001864C
0x000182E4
3
0x00018050
0x0001891E
0x00018230

这些字段使用的都是 RVA 值,是基于 ImageBase 值

 

4. import lookup table

这个 import lookup table 实际上是一个 IMAGE_THUNK_DATA 结构数组,这个结构在 WinNT.h 定义为:

typedef struct _IMAGE_THUNK_DATA64 {
    union {
        ULONGLONG ForwarderString;  // PBYTE 
        ULONGLONG Function;         // PDWORD
        ULONGLONG Ordinal;
        ULONGLONG AddressOfData;    // PIMAGE_IMPORT_BY_NAME
    } u1;
} IMAGE_THUNK_DATA64;
typedef IMAGE_THUNK_DATA64 * PIMAGE_THUNK_DATA64;

#include "poppack.h"                        // Back to 4 byte packing

typedef struct _IMAGE_THUNK_DATA32 {
    union {
        DWORD ForwarderString;      // PBYTE 
        DWORD Function;             // PDWORD
        DWORD Ordinal;
        DWORD AddressOfData;        // PIMAGE_IMPORT_BY_NAME
    } u1;
} IMAGE_THUNK_DATA32;
typedef IMAGE_THUNK_DATA32 * PIMAGE_THUNK_DATA32;

这个结构分为 32/64 位版本。在 64 位版本里它的域是 64 位的。

IMAGE_THUNK_DATA 结构里是一个 union 变量,AddressOfData 是一个指向 hint/name table 的 RVA 值,这个值必定是 32 位的,在 64 位版本的 IMAGE_THUNK_DATA64 结构里,AddressOfData 的高 32 位被清 0

Ordinal 用于提供一个 hint/name table 的序号,在 32 位结构中,当 bit31(最高位)是 1 的话,在 64 位版 本结构中是 bit63(最高位)那么就需要提供 Ordinal 值,可是 Ordinal 不可能高最位是 1,也就是说 IMAGE_THUNK_DATA 不可能提供一个Ordinal 值,windows 根本没实现这样一种结构。

Ordinal 最高位为 0 时,它提供根据 Name 实现导入,这时,AddressOfData 提供 32 位的 RVA 值来指向 IMAGE_IMPORT_BY_NANE 结构。

PE 格式实现始终是以 NAME 来导入,所以 IMAGE_THUNK_DATA 结构必定是提供一个 32 位的 RVA 值。

下面是 helloworld.exe 的其中一组 import lookup table:

OriginalFirstThunk        hint/name RVA
----------------------------------
004181AC              3E 85 01 00
004181B0              2C 85 01 00 
004181B4              1C 85 01 00 
004181B8              0A 85 01 00 
004181BC              FC 84 01 00 
004181C0              F0 84 01 00 
004181C4              DE 84 01 00 
004181C8              CC 84 01 00 
004181CC              BE 84 01 00 
004181D0              AE 84 01 00 
004181D4              A2 84 01 00 
004181D8              94 84 01 00 
004181DC              80 84 01 00
004181E0              72 84 01 00 
004181E4              5E 84 01 00 
004181E8              50 84 01 00 
004181EC              38 84 01 00
004181F0              24 84 01 00 
004181F4              10 84 01 00 
004181F8              2C 89 01 00 
004181FC              3C 89 01 00

该数组的第 1 项值 0x004181AC 就是由 import table 中的 OriginalFirstThunk 值给出,见于上节中的表格。如前面所示,这样的数据应该共有 3 组(3 个 OriginalFirstThunk 值)。

第 1 项中的 hint/name table RVA 值为 0x0001853E,那么它指向的 hint/name table 在 0x0041853E

 

5. hint/name table

前面所说,hint/name table 由 IMAGE_THUNK_DATA 的 AddressOfData 所得,它是 import by NAME

在 WinNT.h 中定义的 IMAGE_IMPORT_BY_NAME 结构来描述 hint/name table:

typedef struct _IMAGE_IMPORT_BY_NAME {
    WORD    Hint;
    BYTE    Name[1];
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

Hint 是一个 16 位的值,它是一个 export 名字索引值。Name 虽然定义为 1 byte 数组,它是一个长度可变 ASCII 字符数组,以 '\0' 结尾的字符数组,它是 import 函数名。

以上面的 0x0041853E 所指的 Hint/Name table 为例:

0041853E  DA 00                                  // Hint = 0x00DA
00418540  45 6E 64 44 69 61 6C 6F 67 00          // Name = EndDialog

它们的关系如上面的关系图表一样。

[import table].OriginalFirstThunk ---> [import lookup table].AddressOfData ---> [Hint/Name table].Hint

 

6. Import Address Table

在导入函数进行真实地址绑定之前,Import Address Table 的组织和内容与 IMPORT_THUNK_DATA 结构是一样的,Import Address Table 的值就是 AddressOfData

因此,在函数绑定之前,Import Address Table 的值就是 Hint/Name Table 的 RVA 值。

import table 第 1 项的 FirstThunk 值为:0x0001838C,看看它的 Import Address Table:

FirstThunk         Hint/Name table RVA
----------------------------------------
0041838C              3E 85 01 00
00418390              2C 85 01 00 
00418394              1C 85 01 00 
00418398              0A 85 01 00 
0041839C              FC 84 01 00
004183A0              F0 84 01 00 
004183A4              DE 84 01 00 
004183A8              CC 84 01 00 
004183AC              BE 84 01 00
004183B0              AE 84 01 00 
004183B4              A2 84 01 00 
004183B8              94 84 01 00 
004183BC              80 84 01 00
004183C0              72 84 01 00 
004183C4              5E 84 01 00 
004183C8              50 84 01 00 
004183CC              38 84 01 00
004183D0              24 84 01 00 
004183D4              10 84 01 00 
004183D8              2C 89 01 00 
004183DC              3C 89 01 00

可以看出通过 OriginalFirstThunk 与 FirstThunk 指向的 Hint/Name table RVA 都是一样的。

但是:

在进行函数地址绑定之后,Import Address Table 就是被导入函数的真实地址

 

7. 获取 import DLL name

IMAGE_IMPORT_DESCRIPTOR 结构里的 Name 域指出所 Import 的 DLL 的名字,在 helloworld.exe 其中的一个 import table 中的 Name

00418000 AC 81 01 00             // OriginalFirstThunk
00418004 00 00 00 00             // TimeDataStamp
00418008 00 00 00 00             // ForwarderChain
0041800C 4A 85 01 00             // Name
00418010 8C 83 01 00             // FirstThunk

这个 Name 值是 0x0001854A 那么,它的值是:

Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

0041854A  55 53 45 52 33 32 2E 64 6C 6C 00                   // "USER32.dll"

在 0x0041854A 处放着 "USER32.dll" 的字符串,它以 ASCII 串形式表示导入的 DLL 名字

 

下一篇文章,我们来探讨一下函数的绑定。


版权 mik 所有,转载请注明出处

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值