学习Unix操作系统知识

系统 其他OS
在文章中,我们知道Unix操作系统程序的链接分为静态链接和动态链接,来用GDB来研究一下Unix操作系统程序的反汇编。

我们知道,Unix操作系统程序的链接分为静态链接和动态链接,静态链接就是把所有所引用到的函数或变量全部地编译到可执行文件中。今天我们就来学习下这方面的知识。

我们先来用GDB来研究一下Unix操作系统程序的反汇编。注意其中的一些部分。那就是if语句。如果条件失败,则会转到<main+75>。当然,用LD_PRELOAD无法影响表达式,其只能只能影响函数。于是,我们可以在printf上动点歪脑筋。

 

  1. (gdb) disassemble main  
  2. Dump of assembler code for function main:  
  3. 0x08048368 <main+0>:push   %ebp  
  4. 0x08048369 <main+1>:mov%esp,%ebp  
  5. 0x0804836b <main+3>:sub$0x18,%esp  
  6. 0x0804836e <main+6>:and$0xfffffff0,%esp  
  7. 0x08048371 <main+9>:mov$0x0,%eax  
  8. 0x08048376 <main+14>:   add$0xf,%eax  
  9. 0x08048379 <main+17>:   add$0xf,%eax  
  10. 0x0804837c <main+20>:   shr$0x4,%eax  
  11. 0x0804837f <main+23>:   shl$0x4,%eax  
  12. 0x08048382 <main+26>:   sub%eax,%esp  
  13. 0x08048384 <main+28>:   movl   $0x1,0xfffffffc(%ebp)  
  14. 0x0804838b <main+35>:   movl   $0x2,0xfffffff8(%ebp)  
  15. 0x08048392 <main+42>:   mov0xfffffffc(%ebp),%eax  
  16. 0x08048395 <main+45>:   cmp0xfffffff8(%ebp),%eax  
  17. 0x08048398 <main+48>:   je 0x80483b3 <main+75> 
  18. 0x0804839a <main+50>:   sub$0xc,%esp  
  19. 0x0804839d <main+53>:   push   $0x80484b0  
  20. 0x080483a2 <main+58>:   call   0x80482b0  
  21. 0x080483a7 <main+63>:   add$0x10,%esp  
  22. 0x080483aa <main+66>:   movl   $0x0,0xfffffff4(%ebp)  
  23. 0x080483b1 <main+73>:   jmp0x80483ca <main+98> 
  24. 0x080483b3 <main+75>:   sub$0xc,%esp  
  25. 0x080483b6 <main+78>:   push   $0x80484b8  
  26. 0x080483bb <main+83>:   call   0x80482b0  
  27. 0x080483c0 <main+88>:   add$0x10,%esp  
  28. 0x080483c3 <main+91>:   movl   $0x1,0xfffffff4(%ebp)  
  29. 0x080483ca <main+98>:   mov0xfffffff4(%ebp),%eax  
  30. 0x080483cd <main+101>:  leave  
  31. 0x080483ce <main+102>:  ret  
  32. End of assembler dump. 

下面是我们Unix操作系统重载printf的so文件。让printf返回后的栈地址变成<main+75>。从而让程序接着执行。下面是so文件的源,都是让人反感的汇编代码。
 

  1. #include <stdarg.h> 
  2. static int (*_printf)(const char *format, ...) = NULL;  
  3. int printf(const char *format, ...)  
  4. {  
  5. if (_printf == NULL) {  
  6.  /* 取得标准库中的printf的函数地址 */  
  7. _printf = (int (*)(const char *format, ...)) dlsym(RTLD_NEXT, "printf");  
  8.  /* 把函数返回的地址置到<main+75> */  
  9.  __asm__ __volatile__ (  
  10. "movl 0x4(%ebp), %eax \n"  
  11. "addl $15, %eax \n"  
  12. "movl %eax, 0x4(%ebp)"  
  13.  );  
  14.  return 1;  
  15. }  
  16. /* 重置 printf的返回地址 */  
  17. __asm__ __volatile__ (  
  18. "addl $12, %%esp \n"  
  19. "jmp *%0 \n"  
  20. : /* no output registers */  
  21. : "g" (_printf)  
  22. : "%esp"  
  23. );  

你可以在你的Unix操作系统下试试这段代码。

【编辑推荐】

  1. 浅析Unix操作系统set命令
  2. 实际运用Unix操作系统set命令
  3. Unix操作系统TCP/UDP知识
  4. 利用Unix操作系统重定向
  5. Unix操作系统与农村信用社
责任编辑:小霞
相关推荐

2010-04-30 17:27:59

Unix操作系统

2010-04-19 16:57:09

Unix操作系统

2010-04-19 17:39:50

Unix操作系统

2010-04-19 10:54:33

Unix操作系统

2010-04-29 13:30:20

Unix操作系统

2010-04-19 17:06:18

2010-04-20 11:34:26

Unix操作系统

2010-04-16 09:27:36

2010-04-13 18:24:14

Unix操作系统

2010-05-04 17:17:46

Unix类

2010-04-20 15:36:02

Unix操作系统

2010-04-07 16:15:04

Unix操作系统

2010-04-19 11:26:52

Unix操作系统

2010-04-19 17:44:56

Unix操作系统

2010-05-07 11:22:18

Unix操作系统

2010-04-19 17:34:02

Unix操作系统

2010-04-19 17:47:59

Unix操作系统

2010-04-20 10:12:40

Unix操作系统

2010-04-16 17:19:58

Unix操作系统

2010-04-09 11:24:38

Unix操作系统
点赞
收藏

51CTO技术栈公众号