radareorg / radare2

UNIX-like reverse engineering framework and command-line toolset
https://www.radare.org/
GNU Lesser General Public License v3.0
20.4k stars 2.98k forks source link

Inform within disassembler on the performed direct relocations with addend #17589

Open cpey opened 4 years ago

cpey commented 4 years ago

Situation The disassembler does not inform on the relocations performed when type is R_X86_64_32S with a non-null addend.

In the test.ko there is a relocation for kmalloc_caches + 0x460. The .text gets patched correctly but there is no visual indication in the disassembly. asm.comments does not provide such information either. See the patched relocation for kmalloc_caches at the address 0x08000094:

┌ 44: sym.test_init ();
│           0x0800007c      e88e0a0000     call __fentry__             ;[1]; RELOC 64 init_module @ 0x0800007c ; [04] -r-x section size 44 named .init.text ; rsp=0xfffffffffffffff
│           0x08000081      55             push rbp                    ; rsp=0xfffffffffffffff0
│           0x08000082      48c7c7ba0000.  mov rdi, reloc..rodata.str1.1    ; 0x80000ba ; "Hello World\n" ; rdi=0x80000ba -> 0x6c6c6548 sym..rodata.str1.1
│           0x08000089      4889e5         mov rbp, rsp                ; rbp=0xfffffffffffffff0
│           0x0800008c      e8860a0000     call printk                 ;[2] ; rsp=0xffffffffffffffe8 ; rip=0x8000b17 reloc.printk ; reloc.printk(0x80000ba, 0x0, 0x0, 0x0)
│           0x08000091      48c7c67f0f00.  mov rsi, 0x8000f7f          ; rsi=0x8000f7f
│           0x08000098      48c7c7c70000.  mov rdi, str.val:__p        ; 0x80000c7 ; "val: %p\n" ; rdi=0x80000c7 -> 0x3a6c6176
│           0x0800009f      e8730a0000     call printk                 ;[2] ; rsp=0xffffffffffffffe0 ; rip=0x8000b17 reloc.printk ; reloc.printk(0x80000c7, 0x8000f7f, 0x0, 0x0)
│           0x080000a4      31c0           xor eax, eax                ; rax=0x0 ; zf=0x1 ; pf=0x1 ; sf=0x0 ; cf=0x0 ; of=0x0
│           0x080000a6      5d             pop rbp                     ; rbp=0xffffffffffffffff ; rsp=0xffffffffffffffe8
└           0x080000a7      c3             ret                         ; rip=0xffffffffffffffff ; rsp=0xfffffffffffffff0

Proposal A way to directly find out the operand corresponds to the result of a relocation. Any of the already existing mechanisms would be fine.

The information is present when -e io.cache=false:

┌ 44: sym.test_init ();
│           0x0800007c      e800000000     call __fentry__             ;[1]; RELOC 32 __fentry__ ; [04] -r-x section si
│           ; CALL XREF from sym.test_init @ 0x800007c
│           0x08000081      55             push rbp
│           0x08000082      48c7c7000000.  mov rdi, 0                  ; RELOC 32 .rodata.str1.1 @ 0x080000ba
│           0x08000089      4889e5         mov rbp, rsp
│           0x0800008c      e800000000     call printk                 ;[2]; RELOC 32 printk
│           ; CALL XREF from sym.test_init @ 0x800008c
│           0x08000091      48c7c6000000.  mov rsi, 0                  ; RELOC 32 kmalloc_caches
│           0x08000098      48c7c7000000.  mov rdi, 0                  ; RELOC 32 .rodata.str1.1 @ 0x080000ba + 0xd
│           0x0800009f      e800000000     call printk                 ;[3]; RELOC 32 printk
│           ; CALL XREF from sym.test_init @ 0x800009f
│           0x080000a4      31c0           xor eax, eax
│           0x080000a6      5d             pop rbp
└           0x080000a7      c3             ret

This is working as expected as well when the addend is 0 (test_no_addend.ko.zip):

┌ 44: sym.test_init ();
│           0x0800007c      e8860a0000     call __fentry__             ;[1]; RELOC 64 init_module @ 0x0800007c ; [04] -r-x section size 44 named .init.text ; rsp=0xfffffffffffffff8 ; rip=0x8000b07 reloc.__fentry ; reloc.__fentry(0x0, 0x0,
│           0x08000081      55             push rbp                    ; rsp=0xfffffffffffffff0
│           0x08000082      48c7c7ba0000.  mov rdi, reloc..rodata.str1.1    ; 0x80000ba ; "Hello World\n" ; rdi=0x80000ba -> 0x6c6c6548 sym..rodata.str1.1
│           0x08000089      4889e5         mov rbp, rsp                ; rbp=0xfffffffffffffff0
│           0x0800008c      e87e0a0000     call printk                 ;[2] ; rsp=0xffffffffffffffe8 ; rip=0x8000b0f reloc.printk ; reloc.printk(0x80000ba, 0x0, 0x0, 0x0)
│           0x08000091      48c7c6170b00.  mov rsi, reloc.kmalloc_caches    ; 0x8000b17 ; rsi=0x8000b17
│           0x08000098      48c7c7c70000.  mov rdi, str.val:__p        ; 0x80000c7 ; "val: %p\n" ; rdi=0x80000c7 -> 0x3a6c6176
│           0x0800009f      e86b0a0000     call printk                 ;[2] ; rsp=0xffffffffffffffe0 ; rip=0x8000b0f reloc.printk ; reloc.printk(0x80000c7, 0x8000b17, 0x0, 0x0)
│           0x080000a4      31c0           xor eax, eax                ; rax=0x0 ; zf=0x1 ; pf=0x1 ; sf=0x0 ; cf=0x0 ; of=0x0
│           0x080000a6      5d             pop rbp                     ; rbp=0xffffffffffffffff ; rsp=0xffffffffffffffe8
└           0x080000a7      c3             ret                         ; rip=0xffffffffffffffff ; rsp=0xfffffffffffffff0
ret2libc commented 4 years ago

I do not think this is only about R_X86_64_32S. Even printk does not tell me that it was relocated. image

I think that's just because once the relocation is applied, that is not shown anymore.