Linux2.6对新型CPU快速系统调用的支持

http://tech.ddvip.com   2006年11月20日    社区交流

本文详细介绍Linux2.6对新型CPU快速系统调用的支持

(gdb) X 0x80aa054 0x80aa054 <_dl_sysinfo>:    0x0804d7f6

  看起来不像是指向内核映射页面内的代码,但是,可以确认,__dl_sysinfo 指针的指向的地址就是 0x80aa054。下面,我们试着启动这个程序,然后停在程序第一条语句,再查看这个地方的值。

(gdb) b main Breakpoint 1 at 0x804820a (gdb)
r Starting program: /opt/static Breakpoint 1, 
0x0804820a in main () (gdb) X 0x80aa054 0x80aa054 
<_dl_sysinfo>:    0xffffe400

  可以看到,_dl_sysinfo 指针指向的数值已经发生了变化,指向了 0xffffe400,如果我们继续运行程序,__getuid 函数将会调用地址 0xffffe400 处的代码。

  接下来,我们将上面的代码编译成动态链接的方式,即默认方式,用 gdb 装载并反编译 main 函数

[root@test opt]# gcc test.c -o ./dynamic [root@test opt]
# gdb ./dynamic (gdb) disassemble main 0x08048204 :  
push  %ebp 0x08048205 :  mov  %esp,%ebp 0x08048207 :
  sub  $0x8,%esp 0x0804820a :  and  $0xfffffff0,
%esp 0x0804820d :  mov  $0x0,%eax 0x08048212 :  sub 
  %eax,%esp 0x08048214 :  call  0x8048288 0x08048219 : 
 leave 0x0804821a :  ret

  由于 libc 库是在程序初始化时才被装载,所以我们先启动程序,并停在 main 第一条语句,然后反汇编 getuid 库函数。

(gdb) b main Breakpoint 1 at 0x804820a 
(gdb) r Starting program: /opt/dynamic Breakpoint 1, 
0x0804820a in main () (gdb) disassemble getuid Dump 
of assembler code for function getuid: 0x40219e50 
<__getuid+0>:    push  %ebp 0x40219e51
<__getuid+1>:    mov  %esp,%ebp 0x40219e53 
<__getuid+3>:    push  %ebx 0x40219e54
<__getuid+4>:    call  0x40219e59
<__getuid+9> 0x40219e59 <__getuid+9>:   
  pop  %ebx 0x40219e5a <__getuid+10>:  
  add  $0x84b0f,%ebx 0x40219e60 
<__getuid+16>:    mov  0xffffd87c(%ebx),
%eax 0x40219e66 <__getuid+22>:    test 
%eax,%eax 0x40219e68 <__getuid+24>:    
jle  0x40219e80 <__getuid+48> 0x40219e6a 
<__getuid+26>:    mov  $0x18,%eax 0x40219e6f 
<__getuid+31>:    call  *%gs:0x10 0x40219e76
<__getuid+38>:    pop  %ebx 0x40219e77
<__getuid+39>:    pop  %ebp 0x40219e78 <__getuid+40>:    ret

  可以看出,库函数 getuid 将 eax 寄存器设置为 getuid 系统调用的调用号 0x18,然后调用 %gs:0x10 所指向的函数。在 gdb 中,无法查看非 DS 段的数据内容,所以无法查看 %gs:0x10 所保存的实际数值,不过我们可以通过编程的办法,内嵌汇编将 %gs:0x10 的值赋予某个局部变量来得到这个数值,而这个数值也是 0xffffe400,具体代码这里就不再赘述。

责编:豆豆技术应用

正在加载评论...