Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fail to generate xref from position in .data to .rodata #4751

Open
PeiweiHu opened this issue Nov 28, 2024 · 4 comments
Open

Fail to generate xref from position in .data to .rodata #4751

PeiweiHu opened this issue Nov 28, 2024 · 4 comments
Labels
bug Something isn't working RzAnalysis test-required

Comments

@PeiweiHu
Copy link
Contributor

For the binary generated by the following code (-O0):

char *global_data = "1000";

int main() {
    printf("In main, global_data: %s\n", global_data);
    return 0;
}

The variable global_data is in 0x4010.
The string "1000" is in 0x2004.
There should be an XREF from 0x4010 to 0x2004, but rizin fails to capture this (while ida and binary ninja does).

Work environment

Questions Answers
OS/arch/bits (mandatory) Ubuntu x64
File format of the file you reverse (mandatory) ELF
Architecture/bits of the file (mandatory) x86/64
rizin -v full output, not truncated (mandatory) latest version

Expected behavior

An xref from 0x4010 to 0x2004.

Actual behavior

after running aaa and axl, the expected xref doesn't appear. The following is the result of axl.

section..init+8 0x1008 ->      DATA -> 0x3fe8 reloc.__gmon_start
                          section..plt+6 0x1026 ->      CODE -> 0x3fc8 section..got+16
                         section..plt+25 0x1039 ->      CODE -> 0x1020 section..plt
                      section..plt.got+4 0x1044 ->      CODE -> 0x3ff8 reloc.__cxa_finalize
                      section..plt.sec+4 0x1054 ->      CODE -> 0x3fd0 reloc.printf
                               entry0+19 0x1073 ->      DATA -> 0x11f0 sym.__libc_csu_fini
                               entry0+26 0x107a ->      DATA -> 0x1180 sym.__libc_csu_init
                               entry0+33 0x1081 ->      DATA -> 0x1149 main
                               entry0+40 0x1088 ->      CALL -> 0x3fe0 reloc.__libc_start_main
                sym.deregister_tm_clones 0x1090 ->      DATA -> 0x4018 section..bss
              sym.deregister_tm_clones+7 0x1097 ->      DATA -> 0x4018 section..bss
             sym.deregister_tm_clones+19 0x10a3 ->      DATA -> 0x3fd8 reloc._ITM_deregisterTMCloneTable
                  sym.register_tm_clones 0x10c0 ->      DATA -> 0x4018 section..bss
                sym.register_tm_clones+7 0x10c7 ->      DATA -> 0x4018 section..bss
               sym.register_tm_clones+36 0x10e4 ->      DATA -> 0x3ff0 reloc._ITM_registerTMCloneTable
                           entry.fini0+4 0x1104 ->      DATA -> 0x4018 section..bss
                          entry.fini0+14 0x110e ->      DATA -> 0x3ff8 reloc.__cxa_finalize
                          entry.fini0+27 0x111b ->      DATA -> 0x4008 obj.__dso_handle
                          entry.fini0+34 0x1122 ->      CALL -> 0x1040 section..plt.got
                          entry.fini0+39 0x1127 ->      CALL -> 0x1090 sym.deregister_tm_clones
                          entry.fini0+44 0x112c ->      DATA -> 0x4018 section..bss
                           entry.init0+4 0x1144 ->      CODE -> 0x10c0 sym.register_tm_clones
                                  main+8 0x1151 ->      DATA -> 0x4010 obj.global_data
                                 main+18 0x115b ->      DATA -> 0x2009 str.In_main__global_data:__s
                                 main+30 0x1167 ->      CALL -> 0x1050 section..plt.sec
                   sym.__libc_csu_init+6 0x1186 ->      DATA -> 0x3db8 section..init_array
                  sym.__libc_csu_init+29 0x119d ->      DATA -> 0x3dc0 section..fini_array
                  sym.__libc_csu_init+44 0x11ac ->      CALL -> 0x1000 section..init
                  sym.__libc_csu_init+73 0x11c9 ->      CALL -> 0x0 segment.LOAD0
                    section..eh_frame+56 0x20a0 ->      DATA -> 0xff segment.PHDR+191
                    section..eh_frame+75 0x20b3 ->      DATA -> 0x3f segment.LOAD0+63
                    section..eh_frame+82 0x20ba ->      DATA -> 0x22 segment.LOAD0+34

But it seems rizin does related analysis since in 0x1151 we can see comment 0x2004 str.1000. Why xref is not created?

[0x00001149]> pdf
            ; DATA XREF from entry0 @ 0x1081
┌ int main(int argc, char **argv, char **envp);
│           0x00001149      endbr64
│           0x0000114d      push  rbp
│           0x0000114e      mov   rbp, rsp
│           0x00001151      mov   rax, qword [obj.global_data]         ; [0x4010:8]=0x2004 str.1000
│           0x00001158      mov   rsi, rax
│           0x0000115b      lea   rdi, str.In_main__global_data:__s    ; 0x2009 ; "In main, global_data: %s\n" ; const char *format
│           0x00001162      mov   eax, 0
│           0x00001167      call  sym.imp.printf                       ; sym.imp.printf ; int printf(const char *format)
│           0x0000116c      mov   eax, 0
│           0x00001171      pop   rbp
└           0x00001172      ret

Steps to reproduce the behavior

  • rizin demo
  • aaa
  • s 0x2004

Additional Logs, screenshots, source code, configuration dump, ...

demo.zip

Drag and drop zip archives containing the Additional info here, don't use external services or link.

@Rot127 Rot127 added bug Something isn't working RzAnalysis labels Nov 28, 2024
@imbillow
Copy link
Contributor

[0x00001060]> iS
paddr      size  vaddr      vsize align perm name               type       flags         
-----------------------------------------------------------------------------------------
0x00000000 0x0   ---------- 0x0   0x0   ----                    NULL       
0x00000318 0x1c  0x00000318 0x1c  0x0   -r-- .interp            PROGBITS   alloc
0x00000338 0x20  0x00000338 0x20  0x0   -r-- .note.gnu.property NOTE       alloc
0x00000358 0x24  0x00000358 0x24  0x0   -r-- .note.gnu.build-id NOTE       alloc
0x0000037c 0x20  0x0000037c 0x20  0x0   -r-- .note.ABI-tag      NOTE       alloc
0x000003a0 0x24  0x000003a0 0x24  0x0   -r-- .gnu.hash          GNU_HASH   alloc
0x000003c8 0xa8  0x000003c8 0xa8  0x0   -r-- .dynsym            DYNSYM     alloc
0x00000470 0x84  0x00000470 0x84  0x0   -r-- .dynstr            STRTAB     alloc
0x000004f4 0xe   0x000004f4 0xe   0x0   -r-- .gnu.version       VERSYM     alloc
0x00000508 0x20  0x00000508 0x20  0x0   -r-- .gnu.version_r     VERNEED    alloc
0x00000528 0xd8  0x00000528 0xd8  0x0   -r-- .rela.dyn          RELA       alloc
0x00000600 0x18  0x00000600 0x18  0x0   -r-- .rela.plt          RELA       alloc,info
0x00001000 0x1b  0x00001000 0x1b  0x0   -r-x .init              PROGBITS   alloc,execute
0x00001020 0x20  0x00001020 0x20  0x0   -r-x .plt               PROGBITS   alloc,execute
0x00001040 0x10  0x00001040 0x10  0x0   -r-x .plt.got           PROGBITS   alloc,execute
0x00001050 0x10  0x00001050 0x10  0x0   -r-x .plt.sec           PROGBITS   alloc,execute
0x00001060 0x195 0x00001060 0x195 0x0   -r-x .text              PROGBITS   alloc,execute
0x000011f8 0xd   0x000011f8 0xd   0x0   -r-x .fini              PROGBITS   alloc,execute
0x00002000 0x23  0x00002000 0x23  0x0   -r-- .rodata            PROGBITS   alloc
0x00002024 0x44  0x00002024 0x44  0x0   -r-- .eh_frame_hdr      PROGBITS   alloc
0x00002068 0x108 0x00002068 0x108 0x0   -r-- .eh_frame          PROGBITS   alloc
0x00002db8 0x8   0x00003db8 0x8   0x0   -rw- .init_array        INIT_ARRAY write,alloc
0x00002dc0 0x8   0x00003dc0 0x8   0x0   -rw- .fini_array        FINI_ARRAY write,alloc
0x00002dc8 0x1f0 0x00003dc8 0x1f0 0x0   -rw- .dynamic           DYNAMIC    write,alloc
0x00002fb8 0x48  0x00003fb8 0x48  0x0   -rw- .got               PROGBITS   write,alloc
0x00003000 0x18  0x00004000 0x18  0x0   -rw- .data              PROGBITS   write,alloc
0x00003018 0x0   0x00004018 0x8   0x0   -rw- .bss               NOBITS     write,alloc
0x00003018 0x2b  ---------- 0x2b  0x0   ---- .comment           PROGBITS   merge,strings
0x00003048 0x630 ---------- 0x630 0x0   ---- .symtab            SYMTAB     
0x00003678 0x210 ---------- 0x210 0x0   ---- .strtab            STRTAB     
0x00003888 0x11a ---------- 0x11a 0x0   ---- .shstrtab          STRTAB     
[0x00001060]> avgl?
Usage: avgl[jqt] [<var_name>]   # show/list global variables
| avgl [<var_name>]       # show/list global variables
| avglj [<var_name>]      # show/list global variables (JSON mode)
| avglq [<var_name>]      # show/list global variables (quiet mode)
| avglt [<var_name>]      # show/list global variables (table mode)
[0x00001060]> avgl
[0x00001060]> id
[0x00001060]> 

There is no section for dwarf (“.debug_*”, compiled with the -g option), so no global variables will be loaded from dwarf, rizin has no information about global variables.

@imbillow
Copy link
Contributor

with debuginfo the output looks like this, not quite sure if it is as expected?

[0x100003f38]> pdf
            ; UNKNOWN XREF from aav.0x100000020 @ +0xb0
            ;-- main:
            ;-- entry0:
            ;-- section.0.__TEXT.__text:
            ;-- _main:
            ;-- func.100003f38:
            ;-- pc:
┌ int main()
│           ; var int64_t arg1 @ x0
│           ; var int64_t var_20h @ stack - 0x20
│           ; var int64_t var_18h @ stack - 0x18
│           ; var int64_t var_14h @ stack - 0x14
│           ; var int64_t var_10h @ stack - 0x10
│           ; var int64_t var_8h @ stack - 0x8
│           0x100003f38      sub   sp, sp, 0x20                        ; demo.c:4 int main() { ; [00] -r-x section size 68 named 0.__TEXT.__text
│           0x100003f3c      stp   fp, lr, [var_10h]
│           0x100003f40      add   fp, sp, 0x10
│           0x100003f44      mov   w8, 0
│           0x100003f48      str   w8, [var_18h]
│           0x100003f4c      stur  wzr, [var_14h]                      ; arg1
│           0x100003f50      adrp  x8, sym._global_data                ; demo.c:5 printf("In main, global_data: %s\n", global_data); ; 0x100008000
│           0x100003f54      ldr   x8, [x8]                            ; [0x100003f88:4]=0x30303031 ; "1000"
│           0x100003f58      mov   x9, sp
│           0x100003f5c      str   x8, [x9]
│           0x100003f60      adrp  x0, data.100003000                  ; 0x100003000
│           0x100003f64      add   x0, x0, 0xf8d                       ; 0x100003f8d ; "In main, global_data: %s\n" ; const char *format
│           0x100003f68      bl    sym.imp.printf                      ; sym.imp.printf ; int printf(const char *format)
│           0x100003f6c      ldr   w0, [var_18h]                       ; [0x8:4]=-1 ; 8
│           0x100003f70      ldp   fp, lr, [var_10h]                   ; demo.c:6 return 0;
│           0x100003f74      add   sp, sp, 0x20                        ; 0x178000
└           0x100003f78      ret
[0x100003f38]> avgl
global char * global_data @ 0x100008000
[0x100003f38]> axl
                      aav.0x100000020+32 0x100000040 ->   UNKNOWN -> 0x100000000 segment.TEXT
                      aav.0x100000020+96 0x100000080 ->   UNKNOWN -> 0x100000000 segment.TEXT
                     aav.0x100000020+176 0x1000000d0 ->   UNKNOWN -> 0x100003f38 main
                     aav.0x100000020+256 0x100000120 ->   UNKNOWN -> 0x100003f7c section.1.__TEXT.__stubs
                     aav.0x100000020+336 0x100000170 ->   UNKNOWN -> 0x100003f88 str.1000
                     aav.0x100000020+416 0x1000001c0 ->   UNKNOWN -> 0x100003fa8 section.3.__TEXT.__unwind_info
                     aav.0x100000020+488 0x100000208 ->   UNKNOWN -> 0x100004000 segment.DATA_CONST
                     aav.0x100000020+568 0x100000258 ->   UNKNOWN -> 0x100004000 segment.DATA_CONST
                     aav.0x100000020+820 0x100000354 ->   UNKNOWN -> 0x100000000 segment.TEXT
                    aav.0x100000020+1036 0x10000042c ->   UNKNOWN -> 0x100000020 aav.0x100000020
                                  main+8 0x100003f40 ->      DATA -> 0x177ff0 x0+1540080
                                 main+24 0x100003f50 ->    STRING -> 0x100008000 global_data
                                 main+28 0x100003f54 ->      DATA -> 0x100003f88 str.1000
                                 main+28 0x100003f54 ->      DATA -> 0x100008000 global_data
                                 main+32 0x100003f58 ->      DATA -> 0x177fe0 x0+1540064
                                 main+40 0x100003f60 ->      DATA -> 0x100003000 data.100003000
                                 main+44 0x100003f64 ->      DATA -> 0x100003f8d str.In_main__global_data:__s
                                 main+48 0x100003f68 ->      CALL -> 0x100003f7c section.1.__TEXT.__stubs
                                 main+52 0x100003f6c ->      DATA -> 0x177fe8 x0+1540072
                                 main+56 0x100003f70 ->      DATA -> 0x177ff0 x0+1540080
                                 main+56 0x100003f70 ->      DATA -> 0x177ff8 x0+1540088
                                 main+60 0x100003f74 ->      DATA -> 0x178000 x29
                section.1.__TEXT.__stubs 0x100003f7c ->    STRING -> 0x100004000 segment.DATA_CONST
              section.1.__TEXT.__stubs+4 0x100003f80 ->      DATA -> 0x100004000 segment.DATA_CONST
              section.1.__TEXT.__stubs+4 0x100003f80 ->      DATA -> 0x100010008 reloc.target.printf
              section.1.__TEXT.__stubs+8 0x100003f84 ->      CODE -> 0x100010008 reloc.target.printf

@PeiweiHu
Copy link
Contributor Author

PeiweiHu commented Nov 29, 2024

@imbillow Thanks for your comments. I am a little bit confused about why capturing the xref from 0x4010 to 0x2004 requires dwarf information. For the same binary without debug info, ida and binary ninja can capture this xref.

Do you mean the areas for global variables will not be analyzed if there is no debug info? Thanks again.

@XVilka
Copy link
Member

XVilka commented Nov 29, 2024

Do you mean the areas for global variables will not be analyzed if there is no debug info? Thanks again.

They will but not in all cases, and this one is apparently isn't covered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working RzAnalysis test-required
Projects
None yet
Development

No branches or pull requests

4 participants