As we can learn about linux gate or virtual dynamic shared object (VDSO) or linux-gate.so.1 or linux-vdso.so.1 by following page :
http://www.trilithium.com/johan/2005/08/linux-gate/
A lot of things explained in the above page, but when tried things, I faced some issues and solved as following :
1. Looking at ELF Auxiliary Vector
--> One can see all the ELF Auxiliary vectors on say 'true' binary as :
LD_SHOW_AUXV=1 /bin/true
This will actually execute the binary, and will show its ELF Auxilliary vector values.
2. It states that
a shared object exposed by the kernel at a fixed address in every process’ memory
Unfortunately, its no longer the case. When I tried getting the maps of vdso a couple of times :
cat /proc/self/maps | grep vdso
I always got the different address
3. Getting vdso segment.
As the above link says, dumping vdso can be done as :
Assuming the fixed mapping at 0xffffe000, the post tells you to use dd to extract the relevant information by accessing the process' pages through /proc/self/mem.
(Note that 0xffffe000/4096 = 1048574)
but you will be surprised to get the following errors :
-- reading /proc/self/mem : I/O error
And no output..
Well, the reason of this error is stated beautifully in the following link :
http://unix.stackexchange.com/questions/6301/how-do-i-read-from-proc-pid-mem-under-linux
A good point made here is :
" since the first page in a process is never mapped (so that dereferencing a
Now then how should we dump vdso.... I then googled around ... found out the following post facing and solved the same issue I am facing :
http://anomit.com/2010/04/18/examining-the-linux-vdso/
He has actually created the following python script to get the vdso map of the current process, and seek to it in /proc/self/mem, and write down the required bytes to new file . Following is the script :
---------
Another way to dump vdso, is to seek to address specified by ELF auxiliary vector AT_SYSINFO_EHDR, and dump 1 page (4096 bytes). Something like this :
-----------
http://www.trilithium.com/johan/2005/08/linux-gate/
A lot of things explained in the above page, but when tried things, I faced some issues and solved as following :
1. Looking at ELF Auxiliary Vector
--> One can see all the ELF Auxiliary vectors on say 'true' binary as :
LD_SHOW_AUXV=1 /bin/true
This will actually execute the binary, and will show its ELF Auxilliary vector values.
2. It states that
a shared object exposed by the kernel at a fixed address in every process’ memory
Unfortunately, its no longer the case. When I tried getting the maps of vdso a couple of times :
cat /proc/self/maps | grep vdso
I always got the different address
3. Getting vdso segment.
As the above link says, dumping vdso can be done as :
Assuming the fixed mapping at 0xffffe000, the post tells you to use dd to extract the relevant information by accessing the process' pages through /proc/self/mem.
(Note that 0xffffe000/4096 = 1048574)
dd if=/proc/self/mem of=linux-gate.dso bs=4096 skip=1048574 count=1
but you will be surprised to get the following errors :
-- reading /proc/self/mem : I/O error
And no output..
Well, the reason of this error is stated beautifully in the following link :
http://unix.stackexchange.com/questions/6301/how-do-i-read-from-proc-pid-mem-under-linux
A good point made here is :
" since the first page in a process is never mapped (so that dereferencing a
NULL pointer fails cleanly rather than unintendedly accessing actual memory), reading the first byte of /proc/$pid/mem always yield an I/O error."Now then how should we dump vdso.... I then googled around ... found out the following post facing and solved the same issue I am facing :
http://anomit.com/2010/04/18/examining-the-linux-vdso/
He has actually created the following python script to get the vdso map of the current process, and seek to it in /proc/self/mem, and write down the required bytes to new file . Following is the script :
---------
#! /usr/bin/env python from __future__ import with_statement import re import os ## regex pattern for finding out the memory address range from the output line pattern = re.compile(r'[\w\d]+-[\w\d]+') with open('/proc/self/maps', 'r') as file: for line in file: line = line.rstrip() if '[vdso]' in line: addr_range = pattern.findall(line)[0] start_addr, end_addr = [int(addr, 16) for addr in addr_range.split('-')] break file.close() fd = os.open('/proc/self/mem', os.O_RDONLY) os.lseek(fd, start_addr, os.SEEK_SET) buf = os.read(fd, (end_addr-start_addr)) with open('linux-gate.dso.1', 'w') as file: file.write(buf) file.close() os.close(fd)------------------------
Another way to dump vdso, is to seek to address specified by ELF auxiliary vector AT_SYSINFO_EHDR, and dump 1 page (4096 bytes). Something like this :
-----------
#include#include #include #include static void *getsys(char **envp) { Elf64_auxv_t *auxv; /* walk past all env pointers */ while (*envp++ != NULL); /* and find ELF auxiliary vectors (if this was an ELF binary) */ auxv = (Elf64_auxv_t *) envp; for ( ; auxv->a_type != AT_NULL; auxv++) if (auxv->a_type == AT_SYSINFO_EHDR) return (void *)auxv->a_un.a_val; fprintf(stderr, "no AT_SYSINFO_EHDR auxv entry found\n"); exit(1); } int main(int argc, char *argv[], char **envp) { unsigned char buffer[4096]; void *p; p=getsys(envp); fprintf(stderr, "AT_SYSINFO_EHDR at %p\n",p); memcpy(buffer, p, 4096); write(1, buffer, 4096); }
