LINUX.ORG.RU

История изменений

Исправление mv, (текущая версия) :

Этот код выводит адрес в plt в исполняемом файле. Мне нужен реальный адрес printf, там, куда ld.so загрузил libc. Как?

Если переносимость между архитектурами не нужна, то по тому адресу находится один джамп с нужным тебе адресом. Правда, не адрес, а смещение с текущего места (следующая инструкция), но он тебе ведь известен.

printf address: 0x4004d0
(gdb) disas 0x4004d0
Dump of assembler code for function printf@plt:
   0x00000000004004d0 <+0>:	jmpq   *0x200b52(%rip)        # 0x601028
   0x00000000004004d6 <+6>:	pushq  $0x2
   0x00000000004004db <+11>:	jmpq   0x4004a0
End of assembler dump.
0x4004d0 <printf@plt>:	0xff	0x25	0x52	0x0b	0x20	0x00	0x68	0x02

0x200b52 + 0x4004d6 = 0x601028

Ой, то есть, это будет указатель на global offset table, и вот уже там-то будет указатель на printf:

(gdb) x/g 0x601028
0x601028:	0x00007ffff7a61230
(gdb) disas 0x00007ffff7a61230
Dump of assembler code for function printf:
   0x00007ffff7a61230 <+0>:	sub    $0xd8,%rsp
   0x00007ffff7a61237 <+7>:	test   %al,%al
   0x00007ffff7a61239 <+9>:	mov    %rsi,0x28(%rsp)
   0x00007ffff7a6123e <+14>:	mov    %rdx,0x30(%rsp)
   0x00007ffff7a61243 <+19>:	mov    %rcx,0x38(%rsp)
   0x00007ffff7a61248 <+24>:	mov    %r8,0x40(%rsp)
   0x00007ffff7a6124d <+29>:	mov    %r9,0x48(%rsp)
   0x00007ffff7a61252 <+34>:	je     0x7ffff7a6128b <printf+91>
   0x00007ffff7a61254 <+36>:	movaps %xmm0,0x50(%rsp)
   0x00007ffff7a61259 <+41>:	movaps %xmm1,0x60(%rsp)
   0x00007ffff7a6125e <+46>:	movaps %xmm2,0x70(%rsp)
   0x00007ffff7a61263 <+51>:	movaps %xmm3,0x80(%rsp)
   0x00007ffff7a6126b <+59>:	movaps %xmm4,0x90(%rsp)
   0x00007ffff7a61273 <+67>:	movaps %xmm5,0xa0(%rsp)
   0x00007ffff7a6127b <+75>:	movaps %xmm6,0xb0(%rsp)
   0x00007ffff7a61283 <+83>:	movaps %xmm7,0xc0(%rsp)
   0x00007ffff7a6128b <+91>:	lea    0xe0(%rsp),%rax
   0x00007ffff7a61293 <+99>:	mov    %rdi,%rsi
   0x00007ffff7a61296 <+102>:	lea    0x8(%rsp),%rdx
   0x00007ffff7a6129b <+107>:	mov    %rax,0x10(%rsp)
   0x00007ffff7a612a0 <+112>:	lea    0x20(%rsp),%rax
   0x00007ffff7a612a5 <+117>:	movl   $0x8,0x8(%rsp)
   0x00007ffff7a612ad <+125>:	movl   $0x30,0xc(%rsp)
   0x00007ffff7a612b5 <+133>:	mov    %rax,0x18(%rsp)
   0x00007ffff7a612ba <+138>:	mov    0x372c7f(%rip),%rax        # 0x7ffff7dd3f40
   0x00007ffff7a612c1 <+145>:	mov    (%rax),%rdi
   0x00007ffff7a612c4 <+148>:	callq  0x7ffff7a56430 <vfprintf>
   0x00007ffff7a612c9 <+153>:	add    $0xd8,%rsp
   0x00007ffff7a612d0 <+160>:	retq   
End of assembler dump.

Исходная версия mv, :

Этот код выводит адрес в plt в исполняемом файле. Мне нужен реальный адрес printf, там, куда ld.so загрузил libc. Как?

Если переносимость между архитектурами не нужна, то по тому адресу находится один джамп с нужным тебе адресом. Правда, не адрес, а смещение с текущего места (следующая инструкция), но он тебе ведь известен.

printf address: 0x4004d0
(gdb) disas 0x4004d0
Dump of assembler code for function printf@plt:
   0x00000000004004d0 <+0>:	jmpq   *0x200b52(%rip)        # 0x601028
   0x00000000004004d6 <+6>:	pushq  $0x2
   0x00000000004004db <+11>:	jmpq   0x4004a0
End of assembler dump.
0x4004d0 <printf@plt>:	0xff	0x25	0x52	0x0b	0x20	0x00	0x68	0x02

0x200b52 + 0x4004d6 = 0x601028