m4b / goblin

An impish, cross-platform binary parsing crate, written in Rust
MIT License
1.17k stars 156 forks source link

index out of bounds error when getting imports on arm64e MachO binaries #323

Open puffyCid opened 2 years ago

puffyCid commented 2 years ago

Hello,

I am encountering a small issue when attempting to parse arm64e MachO binaries using goblin.
When I attempt to call the function imports() I get an index out of bounds error.
An example binary that triggers the error is: /usr/bin/lpoptions MD5: b916ce6df2551e4f9eb7e739b07a8d1d.
The file is a FAT binary. I also encounter the error when using the example file dyldinfo.rs The x86_64 binary is parsed fine:

./dyldinfo -arch x86_64 -bind -lazy_bind /usr/bin/lpoptions
bind information:
segment section          address        type    addend dylib            symbol
__DATA  __got            0x100004008    pointer      0 libSystem        ___stack_chk_guard
__DATA  __got            0x100004010    pointer      0 libSystem        ___stderrp
__DATA  __got            0x100004018    pointer      0 libSystem        ___stdoutp
__DATA  __got            0x100004020    pointer      0 libSystem        dyld_stub_binder
lazy binding information (from lazy_bind part of dyld info):
segment section          address    index  dylib            symbol
__DATA  __la_symbol_ptr  0x100004028 0x0000 libSystem        ___error
__DATA  __la_symbol_ptr  0x100004030 0x000F libSystem        ___stack_chk_f
....

But if i try arm64e I get an error/crash

./dyldinfo -arch arm64e -bind -lazy_bind /usr/bin/lpoptions
thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 17', src/mach/imports.rs:103:20
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

I am using macOS Monterey, Intel

let me know if any more information is needed, thanks.

m4b commented 1 year ago

@puffyCid could you verify if this is happening again, and also post which version of goblin you're using.

puffyCid commented 1 year ago

hi @m4b i just tried again using the master branch but i get the same error using the same file

./dyldinfo -arch arm64e -bind -lazy_bind /usr/bin/lpoptions
thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 17', src/mach/imports.rs:103:20
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
m4b commented 1 year ago

can you print the list of imported libraries? otool -l should do it iirc; the issue is this line:

dylib: libs[bi.symbol_library_ordinal as usize],

an easy fix is goint libs.get().unwrap_or("") but i'm afraid this will just mask the underlying issue, which is that we are told a library is mapped to a given ordinal, but this value is too large for the set of libraries declared to be imported by the binary.

puffyCid commented 1 year ago

output for otool -l

/usr/bin/lpoptions:
Load command 0
      cmd LC_SEGMENT_64
  cmdsize 72
  segname __PAGEZERO
   vmaddr 0x0000000000000000
   vmsize 0x0000000100000000
  fileoff 0
 filesize 0
  maxprot 0x00000000
 initprot 0x00000000
   nsects 0
    flags 0x0
Load command 1
      cmd LC_SEGMENT_64
  cmdsize 552
  segname __TEXT
   vmaddr 0x0000000100000000
   vmsize 0x0000000000004000
  fileoff 0
 filesize 16384
  maxprot 0x00000005
 initprot 0x00000005
   nsects 6
    flags 0x0
Section
  sectname __text
   segname __TEXT
      addr 0x0000000100002788
      size 0x0000000000001125
    offset 10120
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x80000400
 reserved1 0
 reserved2 0
Section
  sectname __stubs
   segname __TEXT
      addr 0x00000001000038ae
      size 0x00000000000000ea
    offset 14510
     align 2^1 (2)
    reloff 0
    nreloc 0
     flags 0x80000408
 reserved1 0 (index into indirect symbol table)
 reserved2 6 (size of stubs)
Section
  sectname __stub_helper
   segname __TEXT
      addr 0x0000000100003998
      size 0x0000000000000196
    offset 14744
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x80000400
 reserved1 0
 reserved2 0
Section
  sectname __const
   segname __TEXT
      addr 0x0000000100003b30
      size 0x0000000000000050
    offset 15152
     align 2^4 (16)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Section
  sectname __cstring
   segname __TEXT
      addr 0x0000000100003b80
      size 0x000000000000041f
    offset 15232
     align 2^0 (1)
    reloff 0
    nreloc 0
     flags 0x00000002
 reserved1 0
 reserved2 0
Section
  sectname __unwind_info
   segname __TEXT
      addr 0x0000000100003fa0
      size 0x0000000000000054
    offset 16288
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Load command 2
      cmd LC_SEGMENT_64
  cmdsize 392
  segname __DATA
   vmaddr 0x0000000100004000
   vmsize 0x0000000000004000
  fileoff 16384
 filesize 16384
  maxprot 0x00000003
 initprot 0x00000003
   nsects 4
    flags 0x0
Section
  sectname __nl_symbol_ptr
   segname __DATA
      addr 0x0000000100004000
      size 0x0000000000000008
    offset 16384
     align 2^3 (8)
    reloff 0
    nreloc 0
     flags 0x00000006
 reserved1 39 (index into indirect symbol table)
 reserved2 0
Section
  sectname __got
   segname __DATA
      addr 0x0000000100004008
      size 0x0000000000000020
    offset 16392
     align 2^3 (8)
    reloff 0
    nreloc 0
     flags 0x00000006
 reserved1 40 (index into indirect symbol table)
 reserved2 0
Section
  sectname __la_symbol_ptr
   segname __DATA
      addr 0x0000000100004028
      size 0x0000000000000138
    offset 16424
     align 2^3 (8)
    reloff 0
    nreloc 0
     flags 0x00000007
 reserved1 44 (index into indirect symbol table)
 reserved2 0
Section
  sectname __const
   segname __DATA
      addr 0x0000000100004160
      size 0x0000000000000040
    offset 16736
     align 2^4 (16)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Load command 3
      cmd LC_SEGMENT_64
  cmdsize 72
  segname __LINKEDIT
   vmaddr 0x0000000100008000
   vmsize 0x0000000000008000
  fileoff 32768
 filesize 21232
  maxprot 0x00000001
 initprot 0x00000001
   nsects 0
    flags 0x0
Load command 4
            cmd LC_DYLD_INFO_ONLY
        cmdsize 48
     rebase_off 32768
    rebase_size 8
       bind_off 32776
      bind_size 72
  weak_bind_off 0
 weak_bind_size 0
  lazy_bind_off 32848
 lazy_bind_size 808
     export_off 33656
    export_size 48
Load command 5
     cmd LC_SYMTAB
 cmdsize 24
  symoff 33720
   nsyms 45
  stroff 34776
 strsize 640
Load command 6
            cmd LC_DYSYMTAB
        cmdsize 80
      ilocalsym 0
      nlocalsym 1
     iextdefsym 1
     nextdefsym 1
      iundefsym 2
      nundefsym 43
         tocoff 0
           ntoc 0
      modtaboff 0
        nmodtab 0
   extrefsymoff 0
    nextrefsyms 0
 indirectsymoff 34440
  nindirectsyms 83
      extreloff 0
        nextrel 0
      locreloff 0
        nlocrel 0
Load command 7
          cmd LC_LOAD_DYLINKER
      cmdsize 32
         name /usr/lib/dyld (offset 12)
Load command 8
     cmd LC_UUID
 cmdsize 24
    uuid 4F37F97E-30E5-36F6-89C9-B18F74320F35
Load command 9
      cmd LC_VERSION_MIN_MACOSX
  cmdsize 16
  version 10.12.3
      sdk 12.3
Load command 10
      cmd LC_SOURCE_VERSION
  cmdsize 16
  version 499.3
Load command 11
       cmd LC_MAIN
   cmdsize 24
  entryoff 10120
 stacksize 0
Load command 12
          cmd LC_LOAD_DYLIB
      cmdsize 56
         name /usr/lib/libcups.2.dylib (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 2.14.0
compatibility version 2.0.0
Load command 13
          cmd LC_LOAD_DYLIB
      cmdsize 56
         name /usr/lib/libSystem.B.dylib (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 1311.100.3
compatibility version 1.0.0
Load command 14
      cmd LC_FUNCTION_STARTS
  cmdsize 16
  dataoff 33704
 datasize 8
Load command 15
      cmd LC_DATA_IN_CODE
  cmdsize 16
  dataoff 33712
 datasize 8
Load command 16
      cmd LC_CODE_SIGNATURE
  cmdsize 16
  dataoff 35424
 datasize 18576
m4b commented 1 month ago

is this still happening?

puffyCid commented 1 month ago

yes, same error, running macOS sonoma. I ran the latest version from Github master branch

./dyldinfo -arch arm64e -bind -lazy_bind /usr/bin/lpoptions
thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 17', src/mach/imports.rs:103:20
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

I can close the issue if you like. I found an alternative way to parse/get the data. Unless you want to keep the issue open for tracking