1. 开始
init/main.c中 L195
-
void init(void)
-
{
-
int pid,i;
-
printf("next setup\n");
-
setup((void *) &drive_info);
-
(void) open("/dev/tty1",O_RDWR,0);
-
(void) dup(0);
-
(void) dup(0);
-
printf("%d buffers = %d bytes buffer space\n\r",NR_BUFFERS,
-
NR_BUFFERS*BLOCK_SIZE);
-
printf("Free mem: %d bytes\n\r",memory_end-main_memory_start);
-
if (!(pid=fork())) {
-
close(0);
-
if (open("/etc/rc",O_RDONLY,0))
-
_exit(1);
-
execve("/bin/sh",argv_rc,envp_rc);
-
_exit(2);
-
}
-
}
a. 其中
execve("/bin/sh",argv_rc,envp_rc)的execve是一个宏定义的:
-
lib/execve.c
-
_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
-
#define _syscall3(type,name,atype,a,btype,b,ctype,c) \
-
type name(atype a,btype b,ctype c) \
-
{ \
-
long __res; \
-
__asm__ volatile ("int $0x80" \
-
: "=a" (__res) \
-
: "0" (__NR_##name),"b" ((long)(a)),"c" ((long)(b)),"d" ((long)(c))); \
-
if (__res>=0) \
-
return (type) __res; \
-
errno=-__res; \
-
return -1; \
-
}
|
展开后:
-
int execve(const char * file,char ** argv,char ** envp)
-
{
-
long __res;
-
__asm__ volatile
-
("int $0x80"
-
: "=a" (__res)
-
: "0" (11),"b" ((long)(file)),"c" ((long)(argv)),"d"((long)(envp))
-
);
-
if (__res>=0)
-
return (int) __res;
-
errno=-__res;
-
return -1;
-
}
|
c. int 0x80系统调用
sys_call --> sys_call_table[11] --> sys_execve
在kernel/sys_call.s中 L214
-
.align 4
-
sys_execve:
-
lea EIP(%esp),%eax
-
pushl %eax
-
call do_execve
-
addl $4,%esp
-
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
-
int do_execve(unsigned long * eip,long tmp,char * filename,
-
char ** argv, char ** envp)
-
{
-
struct m_inode * inode;
-
struct buffer_head * bh;
-
struct exec ex;
-
unsigned long page[MAX_ARG_PAGES];
-
int i,argc,envc;
-
int e_uid, e_gid;
-
int retval;
-
int sh_bang = 0;
-
unsigned long p=PAGE_SIZE*MAX_ARG_PAGES-4;
-
-
if ((0xffff & eip[1]) != 0x000f)
-
panic("execve called from supervisor mode");
-
for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */
-
page[i]=0;
-
if (!(inode=namei(filename))) /* get executables inode */
-
return -ENOENT;
-
argc = count(argv);
-
envc = count(envp);
-
-
restart_interp:
-
if (!S_ISREG(inode->i_mode)) { /* must be regular file */
-
retval = -EACCES;
-
goto exec_error2;
-
}
-
i = inode->i_mode;
-
e_uid = (i & S_ISUID) ? inode->i_uid : current->euid;
-
e_gid = (i & S_ISGID) ? inode->i_gid : current->egid;
-
if (current->euid == inode->i_uid)
-
i >>= 6;
-
else if (in_group_p(inode->i_gid))
-
i >>= 3;
-
if (!(i & 1) &&
-
!((inode->i_mode & 0111) && suser())) {
-
retval = -ENOEXEC;
-
goto exec_error2;
-
}
-
if (!(bh = bread(inode->i_dev,inode->i_zone[0]))) {
-
retval = -EACCES;
-
goto exec_error2;
-
}
-
ex = *((struct exec *) bh->b_data); /* read exec-header */
-
if ((bh->b_data[0] == '#') && (bh->b_data[1] == '!') && (!sh_bang)) {
-
//这儿先不关心shell脚本的执行过程
-
}
-
brelse(bh);
-
if (N_MAGIC(ex) != ZMAGIC || ex.a_trsize || ex.a_drsize ||
-
ex.a_text+ex.a_data+ex.a_bss>0x3000000 ||
-
inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) {
-
retval = -ENOEXEC;
-
goto exec_error2;
-
}
-
if (N_TXTOFF(ex) != BLOCK_SIZE) {
-
printk("%s: N_TXTOFF != BLOCK_SIZE. See a.out.h.", filename);
-
retval = -ENOEXEC;
-
goto exec_error2;
-
}
-
if (!sh_bang) {
-
p = copy_strings(envc,envp,page,p,0);
-
p = copy_strings(argc,argv,page,p,0);
-
if (!p) {
-
retval = -ENOMEM;
-
goto exec_error2;
-
}
-
}
-
/* OK, This is the point of no return */
-
/* note that current->library stays unchanged by an exec */
-
if (current->executable)
-
iput(current->executable);
-
current->executable = inode;
-
current->signal = 0;
-
for (i=0 ; i<32 ; i++) {
-
current->sigaction[i].sa_mask = 0;
-
current->sigaction[i].sa_flags = 0;
-
if (current->sigaction[i].sa_handler != SIG_IGN)
-
current->sigaction[i].sa_handler = NULL;
-
}
-
for (i=0 ; i<NR_OPEN ; i++)
-
if ((current->close_on_exec>>i)&1)
-
sys_close(i);
-
current->close_on_exec = 0;
-
free_page_tables(get_base(current->ldt[1]),get_limit(0x0f));
-
free_page_tables(get_base(current->ldt[2]),get_limit(0x17));
-
if (last_task_used_math == current)
-
last_task_used_math = NULL;
-
current->used_math = 0;
-
p += change_ldt(ex.a_text,page);
-
p -= LIBRARY_SIZE + MAX_ARG_PAGES*PAGE_SIZE;
-
p = (unsigned long) create_tables((char *)p,argc,envc);
-
current->brk = ex.a_bss +
-
(current->end_data = ex.a_data +
-
(current->end_code = ex.a_text));
-
current->start_stack = p & 0xfffff000;
-
current->suid = current->euid = e_uid;
-
current->sgid = current->egid = e_gid;
-
eip[0] = ex.a_entry; /* eip, magic happens :-) */
-
eip[3] = p; /* stack pointer */
-
return 0;
-
exec_error2:
-
iput(inode);
-
exec_error1:
-
for (i=0 ; i<MAX_ARG_PAGES ; i++)
-
free_page(page[i]);
-
return(retval);
-
}
阅读(1063) | 评论(0) | 转发(0) |