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

Android64: DR finds the wrong ELF header when getting libdynamorio.so's ELF header #7195

Open
felixc-arm opened this issue Jan 17, 2025 · 0 comments

Comments

@felixc-arm
Copy link
Collaborator

See #7186

On 64-bit Android, when DR tries to find its own ELF header to use for private loading, it instead finds the ELF header of the vDSO.

When 64-bit Android's base address is set to 0x0, as for 32-bit Android:

Sections for '/data/local/tmp/build/lib64/debug/libdynamorio.so' (aarch64):
  SectID             Type                   Load Address                             Perm File Off.  File Size  Flags      Section Name
  ------------------ ---------------------- ---------------------------------------  ---- ---------- ---------- ---------- ----------------------------
  0xfffffffffffffffe container              [0x0000007ff77fd000-0x0000007ff77fd270)  r--  0x00000000 0x00000270 0x00000000 libdynamorio.so.PT_LOAD[0]
  0x0000000000000001 code                   [0x0000007ff77fd000-0x0000007ff77fd270)  r-x  0x00001000 0x006aacf0 0x00000006 libdynamorio.so.PT_LOAD[0]..text
  0xfffffffffffffffc container              [0x0000007ff7ea8cf0-0x0000007ff7f9fab8)  r--  0x006abcf0 0x000f6dc8 0x00000000 libdynamorio.so.PT_LOAD[1]
Sections for '[vdso](0x0000007ff77fc000)' (aarch64):
  SectID             Type                   Load Address                             Perm File Off.  File Size  Flags      Section Name
  ------------------ ---------------------- ---------------------------------------  ---- ---------- ---------- ---------- ----------------------------
  0xffffffffffffffff container              [0x0000007ff77fc000-0x0000007ff77fc968)  r-x  0x00000000 0x00000968 0x00000000 [vdso].PT_LOAD[0]
(lldb) memory read 0x0000007ff77fc000
0x7ff77fc000: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00  .ELF............
0x7ff77fc010: 03 00 b7 00 01 00 00 00 e0 02 00 00 00 00 00 00  ................
(lldb) memory read 0x0000007ff77fd000
0x7ff77fd000: ff c3 00 d1 fd 7b 02 a9 fd 83 00 91 a0 83 1f f8  .....{..........
0x7ff77fd010: e1 0b 00 f9 e2 07 00 f9 e3 07 00 b9 a0 83 5f f8  .............._.

So here DR identifies 7ff77fc000 as the base, which is where the vDSO is, and so it finds an ELF header, but the wrong one... It's worth noting that 7ff77fd000, where libynamorio.so is supposed to start, contains the same data as in address 0x1000 in the hexdump of libdynamorio.so, implying libdynamorio.so should start at the address 0x1000 before 7ff77fd000, which is where vDSO is.

The patch #7186 changes this base address to 0x1000, which allows libdynamorio.so to find the correct ELF header, and has the following effect in memory:

Sections for '/data/local/tmp/build/lib64/debug/libdynamorio.so' (aarch64):
  SectID             Type                   Load Address                             Perm File Off.  File Size  Flags      Section Name
  ------------------ ---------------------- ---------------------------------------  ---- ---------- ---------- ---------- ----------------------------
  0xfffffffffffffffe container              [0x0000007ff77fc000-0x0000007ff77fc270)  r--  0x00000000 0x00000270 0x00000000 libdynamorio.so.PT_LOAD[0]
  0xfffffffffffffffd container              [0x0000007ff77fd000-0x0000007ff7ea7cf0)  r-x  0x00001000 0x006aacf0 0x00000000 libdynamorio.so.PT_LOAD[1]
  0x0000000000000001 code                   [0x0000007ff77fd000-0x0000007ff7ea7cf0)  r-x  0x00001000 0x006aacf0 0x00000006 libdynamorio.so.PT_LOAD[1]..text
  0xfffffffffffffffc container              [0x0000007ff7ea8cf0-0x0000007ff7f9fab8)  r--  0x006abcf0 0x000f6dc8 0x00000000 libdynamorio.so.PT_LOAD[2]
Sections for '[vdso](0x0000007ff77fb000)' (aarch64):
  SectID             Type                   Load Address                             Perm File Off.  File Size  Flags      Section Name
  ------------------ ---------------------- ---------------------------------------  ---- ---------- ---------- ---------- ----------------------------
  0xffffffffffffffff container              [0x0000007ff77fb000-0x0000007ff77fb968)  r-x  0x00000000 0x00000968 0x00000000 [vdso].PT_LOAD[0]

ELF headers for both libdynamorio.so and vDSO are at the start of their sections as expected:

(lldb) memory read 0x0000007ff77fb000
0x7ff77fb000: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00  .ELF............
0x7ff77fb010: 03 00 b7 00 01 00 00 00 e0 02 00 00 00 00 00 00  ................
(lldb) memory read 0x0000007ff77fc000
0x7ff77fc000: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00  .ELF............
0x7ff77fc010: 03 00 b7 00 01 00 00 00 ec cf 63 00 00 00 00 00  ..........c.....

Keeping the non-32-bit Android base of 0x71000000:

Sections for '/data/local/tmp/build/lib64/debug/libdynamorio.so' (aarch64):
  SectID             Type                   Load Address                             Perm File Off.  File Size  Flags      Section Name
  ------------------ ---------------------- ---------------------------------------  ---- ---------- ---------- ---------- ----------------------------
  0xfffffffffffffffe container              [0x0000007f867fd000-0x0000007f867fd270)  r--  0x00000000 0x00000270 0x00000000 libdynamorio.so.PT_LOAD[0]
  0xfffffffffffffffd container              [0x0000007ff77fd000-0x0000007ff7ea7cf0)  r-x  0x00001000 0x006aacf0 0x00000000 libdynamorio.so.PT_LOAD[1]
  0x0000000000000001 code                   [0x0000007ff77fd000-0x0000007ff7ea7cf0)  r-x  0x00001000 0x006aacf0 0x00000006 libdynamorio.so.PT_LOAD[1]..text
  0xfffffffffffffffc container              [0x0000007ff7ea8cf0-0x0000007ff7f9fab8)  r--  0x006abcf0 0x000f6dc8 0x00000000 libdynamorio.so.PT_LOAD[2]
Sections for '[vdso](0x0000007ff77fc000)' (aarch64):
  SectID             Type                   Load Address                             Perm File Off.  File Size  Flags      Section Name
  ------------------ ---------------------- ---------------------------------------  ---- ---------- ---------- ---------- ----------------------------
  0xffffffffffffffff container              [0x0000007ff77fc000-0x0000007ff77fc968)  r-x  0x00000000 0x00000968 0x00000000 [vdso].PT_LOAD[0]
(lldb) memory read 0x0000007f867fd000
0x7f867fd000: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00  .ELF............
0x7f867fd010: 03 00 b7 00 01 00 00 00 ec bf 63 71 00 00 00 00  ..........cq....
(lldb) memory read 0x0000007ff77fc000
0x7ff77fc000: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00  .ELF............
0x7ff77fc010: 03 00 b7 00 01 00 00 00 e0 02 00 00 00 00 00 00  ................

So now vDSO and libdynamorio.so don't overlap, but libdynamorio.so finds the ELF header at 7ff77fc000, which is vDSO's

It seems that base/Ttext becomes an offset from 0x7ff77fd000 (or the random address chosen when not running under LLDB). Although setting base/Ttext to 0x1000 seems to work, it would be best to solve the issue of libdynamorio.so finding the vDSO's ELF header when the correct ELF header is present in memory, e.g. in the last example given here where the vDSO is between libdynamorio.so's .text portion and its ELF header, leading vDSO's ELF header to be found first and chosen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant