radare2 icon indicating copy to clipboard operation
radare2 copied to clipboard

Defining a block with a pre-existing format (via dF) is broken when using visual mode

Open OhioDuckFarmer opened this issue 6 years ago • 2 comments

It looks like the defining a block with a pre-existing format is broken when using visual mode. More specifically, when applying a previously defined format to a block of data the length of the format is not being calculated properly. Rather than the actual defined length being used the length of the format string is being used (eg. in the below example the structure defined structure size for cpio_image_header is being set to 21 rather than 111) which causes an improper amount of bytes to be consumed when displayed.

Work environment

Q01) OS/arch/bits A01) ULinux 4.4.0-112-generic #135-Ubuntu SMP Fri Jan 19 11:48:36 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

Q02) File format of the file you reverse A02) CPIO Archive "newc"

Q03) Architecture/bits of the file A03) RAW

Q04A) r2 -v full output Q04B) r2 -V full output A04AB) https://gist.github.com/OhioDuckFarmer/ce2bfb729252e79cd89e9539a66cc94c.js

Expected behavior

When applying a defined format to a block of bytes in visual mode both the proper size of the format should be displayed along with the correct amount of bytes being consumed by the format:

    [0x00000000 0% 316 cpio_image.bin]> pd $r
                0x00000000 format cpio_image_header {
        c_magic : 0x00000000 = [ '0', '7', '0', '7', '0', '1' ]
          c_ino : 0x00000006 = [ '0', '0', '0', '0', '0', '2', 'D', '1' ]
         c_mode : 0x0000000e = [ '0', '0', '0', '0', '4', '1', 'E', 'D' ]
          c_uid : 0x00000016 = [ '0', '0', '0', '0', '0', '3', 'E', '9' ]
          c_gid : 0x0000001e = [ '0', '0', '0', '0', '0', '3', 'E', '9' ]
        c_nlink : 0x00000026 = [ '0', '0', '0', '0', '0', '0', '0', '2' ]
        c_mtime : 0x0000002e = [ '5', '8', '1', '0', '9', '0', 'E', '6' ]
     c_filesize : 0x00000036 = [ '0', '0', '0', '0', '0', '0', '0', '0' ]
          c_maj : 0x0000003e = [ '0', '0', '0', '0', '0', '0', '0', '3' ]
          c_min : 0x00000046 = [ '0', '0', '0', '0', '0', '0', '0', '1' ]
         c_rmaj : 0x0000004e = [ '0', '0', '0', '0', '0', '0', '0', '0' ]
         c_rmin : 0x00000056 = [ '0', '0', '0', '0', '0', '0', '0', '0' ]
     c_namesize : 0x0000005e = [ '0', '0', '0', '0', '0', '0', '0', '5' ]
       c_chksum : 0x00000066 = [ '0', '0', '0', '0', '0', '0', '0', '0' ]
       filename : 0x0000006e = /lib
    } 116
                0x00000074      ffffffff

Actual behavior

The size of the format is being calculated from the length of the format string (including the Cf 0 portion contained within the cann to cmd_meta_hsdmf) rather than the actual length (as specified by the formatting chracters) of the format:

    [0x00000000]> pf.
    pf.cpio_image_header [6]c[8]c[8]c[8]c[8]c[8]c[8]c[8]c[8]c[8]c[8]c[8]c[8]c[8]cz c_magic c_ino c_mode c_uid c_gid c_nlink c_mtime c_filesize c_maj c_min c_rmaj c_rmin c_namesize c_chksum filename
    [0x00000000]> pfs.cpio_image_header
    111
    [0x00000000]> V

    [0x00000000 0% 3472 cpio_image.bin]> xc
    - offset -   0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF  comment
    0x00000000  3037 3037 3031 3030 3030 3032 4431 3030  070701000002D100
    0x00000010  3030 3431 4544 3030 3030 3033 4539 3030  0041ED000003E900
    0x00000020  3030 3033 4539 3030 3030 3030 3032 3538  0003E90000000258
    0x00000030  3130 3930 4536 3030 3030 3030 3030 3030  1090E60000000000
    0x00000040  3030 3030 3033 3030 3030 3030 3031 3030  0000030000000100
    0x00000050  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
    0x00000060  3030 3030 3035 3030 3030 3030 3030 2f6c  00000500000000/l
    0x00000070  6962 0000

    [0x00000000 0% 992 cpio_image.bin]> pd $r
                0x00000000      30373037       ori s0, t9, 0x3730
                0x00000004      30313030       andi s0, at, 0x3130
                0x00000008      30303032       andi s0, s1, 0x3030
                0x0000000c      44313030       andi s0, at, 0x3144
                0x00000010      30303431       andi s4, t1, 0x3030
                0x00000014      45443030       andi s0, at, 0x4445
                0x00000018      30303033       andi s0, t9, 0x3030
                0x0000001c      45393030       andi s0, at, 0x3945
                0x00000020      30303033       andi s0, t9, 0x3030
                0x00000024      45393030       andi s0, at, 0x3945
                0x00000028      30303030       andi s0, at, 0x3030
                0x0000002c      30323538       xori s5, at, 0x3230
                0x00000030      31303930       andi t9, at, 0x3031
                0x00000034      45363030       andi s0, at, 0x3645
                0x00000038      30303030       andi s0, at, 0x3030
                0x0000003c      30303030       andi s0, at, 0x3030
                0x00000040      30303030       andi s0, at, 0x3030
                0x00000044      30333030       andi s0, at, 0x3330
                0x00000048      30303030       andi s0, at, 0x3030
                0x0000004c      30313030       andi s0, at, 0x3130
                0x00000050      30303030       andi s0, at, 0x3030
                0x00000054      30303030       andi s0, at, 0x3030
                0x00000058      30303030       andi s0, at, 0x3030
                0x0000005c      30303030       andi s0, at, 0x3030
                0x00000060      30303030       andi s0, at, 0x3030
                0x00000064      30353030       andi s0, at, 0x3530
                0x00000068      30303030       andi s0, at, 0x3030
                0x0000006c      30302f6c       invalid
                0x00000070      69620000

                [Vd]- Define current block as:
                 $    define flag size
                 1    edit bits
                 b    set as byte
                 B    set as short word (2 bytes)
                 c    set as code
                 C    define flag color (fc)
                 d    set as data
                 e    end of function
                 f    analyze function
                 F    format
                 i    immediate base (b(in), o(ct), d(ec), h(ex), s(tr))
                 j    merge down (join this and next functions)
                 k    merge up (join this and previous function)
                 h    define anal hint
                 m    manpage for current call
                 n    rename flag used at cursor
                 r    rename function
                 R    find references /r
                 s    set string
                 S    set strings in current block
                 u    undefine metadata here
                 x    find xrefs to current address (./r)
                 w    set as 32bit word
                 W    set as 64bit word
                 q    quit menu
                 z    zone flag
                |pf: pf[.k[.f[=v]]|[v]]|[n]|[0|cnt][fmt] [a0 a1 ...]
                | Commands:
                | pf?                        Show this help
                | pf??                       Format characters
                | pf???                      pf usage examples
                | pf fmt                     Show data using the given format-string. See 'pf??' and 'pf???'.
                | pf.fmt_name                Show data using named format
                | pf.fmt_name.field_name     Show specific data field using named format
                | pfj fmt_name|fmt           Show data using (named) format in JSON
                | pf* fmt_name|fmt           Show data using (named) format as r2 flag create commands
                | pfd.fmt_name               Show data using named format as graphviz commands
                | pf.name [0|cnt]fmt         Define a new named format
                | pf.                        List all format definitions
                | pf?fmt_name                Show the definition of a named format
                | pfo                        List all format definition files (fdf)
                | pfo fdf_name               Load a Format Definition File (fdf)
                | pf.fmt_name.field_name=33  Set new value for the specified field in named format
                | pfv.fmt_name[.field]       Print value(s) only for named format. Useful for one-liners
                | pfs[.fmt_name| fmt]        Print the size of (named) format in bytes
                format: cpio_image_header
                [0x00000000 0% 310 cpio_image.bin]> pd $r
                            0x00000000 format cpio_image_header {
                    c_magic : 0x00000000 = [ '0', '7', '0', '7', '0', '1' ]
                      c_ino : 0x00000006 = [ '0', '0', '0', '0', '0', '2', 'D', '1' ]
                     c_mode : 0x0000000e = [ '0', '0', '0', '0', '4', '1', 'E', 'D' ]
                      c_uid : 0x00000016 = [ '0', '0', '0', '0', '0', '3', 'E', '9' ]
                      c_gid : 0x0000001e = [ '0', '0', '0', '0', '0', '3', 'E', '9' ]
                    c_nlink : 0x00000026 = [ '0', '0', '0', '0', '0', '0', '0', '2' ]
                    c_mtime : 0x0000002e = [ '5', '8', '1', '0', '9', '0', 'E', '6' ]
                 c_filesize : 0x00000036 = [ '0', '0', '0', '0', '0', '0', '0', '0' ]
                      c_maj : 0x0000003e = [ '0', '0', '0', '0', '0', '0', '0', '3' ]
                      c_min : 0x00000046 = [ '0', '0', '0', '0', '0', '0', '0', '1' ]
                     c_rmaj : 0x0000004e = [ '0', '0', '0', '0', '0', '0', '0', '0' ]
                     c_rmin : 0x00000056 = [ '0', '0', '0', '0', '0', '0', '0', '0' ]
                 c_namesize : 0x0000005e = [ '0', '0', '0', '0', '0', '0', '0', '5' ]
                   c_chksum : 0x00000066 = [ '0', '0', '0', '0', '0', '0', '0', '0' ]
                   filename : 0x0000006e = /lib
                } 21
                            0x00000015      443030         unaligned
                            0x00000016      3030           unaligned
                            0x00000017      30             unaligned
                            0x00000018      30303033       andi s0, t9, 0x3030
                            0x0000001c      45393030       andi s0, at, 0x3945
                            0x00000020      30303033       andi s0, t9, 0x3030
                            0x00000024      45393030       andi s0, at, 0x3945
                            0x00000028      30303030       andi s0, at, 0x3030
                            0x0000002c      30323538       xori s5, at, 0x3230
                            0x00000030      31303930       andi t9, at, 0x3031
                            0x00000034      45363030       andi s0, at, 0x3645
                            0x00000038      30303030       andi s0, at, 0x3030
                            0x0000003c      30303030       andi s0, at, 0x3030
                            0x00000040      30303030       andi s0, at, 0x3030
                            0x00000044      30333030       andi s0, at, 0x3330
                            0x00000048      30303030       andi s0, at, 0x3030
                            0x0000004c      30313030       andi s0, at, 0x3130
                            0x00000050      30303030       andi s0, at, 0x3030
                            0x00000054      30303030       andi s0, at, 0x3030
                            0x00000058      30303030       andi s0, at, 0x3030
                            0x0000005c      30303030       andi s0, at, 0x3030
                            0x00000060      30303030       andi s0, at, 0x3030
                            0x00000064      30353030       andi s0, at, 0x3530
                            0x00000068      30303030       andi s0, at, 0x3030
                            0x0000006c      30302f6c       invalid
                            0x00000070      69620000

Steps to reproduce the behavior

  1. Open any file for reversing
  2. Using the pf command define a named format
  3. Enter visual mode
  4. Change the print mode to disassembly
  5. Define the current offset as type (using dF command)

format_problem.zip

OhioDuckFarmer avatar Jan 30 '18 14:01 OhioDuckFarmer

This issue has been automatically marked as stale because it has not had recent activity. Considering a lot has changed since its creation, we kindly ask you to check again if the issue you reported is still relevant in the current version of radare2. If it is, update this issue with a comment, otherwise it will be automatically closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Jun 16 '20 05:06 stale[bot]

This is still wrong:

[0x00000000 [xAdvc]0 0% 220 ./cpio_image.bin]> pd $r                                                                                                                                          
            0x00000000 pf cpio_image_header # size=111                                                                                                                                        
    c_magic : 0x00000000 = [ '0', '7', '0', '7', '0', '1' ]                                                                                                                                   
      c_ino : 0x00000006 = [ '0', '0', '0', '0', '0', '2', 'D', '1' ]                                                                                                                         
     c_mode : 0x0000000e = [ '0', '0', '0', '0', '4', '1', 'E', 'D' ]                                                                                                                         
      c_uid : 0x00000016 = [ '0', '0', '0', '0', '0', '3', 'E', '9' ]                                                                                                                         
      c_gid : 0x0000001e = [ '0', '0', '0', '0', '0', '3', 'E', '9' ]                                                                                                                         
    c_nlink : 0x00000026 = [ '0', '0', '0', '0', '0', '0', '0', '2' ]                                                                                                                         
    c_mtime : 0x0000002e = [ '5', '8', '1', '0', '9', '0', 'E', '6' ]                                                                                                                         
 c_filesize : 0x00000036 = [ '0', '0', '0', '0', '0', '0', '0', '0' ]                                                                                                                         
      c_maj : 0x0000003e = [ '0', '0', '0', '0', '0', '0', '0', '3' ]                                                                                                                         
      c_min : 0x00000046 = [ '0', '0', '0', '0', '0', '0', '0', '1' ]                                                                                                                         
     c_rmaj : 0x0000004e = [ '0', '0', '0', '0', '0', '0', '0', '0' ]                                                                                                                         
     c_rmin : 0x00000056 = [ '0', '0', '0', '0', '0', '0', '0', '0' ]                                                                                                                         
 c_namesize : 0x0000005e = [ '0', '0', '0', '0', '0', '0', '0', '5' ]                                                                                                                         
   c_chksum : 0x00000066 = [ '0', '0', '0', '0', '0', '0', '0', '0' ]                                                                                                                         
   filename : 0x0000006e = "/lib"                                                                                                                                                             
            0x0000006f      6c             insb byte [rdi], dx                                 

It should end at 0x73.

ret2libc avatar Jun 23 '20 14:06 ret2libc