当前位置: 首页 > 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.tj-hxxt.cn/news/26978.html

相关文章:

  • 某企业网站搜索引擎优化佛山市seo推广联系方式
  • 网站建设前景网络营销专业课程
  • 网站前置审核申请报告seo排名技术教程
  • 网站开发颜色选择器肇庆seo
  • 建筑网站夜里几点维护漯河网络推广哪家好
  • 如何做网站链接分享朋友圈免费的seo网站下载
  • 男朋友抱着我在教室做网站营销型网站策划书
  • 医院网站建设 费用浙江企业seo推广
  • 能自己做效果图的网站seo少女
  • 苏州建设工程检测协会网站2021近期时事新闻热点事件简短
  • 幼儿园网站建设的好处网站seo方案撰写
  • 文本文档写入代码做网站win10优化大师官网
  • wordpress删除作者信息济南网站优化培训
  • 颐高养生园网站建设百度信息流怎么收费
  • 做网站法人拍照背景seo网站排名全选
  • 咸阳营销型网站建设临沂seo推广外包
  • 怎样做商城网站的推广seo网络优化是做什么的
  • 深圳网站建设php网络营销属于什么专业类型
  • 电商网站搭建流程长沙推广引流
  • 云南高端网站建设公司网站建设计划书
  • 苹果电脑适合网站开发人员比较靠谱的网站
  • 装饰设计师在哪个平台上寻找seo网址大全
  • 工业和信息化部网站备案系统查询seo排名资源
  • 如何建设一个好的企业网站seo快速排名源码
  • 盐城市城乡和住房建设厅网站快速排名点击工具
  • 网站开发数据库有关合同最新舆情信息网
  • 深圳做二维码网站设计免费发广告的软件
  • 带有响应式的网站合肥seo管理
  • wordpress是怎么添加登录的seo怎么去优化
  • 做的网站为什么图片看不了怎么回事搜索引擎优化的步骤