Import Address Table 和 Global Offset Table 有什么区别?
What is the difference between Import Address Table and Global Offset Table?
我试着分别用谷歌搜索它们,但最突出的是一件事。难道只是IAT是PE文件而GoT是ELF?
在 Linux 上,可以使用 nm 命令查看必须从共享库导入的所有符号。我编译了一个叫"main"的小程序。使用 nm 命令,我可以看到对象的偏移量。以 'T' 为前缀的符号是可以在 "main" 代码中找到的函数,以及逻辑偏移量(全局偏移量 Table)。以 'U' 为前缀的符号未定义,必须导入(导入地址 Table)。
$ nm main
0000000100000d70 T _AddAlbum
U ___error
U ___stderrp
0000000100000000 T __mh_execute_header
U _fprintf
0000000100000e40 T _main
U _malloc
U _printf
U _realloc
U _strerror
U dyld_stub_binder
有关更多详细信息,请使用带有 -x 选项的 objdump:
$ objdump -x main
main: file format Mach-O 64-bit x86-64
Sections:
Idx Name Size Address Type
0 __text 0000018a 0000000100000d70 TEXT
1 __stubs 00000024 0000000100000efa TEXT
2 __stub_helper 0000004c 0000000100000f20 TEXT
3 __cstring 00000042 0000000100000f6c DATA
4 __unwind_info 00000048 0000000100000fb0 DATA
5 __nl_symbol_ptr 00000008 0000000100001000 DATA
6 __got 00000010 0000000100001008 DATA
7 __la_symbol_ptr 00000030 0000000100001018 DATA
SYMBOL TABLE:
0000000100000d70 g F __TEXT,__text _AddAlbum
0000000100000000 g F __TEXT,__text __mh_execute_header
0000000100000e40 g F __TEXT,__text _main
0000000000000000 *UND* ___error
0000000000000000 *UND* ___stderrp
0000000000000000 *UND* _fprintf
0000000000000000 *UND* _malloc
0000000000000000 *UND* _printf
0000000000000000 *UND* _realloc
0000000000000000 *UND* _strerror
0000000000000000 *UND* dyld_stub_binder
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
MH_MAGIC_64 X86_64 ALL LIB64 EXECUTE 15 1296 NOUNDEFS DYLDLINK TWOLEVEL PIE
Load command 0
cmd LC_SEGMENT_64
cmdsize 72
segname __PAGEZERO
vmaddr 0x0000000000000000
vmsize 0x0000000100000000
fileoff 0
filesize 0
maxprot ---
initprot ---
nsects 0
flags (none)
Load command 1
cmd LC_SEGMENT_64
cmdsize 472
segname __TEXT
vmaddr 0x0000000100000000
vmsize 0x0000000000001000
fileoff 0
filesize 4096
maxprot r-x
initprot r-x
nsects 5
flags (none)
Section
sectname __text
segname __TEXT
addr 0x0000000100000d70
size 0x000000000000018a
offset 3440
align 2^4 (16)
reloff 0
nreloc 0
type S_REGULAR
attributes PURE_INSTRUCTIONS SOME_INSTRUCTIONS
reserved1 0
reserved2 0
Section
sectname __stubs
segname __TEXT
addr 0x0000000100000efa
size 0x0000000000000024
offset 3834
align 2^1 (2)
reloff 0
nreloc 0
type S_SYMBOL_STUBS
attributes PURE_INSTRUCTIONS SOME_INSTRUCTIONS
reserved1 0 (index into indirect symbol table)
reserved2 6 (size of stubs)
Section
sectname __stub_helper
segname __TEXT
addr 0x0000000100000f20
size 0x000000000000004c
offset 3872
align 2^2 (4)
reloff 0
nreloc 0
type S_REGULAR
attributes PURE_INSTRUCTIONS SOME_INSTRUCTIONS
reserved1 0
reserved2 0
Section
sectname __cstring
segname __TEXT
addr 0x0000000100000f6c
size 0x0000000000000042
offset 3948
align 2^0 (1)
reloff 0
nreloc 0
type S_CSTRING_LITERALS
attributes (none)
reserved1 0
reserved2 0
Section
sectname __unwind_info
segname __TEXT
addr 0x0000000100000fb0
size 0x0000000000000048
offset 4016
align 2^2 (4)
reloff 0
nreloc 0
type S_REGULAR
attributes (none)
reserved1 0
reserved2 0
Load command 2
cmd LC_SEGMENT_64
cmdsize 312
segname __DATA
vmaddr 0x0000000100001000
vmsize 0x0000000000001000
fileoff 4096
filesize 4096
maxprot rw-
initprot rw-
nsects 3
flags (none)
Section
sectname __nl_symbol_ptr
segname __DATA
addr 0x0000000100001000
size 0x0000000000000008
offset 4096
align 2^3 (8)
reloff 0
nreloc 0
type S_NON_LAZY_SYMBOL_POINTERS
attributes (none)
reserved1 6 (index into indirect symbol table)
reserved2 0
Section
sectname __got
segname __DATA
addr 0x0000000100001008
size 0x0000000000000010
offset 4104
align 2^3 (8)
reloff 0
nreloc 0
type S_NON_LAZY_SYMBOL_POINTERS
attributes (none)
reserved1 7 (index into indirect symbol table)
reserved2 0
Section
sectname __la_symbol_ptr
segname __DATA
addr 0x0000000100001018
size 0x0000000000000030
offset 4120
align 2^3 (8)
reloff 0
nreloc 0
type S_LAZY_SYMBOL_POINTERS
attributes (none)
reserved1 9 (index into indirect symbol table)
reserved2 0
Load command 3
cmd LC_SEGMENT_64
cmdsize 72
segname __LINKEDIT
vmaddr 0x0000000100002000
vmsize 0x0000000000001000
fileoff 8192
filesize 572
maxprot r--
initprot r--
nsects 0
flags (none)
Load command 4
cmd LC_DYLD_INFO_ONLY
cmdsize 48
rebase_off 8192
rebase_size 8
bind_off 8200
bind_size 40
weak_bind_off 0
weak_bind_size 0
lazy_bind_off 8240
lazy_bind_size 96
export_off 8336
export_size 64
Load command 5
cmd LC_SYMTAB
cmdsize 24
symoff 8408
nsyms 11
stroff 8644
strsize 120
Load command 6
cmd LC_DYSYMTAB
cmdsize 80
ilocalsym 0
nlocalsym 0
iextdefsym 0
nextdefsym 3
iundefsym 3
nundefsym 8
tocoff 0
ntoc 0
modtaboff 0
nmodtab 0
extrefsymoff 0
nextrefsyms 0
indirectsymoff 8584
nindirectsyms 15
extreloff 0
nextrel 0
locreloff 0
nlocrel 0
Load command 7
cmd LC_LOAD_DYLINKER
cmdsize 32
name /usr/lib/dyld (offset 12)
Load command 8
cmd LC_UUID
cmdsize 24
uuid 55558635-5195-3609-B115-706912ED1DA7
Load command 9
cmd LC_BUILD_VERSION
cmdsize 32
platform macos
sdk 10.14
minos 10.14
ntools 1
tool ld
version 520.0
Load command 10
cmd LC_SOURCE_VERSION
cmdsize 16
version 0.0
Load command 11
cmd LC_MAIN
cmdsize 24
entryoff 3648
stacksize 0
Load command 12
cmd LC_LOAD_DYLIB
cmdsize 56
name /usr/lib/libSystem.B.dylib (offset 24)
time stamp 2 Wed Dec 31 17:00:02 1969
current version 1281.0.0
compatibility version 1.0.0
Load command 13
cmd LC_FUNCTION_STARTS
cmdsize 16
dataoff 8400
datasize 8
Load command 14
cmd LC_DATA_IN_CODE
cmdsize 16
dataoff 8408
datasize 0
Is it just that IAT is for PE files and GoT is for ELF?
这是主要区别。
另一个区别是 ELF 文件中的 GOT 也可能包含描述 ELF 文件本身定义的符号的条目。这是典型的 32 位共享库。
PE 文件中的 IAT 仅包含描述其他 DLL 文件中定义的符号的条目。
我试着分别用谷歌搜索它们,但最突出的是一件事。难道只是IAT是PE文件而GoT是ELF?
在 Linux 上,可以使用 nm 命令查看必须从共享库导入的所有符号。我编译了一个叫"main"的小程序。使用 nm 命令,我可以看到对象的偏移量。以 'T' 为前缀的符号是可以在 "main" 代码中找到的函数,以及逻辑偏移量(全局偏移量 Table)。以 'U' 为前缀的符号未定义,必须导入(导入地址 Table)。
$ nm main
0000000100000d70 T _AddAlbum
U ___error
U ___stderrp
0000000100000000 T __mh_execute_header
U _fprintf
0000000100000e40 T _main
U _malloc
U _printf
U _realloc
U _strerror
U dyld_stub_binder
有关更多详细信息,请使用带有 -x 选项的 objdump:
$ objdump -x main
main: file format Mach-O 64-bit x86-64
Sections:
Idx Name Size Address Type
0 __text 0000018a 0000000100000d70 TEXT
1 __stubs 00000024 0000000100000efa TEXT
2 __stub_helper 0000004c 0000000100000f20 TEXT
3 __cstring 00000042 0000000100000f6c DATA
4 __unwind_info 00000048 0000000100000fb0 DATA
5 __nl_symbol_ptr 00000008 0000000100001000 DATA
6 __got 00000010 0000000100001008 DATA
7 __la_symbol_ptr 00000030 0000000100001018 DATA
SYMBOL TABLE:
0000000100000d70 g F __TEXT,__text _AddAlbum
0000000100000000 g F __TEXT,__text __mh_execute_header
0000000100000e40 g F __TEXT,__text _main
0000000000000000 *UND* ___error
0000000000000000 *UND* ___stderrp
0000000000000000 *UND* _fprintf
0000000000000000 *UND* _malloc
0000000000000000 *UND* _printf
0000000000000000 *UND* _realloc
0000000000000000 *UND* _strerror
0000000000000000 *UND* dyld_stub_binder
Mach header
magic cputype cpusubtype caps filetype ncmds sizeofcmds flags
MH_MAGIC_64 X86_64 ALL LIB64 EXECUTE 15 1296 NOUNDEFS DYLDLINK TWOLEVEL PIE
Load command 0
cmd LC_SEGMENT_64
cmdsize 72
segname __PAGEZERO
vmaddr 0x0000000000000000
vmsize 0x0000000100000000
fileoff 0
filesize 0
maxprot ---
initprot ---
nsects 0
flags (none)
Load command 1
cmd LC_SEGMENT_64
cmdsize 472
segname __TEXT
vmaddr 0x0000000100000000
vmsize 0x0000000000001000
fileoff 0
filesize 4096
maxprot r-x
initprot r-x
nsects 5
flags (none)
Section
sectname __text
segname __TEXT
addr 0x0000000100000d70
size 0x000000000000018a
offset 3440
align 2^4 (16)
reloff 0
nreloc 0
type S_REGULAR
attributes PURE_INSTRUCTIONS SOME_INSTRUCTIONS
reserved1 0
reserved2 0
Section
sectname __stubs
segname __TEXT
addr 0x0000000100000efa
size 0x0000000000000024
offset 3834
align 2^1 (2)
reloff 0
nreloc 0
type S_SYMBOL_STUBS
attributes PURE_INSTRUCTIONS SOME_INSTRUCTIONS
reserved1 0 (index into indirect symbol table)
reserved2 6 (size of stubs)
Section
sectname __stub_helper
segname __TEXT
addr 0x0000000100000f20
size 0x000000000000004c
offset 3872
align 2^2 (4)
reloff 0
nreloc 0
type S_REGULAR
attributes PURE_INSTRUCTIONS SOME_INSTRUCTIONS
reserved1 0
reserved2 0
Section
sectname __cstring
segname __TEXT
addr 0x0000000100000f6c
size 0x0000000000000042
offset 3948
align 2^0 (1)
reloff 0
nreloc 0
type S_CSTRING_LITERALS
attributes (none)
reserved1 0
reserved2 0
Section
sectname __unwind_info
segname __TEXT
addr 0x0000000100000fb0
size 0x0000000000000048
offset 4016
align 2^2 (4)
reloff 0
nreloc 0
type S_REGULAR
attributes (none)
reserved1 0
reserved2 0
Load command 2
cmd LC_SEGMENT_64
cmdsize 312
segname __DATA
vmaddr 0x0000000100001000
vmsize 0x0000000000001000
fileoff 4096
filesize 4096
maxprot rw-
initprot rw-
nsects 3
flags (none)
Section
sectname __nl_symbol_ptr
segname __DATA
addr 0x0000000100001000
size 0x0000000000000008
offset 4096
align 2^3 (8)
reloff 0
nreloc 0
type S_NON_LAZY_SYMBOL_POINTERS
attributes (none)
reserved1 6 (index into indirect symbol table)
reserved2 0
Section
sectname __got
segname __DATA
addr 0x0000000100001008
size 0x0000000000000010
offset 4104
align 2^3 (8)
reloff 0
nreloc 0
type S_NON_LAZY_SYMBOL_POINTERS
attributes (none)
reserved1 7 (index into indirect symbol table)
reserved2 0
Section
sectname __la_symbol_ptr
segname __DATA
addr 0x0000000100001018
size 0x0000000000000030
offset 4120
align 2^3 (8)
reloff 0
nreloc 0
type S_LAZY_SYMBOL_POINTERS
attributes (none)
reserved1 9 (index into indirect symbol table)
reserved2 0
Load command 3
cmd LC_SEGMENT_64
cmdsize 72
segname __LINKEDIT
vmaddr 0x0000000100002000
vmsize 0x0000000000001000
fileoff 8192
filesize 572
maxprot r--
initprot r--
nsects 0
flags (none)
Load command 4
cmd LC_DYLD_INFO_ONLY
cmdsize 48
rebase_off 8192
rebase_size 8
bind_off 8200
bind_size 40
weak_bind_off 0
weak_bind_size 0
lazy_bind_off 8240
lazy_bind_size 96
export_off 8336
export_size 64
Load command 5
cmd LC_SYMTAB
cmdsize 24
symoff 8408
nsyms 11
stroff 8644
strsize 120
Load command 6
cmd LC_DYSYMTAB
cmdsize 80
ilocalsym 0
nlocalsym 0
iextdefsym 0
nextdefsym 3
iundefsym 3
nundefsym 8
tocoff 0
ntoc 0
modtaboff 0
nmodtab 0
extrefsymoff 0
nextrefsyms 0
indirectsymoff 8584
nindirectsyms 15
extreloff 0
nextrel 0
locreloff 0
nlocrel 0
Load command 7
cmd LC_LOAD_DYLINKER
cmdsize 32
name /usr/lib/dyld (offset 12)
Load command 8
cmd LC_UUID
cmdsize 24
uuid 55558635-5195-3609-B115-706912ED1DA7
Load command 9
cmd LC_BUILD_VERSION
cmdsize 32
platform macos
sdk 10.14
minos 10.14
ntools 1
tool ld
version 520.0
Load command 10
cmd LC_SOURCE_VERSION
cmdsize 16
version 0.0
Load command 11
cmd LC_MAIN
cmdsize 24
entryoff 3648
stacksize 0
Load command 12
cmd LC_LOAD_DYLIB
cmdsize 56
name /usr/lib/libSystem.B.dylib (offset 24)
time stamp 2 Wed Dec 31 17:00:02 1969
current version 1281.0.0
compatibility version 1.0.0
Load command 13
cmd LC_FUNCTION_STARTS
cmdsize 16
dataoff 8400
datasize 8
Load command 14
cmd LC_DATA_IN_CODE
cmdsize 16
dataoff 8408
datasize 0
Is it just that IAT is for PE files and GoT is for ELF?
这是主要区别。
另一个区别是 ELF 文件中的 GOT 也可能包含描述 ELF 文件本身定义的符号的条目。这是典型的 32 位共享库。
PE 文件中的 IAT 仅包含描述其他 DLL 文件中定义的符号的条目。