Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2150632
  • 博文数量: 438
  • 博客积分: 3871
  • 博客等级: 中校
  • 技术积分: 6075
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-10 00:11
个人简介

邮箱: wangcong02345@163.com

文章分类

全部博文(438)

文章存档

2017年(15)

2016年(119)

2015年(91)

2014年(62)

2013年(56)

2012年(79)

2011年(16)

分类: LINUX

2016-10-12 11:04:54

1. 开始
init/main.c中 L195
  1. void init(void)
  2. {
  3.     int pid,i;
  4.     printf("next setup\n");
  5.     setup((void *) &drive_info);
  6.     (void) open("/dev/tty1",O_RDWR,0);
  7.     (void) dup(0);
  8.     (void) dup(0);
  9.     printf("%d buffers = %d bytes buffer space\n\r",NR_BUFFERS,
  10.         NR_BUFFERS*BLOCK_SIZE);
  11.     printf("Free mem: %d bytes\n\r",memory_end-main_memory_start);
  12.     if (!(pid=fork())) {
  13.         close(0);
  14.         if (open("/etc/rc",O_RDONLY,0))
  15.             _exit(1);
  16.         execve("/bin/sh",argv_rc,envp_rc);
  17.         _exit(2);
  18.     }
  19. }
a. 其中 execve("/bin/sh",argv_rc,envp_rc)的execve是一个宏定义的:
  1. lib/execve.c
  2. _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
b. include/unistd.h中的宏
lib/execve.c:_syscall3(int,execve,const char *,file,char **,argv,char **,envp)
include/unistd.h --> L189定义了syscall3
  1. #define _syscall3(type,name,atype,a,btype,b,ctype,c) \
  2. type name(atype a,btype b,ctype c) \
  3. { \
  4. long __res; \
  5. __asm__ volatile ("int $0x80" \
  6.     : "=a" (__res) \
  7.     : "0" (__NR_##name),"b" ((long)(a)),"c" ((long)(b)),"d" ((long)(c))); \
  8. if (__res>=0) \
  9.     return (type) __res; \
  10. errno=-__res; \
  11. return -1; \
  12. }


展开后:
  1. int execve(const char * file,char ** argv,char ** envp)
  2. {
  3.     long __res;
  4.     __asm__ volatile
  5.     ("int $0x80"
  6.             : "=a" (__res)
  7.             : "0" (11),"b" ((long)(file)),"c" ((long)(argv)),"d"((long)(envp))
  8.     );
  9.     if (__res>=0)
  10.         return (int) __res;
  11.    errno=-__res;
  12.    return -1;
  13. }


c. int 0x80系统调用
sys_call --> sys_call_table[11] --> sys_execve
在kernel/sys_call.s中 L214
  1. .align 4
  2. sys_execve:
  3.     lea EIP(%esp),%eax
  4.     pushl %eax
  5.     call do_execve
  6.     addl $4,%esp
  7.     ret
即系统调用到了do_execve

2. do_execve
#0  do_execve (eip=0xffbfec, tmp=30935, filename=0x22660 "/bin/sh", argv=0x29820 , envp=0x29828 ) at exec.c:220
在fs/exec.c中L207
  1. int do_execve(unsigned long * eip,long tmp,char * filename,
  2.     char ** argv, char ** envp)
  3. {
  4.     struct m_inode * inode;
  5.     struct buffer_head * bh;
  6.     struct exec ex;
  7.     unsigned long page[MAX_ARG_PAGES];
  8.     int i,argc,envc;
  9.     int e_uid, e_gid;
  10.     int retval;
  11.     int sh_bang = 0;
  12.     unsigned long p=PAGE_SIZE*MAX_ARG_PAGES-4;

  13.     if ((0xffff & eip[1]) != 0x000f)
  14.         panic("execve called from supervisor mode");
  15.     for (i=0 ; i<MAX_ARG_PAGES ; i++)    /* clear page-table */
  16.         page[i]=0;
  17.     if (!(inode=namei(filename)))        /* get executables inode */
  18.         return -ENOENT;
  19.     argc = count(argv);
  20.     envc = count(envp);
  21.     
  22. restart_interp:
  23.     if (!S_ISREG(inode->i_mode)) {    /* must be regular file */
  24.         retval = -EACCES;
  25.         goto exec_error2;
  26.     }
  27.     i = inode->i_mode;
  28.     e_uid = (i & S_ISUID) ? inode->i_uid : current->euid;
  29.     e_gid = (i & S_ISGID) ? inode->i_gid : current->egid;
  30.     if (current->euid == inode->i_uid)
  31.         i >>= 6;
  32.     else if (in_group_p(inode->i_gid))
  33.         i >>= 3;
  34.     if (!(i & 1) &&
  35.      !((inode->i_mode & 0111) && suser())) {
  36.         retval = -ENOEXEC;
  37.         goto exec_error2;
  38.     }
  39.     if (!(bh = bread(inode->i_dev,inode->i_zone[0]))) {
  40.         retval = -EACCES;
  41.         goto exec_error2;
  42.     }
  43.     ex = *((struct exec *) bh->b_data);    /* read exec-header */
  44.     if ((bh->b_data[0] == '#') && (bh->b_data[1] == '!') && (!sh_bang)) {
  45.           //这儿先不关心shell脚本的执行过程
  46.     }
  47.     brelse(bh);
  48.     if (N_MAGIC(ex) != ZMAGIC || ex.a_trsize || ex.a_drsize ||
  49.         ex.a_text+ex.a_data+ex.a_bss>0x3000000 ||
  50.         inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) {
  51.         retval = -ENOEXEC;
  52.         goto exec_error2;
  53.     }
  54.     if (N_TXTOFF(ex) != BLOCK_SIZE) {
  55.         printk("%s: N_TXTOFF != BLOCK_SIZE. See a.out.h.", filename);
  56.         retval = -ENOEXEC;
  57.         goto exec_error2;
  58.     }
  59.     if (!sh_bang) {
  60.         p = copy_strings(envc,envp,page,p,0);
  61.         p = copy_strings(argc,argv,page,p,0);
  62.         if (!p) {
  63.             retval = -ENOMEM;
  64.             goto exec_error2;
  65.         }
  66.     }
  67. /* OK, This is the point of no return */
  68. /* note that current->library stays unchanged by an exec */
  69.     if (current->executable)
  70.         iput(current->executable);
  71.     current->executable = inode;
  72.     current->signal = 0;
  73.     for (i=0 ; i<32 ; i++) {
  74.         current->sigaction[i].sa_mask = 0;
  75.         current->sigaction[i].sa_flags = 0;
  76.         if (current->sigaction[i].sa_handler != SIG_IGN)
  77.             current->sigaction[i].sa_handler = NULL;
  78.     }
  79.     for (i=0 ; i<NR_OPEN ; i++)
  80.         if ((current->close_on_exec>>i)&1)
  81.             sys_close(i);
  82.     current->close_on_exec = 0;
  83.     free_page_tables(get_base(current->ldt[1]),get_limit(0x0f));
  84.     free_page_tables(get_base(current->ldt[2]),get_limit(0x17));
  85.     if (last_task_used_math == current)
  86.         last_task_used_math = NULL;
  87.     current->used_math = 0;
  88.     p += change_ldt(ex.a_text,page);
  89.     p -= LIBRARY_SIZE + MAX_ARG_PAGES*PAGE_SIZE;
  90.     p = (unsigned long) create_tables((char *)p,argc,envc);
  91.     current->brk = ex.a_bss +
  92.         (current->end_data = ex.a_data +
  93.         (current->end_code = ex.a_text));
  94.     current->start_stack = p & 0xfffff000;
  95.     current->suid = current->euid = e_uid;
  96.     current->sgid = current->egid = e_gid;
  97.     eip[0] = ex.a_entry;        /* eip, magic happens :-) */
  98.     eip[3] = p;            /* stack pointer */
  99.     return 0;
  100. exec_error2:
  101.     iput(inode);
  102. exec_error1:
  103.     for (i=0 ; i<MAX_ARG_PAGES ; i++)
  104.         free_page(page[i]);
  105.     return(retval);
  106. }



阅读(1063) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~