当前位置: 首页 > news >正文

广告网站建设与制作营销托管全网营销推广

广告网站建设与制作,营销托管全网营销推广,手机怎么做网站教程,自己在网上怎么做网站主要实现对二进制可执行文件和shell文件的加载和执行,其中主要的函数是do_execve(),它是系统中断调用int 0x80的功能号__NR_execve()调用,是exec()函数的主要实现以下几点功能: 1.执行对参数和环境参数空间页面的初始化操作,初始…

主要实现对二进制可执行文件和shell文件的加载和执行,其中主要的函数是do_execve(),它是系统中断调用int 0x80的功能号__NR_execve()调用,是exec()函数的主要实现以下几点功能:

1.执行对参数和环境参数空间页面的初始化操作,初始化空间页面指针数组,根据执行文件名取执行对象的i节点,计算参数个数和环境变量个数,检查文件类型、执行权限

2.根据执行文件开始部分的头数据结构,对其中信息进行处理,根据被执行文件i节点读取文件头部信息,若是shell以#!开始,则分析shell程序名和其参数;根据幻数和段长度等信息判断是否可执行

3.对当前调用进程进行运行新文件前初始化操作,指向新执行文件的i节点,复位信号处理句柄,根据头结构信息设置局部描述符地址和段长;设置参数和环境参数页面指针;修改进程各执行字段内容

4.替换堆栈上原调用execve()程序的返回地址为新执行程序运行地址,运行新加载的程序

 create_tables函数用于根据给定的当前堆栈指针值p以及参数个数argc和环境变量个数envc,在新的程序堆栈中创建环境和参数变量指针表,并返回此时的堆栈指针值sp

 create_tables

用戶内存中解析环境变量和参数字符串,创建指针表,并将地址放到堆栈上,返回栈指针

/** MAX_ARG_PAGES defines the number of pages allocated for arguments* and envelope for the new program. 32 should suffice, this gives* a maximum env+arg of 128kB !*/
#define MAX_ARG_PAGES 32/** create_tables() parses the env- and arg-strings in new user* memory and creates the pointer tables from them, and puts their* addresses on the "stack", returning the new stack pointer value.*/
static unsigned long * create_tables(char * p,int argc,int envc)
{unsigned long *argv,*envp;unsigned long * sp;//堆栈指针是以4字节为边界寻址sp = (unsigned long *) (0xfffffffc & (unsigned long) p);//sp向下移动,空出环境参数占用空间个数,让环境参数指针envp指向该处sp -= envc+1;envp = sp;//sp向下移动,空出环境参数占用的空间个数,并让环境参数指针envp指向该处sp -= argc+1;argv = sp;//argc、argv、envpput_fs_long((unsigned long)envp,--sp);put_fs_long((unsigned long)argv,--sp);put_fs_long((unsigned long)argc,--sp);//argcwhile (argc-->0) {put_fs_long((unsigned long) p,argv++);while (get_fs_byte(p++)) /* nothing */ ;}//最后放置NULLput_fs_long(0,argv);//envcwhile (envc-->0) {put_fs_long((unsigned long) p,envp++);while (get_fs_byte(p++)) /* nothing */ ;}//最后放置NULLput_fs_long(0,envp);return sp;
}

count

计算参数个数

/** count() counts the number of arguments/envelopes*/
static int count(char ** argv)
{int i=0;char ** tmp;if ((tmp = argv))//判断为NULL就退出while (get_fs_long((unsigned long *) (tmp++)))i++;return i;
}

copy_string

函数从用户内存空间拷贝参数和环境字符串到内核空闲页面内存中,argc

/** 'copy_string()' copies argument/envelope strings from user* memory to free pages in kernel mem. These are in a format ready* to be put directly into the top of new user memory.** Modified by TYT, 11/24/91 to add the from_kmem argument, which specifies* whether the string and the string array are from user or kernel segments:* * from_kmem     argv *        argv ***    0          user space    user space*    1          kernel space  user space*    2          kernel space  kernel space* * We do this by playing games with the fs segment register.  Since it* it is expensive to load a segment register, we try to avoid calling* set_fs() unless we absolutely have to.*/
static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,unsigned long p, int from_kmem)
{char *tmp, *pag=NULL;int len, offset = 0;unsigned long old_fs, new_fs;if (!p)return 0;	/* bullet-proofing */new_fs = get_ds();old_fs = get_fs();if (from_kmem==2)set_fs(new_fs);while (argc-- > 0) {if (from_kmem == 1)set_fs(new_fs);if (!(tmp = (char *)get_fs_long(((unsigned long *)argv)+argc)))panic("argc is wrong");if (from_kmem == 1)set_fs(old_fs);len=0;		/* remember zero-padding *///计算字符串的长度do {len++;} while (get_fs_byte(tmp++));//字符串长度判断if (p-len < 0) {	/* this shouldn't happen - 128kB */set_fs(old_fs);return 0;}while (len) {--p; --tmp; --len;//首次复制字符串,offset复制为0if (--offset < 0) {//p指针在页内的偏移offset = p % PAGE_SIZE;//恢复fs段寄存器if (from_kmem==2)set_fs(old_fs);//如果pag不为NULL,说明页面在之前的拷贝过程得到分配//pag指针为NULL,说明该页面还没有分配内存空间if (!(pag = (char *) page[p/PAGE_SIZE]) &&!(pag = (char *) (page[p/PAGE_SIZE] =(unsigned long *) get_free_page()))) return 0;if (from_kmem==2)set_fs(new_fs);}*(pag + offset) = get_fs_byte(tmp);}}//还原fsif (from_kmem==2)set_fs(old_fs);return p;
}

修改局部描述符表中的描述符基址和段限长,并将参数和环境页面放置在数据段末端

参数:text_size 执行文件头部中a_text字段给出的代码段长度值,page参数和环境空间页面指针数组

static unsigned long change_ldt(unsigned long text_size,unsigned long * page)
{unsigned long code_limit,data_limit,code_base,data_base;int i;
//根据执行文件头部a_text的值,计算以页面长度为边界代码段限长,并设置数据段长度为64MBcode_limit = text_size+PAGE_SIZE -1;code_limit &= 0xFFFFF000;data_limit = 0x4000000;
//取当前进程中局部描述符代码段描述符中代码段基地址,代码段基址和数据段基址相同code_base = get_base(current->ldt[1]);data_base = code_base;
//重新设置局部表中代码段和数据描述符的基址和段限长set_base(current->ldt[1],code_base);set_limit(current->ldt[1],code_limit);set_base(current->ldt[2],data_base);set_limit(current->ldt[2],data_limit);
/* make sure fs points to the NEW data segment */__asm__("pushl $0x17\n\tpop %%fs"::);data_base += data_limit;for (i=MAX_ARG_PAGES-1 ; i>=0 ; i--) {data_base -= PAGE_SIZE;if (page[i])put_page(page[i],data_base);}return data_limit;
}

execve系统中断调用函数,加载并执行子进程

函数系统中断调用int 0x80功能号__NR_execve,

参数:eip指向堆栈中调用系统中断的程序代码指针eip,

tmp:_sys_execve时返回地址

filename 被执行程序文件名

argv命令行参数指针数组

envp环境变量指针数组

/** 'do_execve()' executes a new program.*/
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 (current->egid == 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)) {/** This section does the #! interpretation.* Sorta complicated, but hopefully it will work.  -TYT*/char buf[1023], *cp, *interp, *i_name, *i_arg;unsigned long old_fs;strncpy(buf, bh->b_data+2, 1022);brelse(bh);iput(inode);buf[1022] = '\0';if ((cp = strchr(buf, '\n'))) {*cp = '\0';for (cp = buf; (*cp == ' ') || (*cp == '\t'); cp++);}if (!cp || *cp == '\0') {retval = -ENOEXEC; /* No interpreter name found */goto exec_error1;}interp = i_name = cp;i_arg = 0;for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) {if (*cp == '/')i_name = cp+1;}if (*cp) {*cp++ = '\0';i_arg = cp;}/** OK, we've parsed out the interpreter name and* (optional) argument.*/if (sh_bang++ == 0) {p = copy_strings(envc, envp, page, p, 0);p = copy_strings(--argc, argv+1, page, p, 0);}/** Splice in (1) the interpreter's name for argv[0]*           (2) (optional) argument to interpreter*           (3) filename of shell script** This is done in reverse order, because of how the* user environment and arguments are stored.*/p = copy_strings(1, &filename, page, p, 1);argc++;if (i_arg) {p = copy_strings(1, &i_arg, page, p, 2);argc++;}p = copy_strings(1, &i_name, page, p, 2);argc++;if (!p) {retval = -ENOMEM;goto exec_error1;}/** OK, now restart the process with the interpreter's inode.*/old_fs = get_fs();set_fs(get_ds());if (!(inode=namei(interp))) { /* get executables inode */set_fs(old_fs);retval = -ENOENT;goto exec_error1;}set_fs(old_fs);goto restart_interp;}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 */if (current->executable)iput(current->executable);current->executable = inode;for (i=0 ; i<32 ; i++)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)-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->euid = e_uid;current->egid = e_gid;i = ex.a_text+ex.a_data;while (i&0xfff)put_fs_byte(0,(char *) (i++));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);
}

http://www.shuangfujiaoyu.com/news/20717.html

相关文章:

  • 宁波建站模板免费建站网站一站式
  • 网站建设英语网络营销的好处
  • 英语网站新增两个栏目广州网站优化服务商
  • 怎么在虚拟空间做两个网站武汉网站建设优化
  • 制作网页要钱吗西安网站关键词优化推荐
  • 免费空间的个人网站免费加客源
  • 如何通过国外社交网站做外销企业网站注册域名的步骤
  • 建网站用的域名多少钱郑州网站营销推广
  • 样式模板网站网站推广的四个阶段
  • 深圳网页设计教程seo优化顾问
  • 网站建设费用表优化方案官方网站
  • 网络用户提要求找人帮忙做的网站指数基金排名前十名
  • asp网站防注入代码企业网站的推广阶段
  • 网站模板建设二级目录刷赞网站推广免费链接
  • 什么是专门型的网站如何优化网络连接
  • 广州知名网站建设哪家公司好官网优化哪家专业
  • 布吉网站建设多少钱seo排名系统源码
  • 中国建设银行武汉招聘信息网站收录优美的图片app
  • 做网站通栏模糊丁香人才网官方网站
  • 泉州企业网站建站模板怎么有自己的网站
  • asp.net空网站黑马培训
  • 如何做强企业网站外链工具软件
  • 巴彦淖尔网站制作百度指数支持数据下载吗
  • 设计网站费用搜索引擎营销的内容有哪些
  • 网站演示程序18种最有效推广的方式
  • wordpress save post西安seo建站
  • thinkphp网站优化网络推广软文范文
  • 深圳做兼职的网站哪些网站可以免费申请域名
  • 如何做网站联盟营销百度上怎么免费开店
  • 做日语问卷调查的网站seo搜索引擎优化工资薪酬