I would like to find out which method my 32bit QEMU guest is using for system calls. There's an excellent article explaining linux-gate.dso (http://www.trilithium.com/johan/2005/08/linux-gate/). However, I can 't seem to get any of the commands to work on my newer system.

It appears that current security features don't allow me to dump the virtual dso:

[root@qemu ~]# dd if=/proc/self/mem of=linux-gate.dso bs=4096 skip=1048574 count=1
dd: ‘/proc/self/mem’: cannot skip to specified offset
dd: error reading ‘/proc/self/mem’: Input/output error
0+0 records in
0+0 records out
0 bytes (0 B) copied, 0.0332587 s, 0.0 kB/s

In order to read /proc/[pid]/mem, a process must now PTRACE_ATTACH to it. A commonly available utility that does this is gdb

Pick a running process (in my case I just opened cat in another window), then attach gdb to that process:

[root@qemu ~]# gdb --pid 423
0xb771dbac in __kernel_vsyscall ()

As part of its output while loading symbols, gdb should output the line I included above. If it doesn't, you can search the symbol table for it:

(gdb) info functions vsyscall
All functions matching regular expression "vsyscall":

Non-debugging symbols:
0xb771db9c  __kernel_vsyscall

Now that we have the address of __kernel_vsyscall, we can either use gdb to inspect the system call method used:

(gdb) disassemble 0xb771db9c
Dump of assembler code for function __kernel_vsyscall:
   0xb771db9c <+0>:     push   %ecx
   0xb771db9d <+1>:     push   %edx
   0xb771db9e <+2>:     push   %ebp
   0xb771db9f <+3>:     mov    %esp,%ebp
   0xb771dba1 <+5>:     sysenter 
   0xb771dba3 <+7>:     nop
   0xb771dba4 <+8>:     nop
   0xb771dba5 <+9>:     nop
   0xb771dba6 <+10>:    nop
   0xb771dba7 <+11>:    nop
   0xb771dba8 <+12>:    nop
   0xb771dba9 <+13>:    nop
   0xb771dbaa <+14>:    int    $0x80
=> 0xb771dbac <+16>:    pop    %ebp
   0xb771dbad <+17>:    pop    %edx
   0xb771dbae <+18>:    pop    %ecx
   0xb771dbaf <+19>:    ret    
End of assembler dump.

or we can dump linux-gate.dso as originally requested:

(gdb) dump memory ./linux-gate.dso 0xb771d000 0xb771e000

Basically, we know that linux-gate.dso takes one full page. Since this system has a page size of 4K=0x1000, I just rounded down from the address of __kernel_vsyscall and added 0x1000 to get the end. Outside of gdb, we can see that the file is recognized as a shared library:

[root@qemu ~]# objdump -T ./linux-gate.dso |grep syscall
00000b9c g    DF .text  00000014  LINUX_2.5   __kernel_vsyscall

and we can find sysenter again: [root@arch-qemu ~]# objdump -d --start-address=0x00000b9c --stop-address=0x00000bac linux-gate.dso

linux-gate.dso: file format elf32-i386

Disassembly of section .text:

00000b9c <__kernel_vsyscall>:
 b9c:   51                      push   %ecx
 b9d:   52                      push   %edx
 b9e:   55                      push   %ebp
 b9f:   89 e5                   mov    %esp,%ebp
 ba1:   0f 34                   sysenter 
 ba3:   90                      nop
 ba4:   90                      nop
 ba5:   90                      nop
 ba6:   90                      nop
 ba7:   90                      nop
 ba8:   90                      nop
 ba9:   90                      nop
 baa:   cd 80                   int    $0x80

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.