Skip to main content
Tweeted twitter.com/#!/StackReverseEng/status/537029532159864832
deleted 10 characters in body
Source Link
Zach Riggle
  • 2.4k
  • 1
  • 16
  • 28

When linking a binary with -Wl,-z,relro,-z,now, all relocations are performed at start-up before passing control to the binary.

Because of this, there is no need for the .got.plt segment. Normally, a pointer to the linker's link_map structure is stored in this segment.

When compiled with full RELRO, where, if anywhere, can a copy of the link_map be obtained without consulting other loaded libraries, or libdl?

The place one would expect it to be -- in the segment marked with the tag DT_PLTGOT -- it does not appear. Instead, there's just a link back to Program Header of type PT_DYNAMIC. The slot in the segment marked DT_GOTPLT starts with the offset of the DYNAMIC section, and does not contain any pointers to the link map.

Headers

$ readelf -a amd64-pwntest-relro | egrep -i '(_dynamic|pltgot)'
 0x0000000000000003 (PLTGOT)             0x202eb8
    48: 0000000000202ca8     0 OBJECT  LOCAL  DEFAULT   21 _DYNAMIC

Binary is RELRO

$ checksec.sh --file amd64-relro
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FILE
Full RELRO      No canary found   NX disabled   PIE enabled     No RPATH   No RUNPATH   amd64-relro

GDB shows that the data at the specified offset, at runtime, does not contain a link map pointer.

$ gdb ./amd64-relro
gdb-peda$ start
gdb-peda$ gdb-peda$ vmmap relro
Start              End                Perm      Name
0x0000555555554000 0x0000555555556000 r-xp      /home/user/pwntools-regression/src/amd64-relro
0x0000555555756000 0x0000555555757000 r-xp      /home/user/pwntools-regression/src/amd64-relro
0x0000555555757000 0x0000555555758000 rwxp      /home/user/pwntools-regression/src/amd64-relro
gdb-peda$ telescope 0x0000555555554000+0x202eb8 5
00:0000|  0x555555756eb8 --> 0x202ca8 
01:0008|  0x555555756ec0 --> 0x0 
02:0016|  0x555555756ec8 --> 0x0 
03:0024|  0x555555756ed0 --> 0x7ffff7675870 (<__GI___libc_free>:        mov    rax,QWORD PTR [rip+0x33b671]        # 0x7ffff79b0ee8)
04:0032|  0x555555756ed8 --> 0x7ffff79c0430 (<__pthread_create_2_1>:    push   rbp)

When linking a binary with -Wl,-z,relro,-z,now, all relocations are performed at start-up before passing control to the binary.

Because of this, there is no need for the .got.plt segment. Normally, a pointer to the linker's link_map structure is stored in this segment.

When compiled with full RELRO, where, if anywhere, can a copy of the link_map be obtained without consulting other loaded libraries, or libdl?

The place one would expect it to be -- in the segment marked with the tag DT_PLTGOT -- it does not appear. Instead, there's just a link back to Program Header of type PT_DYNAMIC. The slot in the segment marked DT_GOTPLT starts with the offset of the DYNAMIC section, and does not contain any pointers to the link map.

Headers

$ readelf -a amd64-pwntest-relro | egrep -i '(_dynamic|pltgot)'
 0x0000000000000003 (PLTGOT)             0x202eb8
    48: 0000000000202ca8     0 OBJECT  LOCAL  DEFAULT   21 _DYNAMIC

Binary is RELRO

$ checksec.sh --file amd64-relro
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FILE
Full RELRO      No canary found   NX disabled   PIE enabled     No RPATH   No RUNPATH   amd64-relro

GDB shows that the data at the specified offset, at runtime, does not contain a link map pointer.

$ gdb ./amd64-relro
gdb-peda$ start
gdb-peda$ gdb-peda$ vmmap relro
Start              End                Perm      Name
0x0000555555554000 0x0000555555556000 r-xp      /home/user/pwntools-regression/src/amd64-relro
0x0000555555756000 0x0000555555757000 r-xp      /home/user/pwntools-regression/src/amd64-relro
0x0000555555757000 0x0000555555758000 rwxp      /home/user/pwntools-regression/src/amd64-relro
gdb-peda$ telescope 0x0000555555554000+0x202eb8 5
00:0000|  0x555555756eb8 --> 0x202ca8 
01:0008|  0x555555756ec0 --> 0x0 
02:0016|  0x555555756ec8 --> 0x0 
03:0024|  0x555555756ed0 --> 0x7ffff7675870 (<__GI___libc_free>:        mov    rax,QWORD PTR [rip+0x33b671]        # 0x7ffff79b0ee8)
04:0032|  0x555555756ed8 --> 0x7ffff79c0430 (<__pthread_create_2_1>:    push   rbp)

When linking a binary with -Wl,-z,relro,-z,now, all relocations are performed at start-up before passing control to the binary.

Because of this, there is no need for the .got.plt segment. Normally, a pointer to the linker's link_map structure is stored in this segment.

When compiled with full RELRO, where, if anywhere, can a copy of the link_map be obtained without consulting other loaded libraries, or libdl?

The place one would expect it to be -- in the segment marked with the tag DT_PLTGOT -- it does not appear. Instead, there's just a link back to Program Header of type PT_DYNAMIC. The slot in the segment marked DT_GOTPLT starts with the offset of the DYNAMIC section, and does not contain any pointers to the link map.

Headers

$ readelf -a amd64-pwntest-relro | egrep -i '(_dynamic|pltgot)'
 0x0000000000000003 (PLTGOT)             0x202eb8
    48: 0000000000202ca8     0 OBJECT  LOCAL  DEFAULT   21 _DYNAMIC

Binary is RELRO

$ checksec.sh --file amd64-relro
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FILE
Full RELRO      No canary found   NX disabled   PIE enabled     No RPATH   No RUNPATH   amd64-relro

GDB shows that the data at the specified offset, at runtime, does not contain a link map pointer.

$ gdb ./amd64-relro
gdb-peda$ start
gdb-peda$ vmmap relro
Start              End                Perm      Name
0x0000555555554000 0x0000555555556000 r-xp      /home/user/pwntools-regression/src/amd64-relro
0x0000555555756000 0x0000555555757000 r-xp      /home/user/pwntools-regression/src/amd64-relro
0x0000555555757000 0x0000555555758000 rwxp      /home/user/pwntools-regression/src/amd64-relro
gdb-peda$ telescope 0x0000555555554000+0x202eb8 5
00:0000|  0x555555756eb8 --> 0x202ca8 
01:0008|  0x555555756ec0 --> 0x0 
02:0016|  0x555555756ec8 --> 0x0 
03:0024|  0x555555756ed0 --> 0x7ffff7675870 (<__GI___libc_free>:        mov    rax,QWORD PTR [rip+0x33b671]        # 0x7ffff79b0ee8)
04:0032|  0x555555756ed8 --> 0x7ffff79c0430 (<__pthread_create_2_1>:    push   rbp)
Source Link
Zach Riggle
  • 2.4k
  • 1
  • 16
  • 28

ELF link_map when linked as RELRO

When linking a binary with -Wl,-z,relro,-z,now, all relocations are performed at start-up before passing control to the binary.

Because of this, there is no need for the .got.plt segment. Normally, a pointer to the linker's link_map structure is stored in this segment.

When compiled with full RELRO, where, if anywhere, can a copy of the link_map be obtained without consulting other loaded libraries, or libdl?

The place one would expect it to be -- in the segment marked with the tag DT_PLTGOT -- it does not appear. Instead, there's just a link back to Program Header of type PT_DYNAMIC. The slot in the segment marked DT_GOTPLT starts with the offset of the DYNAMIC section, and does not contain any pointers to the link map.

Headers

$ readelf -a amd64-pwntest-relro | egrep -i '(_dynamic|pltgot)'
 0x0000000000000003 (PLTGOT)             0x202eb8
    48: 0000000000202ca8     0 OBJECT  LOCAL  DEFAULT   21 _DYNAMIC

Binary is RELRO

$ checksec.sh --file amd64-relro
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FILE
Full RELRO      No canary found   NX disabled   PIE enabled     No RPATH   No RUNPATH   amd64-relro

GDB shows that the data at the specified offset, at runtime, does not contain a link map pointer.

$ gdb ./amd64-relro
gdb-peda$ start
gdb-peda$ gdb-peda$ vmmap relro
Start              End                Perm      Name
0x0000555555554000 0x0000555555556000 r-xp      /home/user/pwntools-regression/src/amd64-relro
0x0000555555756000 0x0000555555757000 r-xp      /home/user/pwntools-regression/src/amd64-relro
0x0000555555757000 0x0000555555758000 rwxp      /home/user/pwntools-regression/src/amd64-relro
gdb-peda$ telescope 0x0000555555554000+0x202eb8 5
00:0000|  0x555555756eb8 --> 0x202ca8 
01:0008|  0x555555756ec0 --> 0x0 
02:0016|  0x555555756ec8 --> 0x0 
03:0024|  0x555555756ed0 --> 0x7ffff7675870 (<__GI___libc_free>:        mov    rax,QWORD PTR [rip+0x33b671]        # 0x7ffff79b0ee8)
04:0032|  0x555555756ed8 --> 0x7ffff79c0430 (<__pthread_create_2_1>:    push   rbp)