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

山西省住房和城乡建设厅门户网官方网站旧房翻新装修公司排名

山西省住房和城乡建设厅门户网官方网站,旧房翻新装修公司排名,外贸网站推广技巧,效果好的徐州网站建设Linux-0.11 文件系统exec.c详解 模块简介 该模块实现了二进制可执行文件和shell脚本文件的加载和执行。 函数详解 create_tables static unsigned long * create_tables(char * p,int argc,int envc)该函数的作用是建立参数和环境变量指针表。 create_table的作用就是建立…Linux-0.11 文件系统exec.c详解 模块简介 该模块实现了二进制可执行文件和shell脚本文件的加载和执行。 函数详解 create_tables static unsigned long * create_tables(char * p,int argc,int envc)该函数的作用是建立参数和环境变量指针表。 create_table的作用就是建立指针表去指向copy_string拷贝的字符串。 unsigned long *argv,*envp;unsigned long * sp;sp (unsigned long *) (0xfffffffc (unsigned long) p);sp - envc1;envp sp;sp - argc1;argv sp;put_fs_long((unsigned long)envp,--sp);put_fs_long((unsigned long)argv,--sp);put_fs_long((unsigned long)argc,--sp);while (argc--0) {put_fs_long((unsigned long) p,argv);while (get_fs_byte(p)) /* nothing */ ;}put_fs_long(0,argv);while (envc--0) {put_fs_long((unsigned long) p,envp);while (get_fs_byte(p)) /* nothing */ ;}put_fs_long(0,envp);return sp;count static int count(char ** argv)该函数用于计算参数的个数。 argv数组的最后一项是NULL以此作为循环终止的条件。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aRmQGiRv-1685200650093)(null)] int i0;char ** tmp;if ((tmp argv))while (get_fs_long((unsigned long *) (tmp)))i;return i;copy_strings static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,unsigned long p, int from_kmem)该函数的作用是从用户拷贝命令行参数和环境字符串拷贝到内核空间。 在do_execve函数中定义了一个page数组unsigned long page[MAX_ARG_PAGES]该数组定义在内核空间中用于存储用户态传递过来的环境参数和命令行参数。初始时程序定义了一个指向该空间末端(128k-4)处的空间偏移量p, 当随着环境参数和命令行参数的拷贝p指针将向前进行移动 如下图所示 在函数的内部考虑了参数不处于用户空间的场景使用from_kmen为了便于理解可以默认from_kmen0。 * from_kmem argv * argv *** 0 user space user space* 1 kernel space user space* 2 kernel space kernel space该函数在开始处定义了一些参数并获取处ds寄存器和fs寄存器的值。 char *tmp, *pagNULL;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_kmem2)set_fs(new_fs);接下来,因此传入的参数的数量argc个因此对其进行遍历依次将其拷贝到page数组中。 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);len0; /* remember zero-padding */do {len;} while (get_fs_byte(tmp));//将tmp指向字符串的末端if (p-len 0) { /* this shouldnt happen - 128kB */set_fs(old_fs);return 0;}while (len) {//逐字节拷贝--p; --tmp; --len;if (--offset 0) {offset p % PAGE_SIZE;if (from_kmem2)set_fs(old_fs);if (!(pag (char *) page[p/PAGE_SIZE]) !(pag (char *) (page[p/PAGE_SIZE] get_free_page()))) return 0;if (from_kmem2)set_fs(new_fs);}*(pag offset) get_fs_byte(tmp);}}if (from_kmem2)set_fs(old_fs);return p;change_ldt static unsigned long change_ldt(unsigned long text_size,unsigned long * page)该函数的作用是修改LDT中段基址和段限长度 同时将参数和环境空间放置在数据段的末端。 unsigned long code_limit,data_limit,code_base,data_base;int i;code_limit text_sizePAGE_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 (iMAX_ARG_PAGES-1 ; i0 ; i--) {data_base - PAGE_SIZE;if (page[i])put_page(page[i],data_base);}return data_limit;do_execve int do_execve(unsigned long * eip,long tmp,char * filename,char ** argv, char ** envp)该函数的作用是用于加载并执行其他的程序。通常会跟着fork之后调用。 第一部分是变量的定义没啥好说的。 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 pPAGE_SIZE*MAX_ARG_PAGES-4; 下面这里是对变量的check。eip[1]实际上就是源程序的cs寄存器值。对于用户态的程序 TI字段为1RPL3代码段的序号为1因此cs寄存器的值为0x000f,因此如果eip[1] 0xffff的值不是0x000f,也就意味着execve是从内核进程调用的但是内核进程是不能被替换掉的因此这里进行检查。 | 段描述符索引 |TI | RPL | 0x0017 |0 0 0 0 0 0 0 0 0 0 0 1 0| 1 | 1 1 | 0x000f |0 0 0 0 0 0 0 0 0 0 0 0 1| 1 | 1 1 |if ((0xffff eip[1]) ! 0x000f)panic(execve called from supervisor mode);接下来根据文件的路径获取i节点。 if (!(inodenamei(filename))) /* get executables inode */return -ENOENT;然后统计参数和环境变量的个数。 argc count(argv); envc count(envp);如果inode不是常规文件则返回错误。 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)) {此时bh块中的数据内容已经被拷贝到了ex结构体中因此可以释放bh块。 接下来因为Linux-0.11只支持ZMAGIC格式可执行文件因此如果格式不等于ZMAGIC将直接返回错误。 此外如果可执行文件太大或者文件缺失不全那么也不能运行。首先如果程序的代码段数据段bss段的长度超过了50M则返回错误。 其次如果执行文件的长度小于代码段数据段符号表长度执行头)的长度也会返回错误。 brelse(bh); if (N_MAGIC(ex) ! ZMAGIC || ex.a_trsize || ex.a_drsize ||ex.a_textex.a_dataex.a_bss0x3000000 ||inode-i_size ex.a_textex.a_dataex.a_symsN_TXTOFF(ex)) {retval -ENOEXEC;goto exec_error2; }如果执行文件代码开始处没有位于1024字节边界处则也不能执行。 if (N_TXTOFF(ex) ! BLOCK_SIZE) {printk(%s: N_TXTOFF ! BLOCK_SIZE. See a.out.h., filename);retval -ENOEXEC;goto exec_error2; }如果sh_bang标志没有设置则复制指定个数的命令行参数和环境字符串到参数和环境空间。如果sh_bang为true代表是运行的脚本程序此时命令行参数和环境字符串已经进行了复制。 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;}}这里放回进程原来所需要执行的程序的i节点并让进程executable指向新执行文件的i节点。然后复位原进程的所有信号处理句柄。再根据执行时关闭文件句柄close_on_exec位图标志关闭指定的打开文件并复位该标志。 if (current-executable)iput(current-executable); current-executable inode; for (i0 ; i32 ; i)current-sigaction[i].sa_handler NULL; for (i0 ; iNR_OPEN ; i)if ((current-close_on_execi)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);接下来重新设置进程个字段的值。例如brka_texta_dataa_bss 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;如果执行文件的代码段加上数据段长度不在页面的边界上则将剩余部分置为0。 i ex.a_textex.a_data; while (i0xfff)put_fs_byte(0,(char *) (i)); eip[0] ex.a_entry; /* eip, magic happens :-) */ eip[3] p; /* stack pointer */ return 0;Q A
http://www.w-s-a.com/news/714120/

相关文章:

  • 罗源福州网站建设个体户可以网站备案吗
  • 网站开发 专有名词pc网站建设和推广
  • 上海部道网站 建设conoha wordpress
  • 手机测评做视频网站宝塔可以做二级域名网站么
  • 代理公司注册济南重庆seo优化效果好
  • 佛山市骏域网站建设专家徐州网站建设价格
  • 公司做网站多济南好的网站建设公司排名
  • 网站维护的方式有哪几种该网站在工信部的icp ip地址
  • 中小企业服务中心网站建设做考勤的网站
  • 大连网站建设报价wordpress实用功能
  • 学校网站建设自查报告电脑网站制作教程
  • 适合推广的网站世界搜索引擎公司排名
  • 合肥网站建设费用ppt在哪个软件制作
  • 湖南省住房和城乡建设厅门户网站网站建设课程性质
  • 如何设计公司网站公司网站空间要多大
  • 建筑公司网站排名5G网站建设要多少个
  • seo怎样新建网站弹簧东莞网站建设
  • 在线做爰直播网站石家庄房产
  • 建筑网站哪里找拓者设计吧首页
  • 广州网站的建设wordpress注册数学验证码
  • 装修平台自己做网站有几个黄页名录网站开发
  • php网站的安全优势平面设计师培训
  • 乐清市网站建设设计重庆沙坪坝区
  • 什么是seo站内优化开发网页的工具有哪些
  • 文化类网站是不是休闲娱乐类网站青州市建设局网站
  • 网站的中英文切换代码做现货黄金网站
  • 万江区网站建设公司前端如何根据ui设计写页面
  • 宿迁公司做网站手机免费创建网站的软件
  • 免费可商用素材网站山东威海网站开发
  • 建设网站什么语言比较合适柳州建设网经济适用房