Для кода
PIE (и PIC) требуется процесс перемещения после загрузки по какому-либо адресу (отличному от значения по умолчанию) и до его запуска. Предлагаю вам ознакомиться с кодом ld.so
. Кроме того, вы должны проверить таблицу перемещений в вашем двоичном файле (например, используя readelf -r
).
Вот хорошая презентация о PIE (речь идет об OpenBSD, но процесс такой же). http://www.openbsd.org/papers/nycbsdcon08-pie/ или http://www.dcbsdcon.org/speakers/slides/miller_dcbsdcon2009.pdf
Полагаю, вам следует не только изменить GOT, но и найти все перемещения и выполнить их.
По сути, обработка двоичного файла PIE с помощью ld.so почти такая же, как обработка динамической библиотеки с помощью PIC с перемещением не библиотеки, а самого исполняемого образа.
«Неправильные адреса», которые вы видите, - это место, где фактическое значение будет записано путем решения о перемещении. Что касается i386 http://books.google.com/books?id=Id9cYsIdjIwC&pg=PA174, то есть перемещения:
- R_386_GOTPC
- R_386_GOT32
- R_386_GOTOFF
- R_386_RELATIVE
Линкер должен разрешить все из них, прежде чем код сможет получить доступ к глобальным данным.
Readelf -r образец:
Динамически связанный
$ readelf -r fdyn
Relocation section '.rel.dyn' at offset 0x27c contains 1 entries:
Offset Info Type Sym.Value Sym. Name
08049ff0 00000106 R_386_GLOB_DAT 00000000 __gmon_start__
Relocation section '.rel.plt' at offset 0x284 contains 2 entries:
Offset Info Type Sym.Value Sym. Name
0804a000 00000107 R_386_JUMP_SLOT 00000000 __gmon_start__
0804a004 00000207 R_386_JUMP_SLOT 00000000 __libc_start_main
PIE:
$ readelf -r fPIE
Relocation section '.rel.dyn' at offset 0x388 contains 6 entries:
Offset Info Type Sym.Value Sym. Name
00001fe8 00000008 R_386_RELATIVE
00001ff0 00000008 R_386_RELATIVE
00002010 00000008 R_386_RELATIVE
00001fe0 00000106 R_386_GLOB_DAT 00000000 __gmon_start__
00001fe4 00000206 R_386_GLOB_DAT 00000000 _Jv_RegisterClasses
00001fec 00000406 R_386_GLOB_DAT 00000000 __cxa_finalize
Relocation section '.rel.plt' at offset 0x3b8 contains 3 entries:
Offset Info Type Sym.Value Sym. Name
00002000 00000107 R_386_JUMP_SLOT 00000000 __gmon_start__
00002004 00000307 R_386_JUMP_SLOT 00000000 __libc_start_main
00002008 00000407 R_386_JUMP_SLOT 00000000 __cxa_finalize