2

I am studying the vdso mechanism in Linux. To find the DSO, I can parse the auxiliary vector passed to the program's entry point. The AT_SYSINFO_EHDR entry will point to the vDSO.

My question is why, can't I access the vDSO using the addresses showed in /proc/self/maps ? Shouldn't the result be the same? I tried to access vDSO using those addresses in several ways, but I always got a wrong memory area. I am using a x86_64 bit.

For example, I don't understand why using dd to dump that memory area does not work in 64 bit operating system, while it seems to work on 32bit. Any Idea?

dd if=/prcc/self/mem of=vDSO.bin count=1 bs=4096 skip=0xffffffffff600000

I know I cannot use a hexadecimal offset, I put it like that because it's more clear to read.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
Giuseppe Pes
  • 7,772
  • 3
  • 52
  • 90

2 Answers2

3

Recently, for Android someone reported a failing test case against our vdso's on one of our devices. The issue was strangely not reproducible with local kernel builds (where vdso.so is output from the kernel build process), so I needed to pull a copy of it off a live device.

In order to pull the vdso out of a running device, you need to know where it's mapped and how big it is. This information is provided by /proc/<pid>/maps from a long running process (example, pid 1, init). ex:

$ adb root
$ adb shell cat /proc/1/maps | grep vdso
7fa6403000-7fa6405000 r-xp 00000000 00:00 0  [vdso]

So this tells us that the vdso is 8192 bytes (0x7fa6405000 - 0x7fa6403000 == 0x2000 == 8192) starting at 0x7fa6403000. 0x2000 is NOT a multiple of 0x7fa6403000 (remainder of 0x0.8 == 0.5), so we use 4096 (0x1000) (half the size) as the block size, double the count, and skip 133850115 multiples of the block size (133850115 * 4096 == 548250071040 == 0x7FA6403000).

$ adb shell dd if=/proc/1/mem of=/data/local/tmp/vdso.so bs=4096 count=2 skip=133850115
2+0 records in
2+0 records out
8192 bytes (8.0 K) copied, 0.000442 s, 18 M/s
$ adb shell ls -l /data/local/tmp
-rw-rw-rw- 1 root  root   8192 2019-02-20 23:51 vdso.so
$ adb pull /data/local/tmp/vdso.so
/data/local/tmp/vdso.so: 1 file pulled. 3.2 MB/s (8192 bytes in 0.002s)
$ file vdso.so
vdso.so: ELF 64-bit LSB shared object ARM aarch64, version 1 (SYSV), dynamically linked, stripped
$ readelf -s vdso.so 

Symbol table '.dynsym' contains 8 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00000000000002e8     0 SECTION LOCAL  DEFAULT    6 
     2: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  ABS LINUX_2.6.39
     3: 00000000000007dc   108 FUNC    GLOBAL DEFAULT    7 
__kernel_clock_getres@@LINUX_2.6.39
     4: 00000000000008c0     8 FUNC    GLOBAL DEFAULT    7 
__kernel_rt_sigreturn@@LINUX_2.6.39
     5: 00000000000006e4   248 FUNC    GLOBAL DEFAULT    7 
__kernel_gettimeofday@@LINUX_2.6.39
     6: 0000000000000848    96 FUNC    GLOBAL DEFAULT    7 
__kernel_time@@LINUX_2.6.39
     7: 0000000000000300   996 FUNC    GLOBAL DEFAULT    7 
__kernel_clock_gettime@@LINUX_2.6.39
Braiam
  • 1
  • 11
  • 47
  • 78
Nick Desaulniers
  • 2,046
  • 3
  • 25
  • 47
1

skip must be given in units of bs.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711