Что за чертовщина?! Каким образом расшифровщик может существовать в extern, когда здесь прямым текстом прописаны фактические адреса динамически загружаемых функций! Но тот факт, что файл все-таки работает, убеждает нас, что да — может! Просто IDA Pro в попытке "эмуляции" загрузки elf-файла пихает в extern всякую хрень, которой там нет. ### то, чего там в действительности нет
Здесь мы подходим к одной из самых любопытных особенной строения elf-файлов. В отличии от Windows, где заполнение extern'а происходит на стадии загрузки файла в память, в UNIX это делает стартовый код, причем делает он это очень хитрым способом. Ниже показан протокол трассировки программы под отладчиком с моими комментариями, отмеченными знаком ';' и содержимым дизассемблерного листинга IDA Pro, отмеченным знаком '#'. Как говориться — сравните и почувствуйте разницу!
Для облегчения понимая возьмем незашифрованную программу, необработанную ELFCrypt'ом:
(gdb) b _start ; устанавливаем точку останова на начало стартового кода
Breakpoint 1 at 0x80482c0: file ../sysdeps/i386/elf/start.S, line 47.
(gdb) r ; запускаем программу на выполнение
Breakpoint 1, _start () at ../sysdeps/i386/elf/start.S:47
(gdb) x 0x80495DC ; ок, мы в точке входа. смотрим на extern
# extern:80495DC 7F 01 00 00 extern puts@@GLIBC_2_0:near
0x80495dc: 0x00000000
; IDA Pro нас уверяет, что extern содержит адрес 0000017Fh, но в действительности
; область extern на момент запуска файла девственно чиста и забита нулями
#.text:080482C0 _start proc near
#.text:080482C0 31 ED xor ebp, ebp
1: x/i $pc 0x80482c0 <_start>
: xor %ebp,%ebp
; // незначащие машинные инструкции пропущены
#.text:080482D7 68 90 83 04 08 push offset main
1: x/i $pc 0x80482d7 <_start+23>
: push $0x8048390
#.text:080482DC E8 CF FF FF FF call ___libc_start_main