x86使用execve执行一个elf文件并传递参数--代码思路分析

execve(const char *filename, char *const argv[ ], char *const envp[ ])

视频教程以及实际代码可以看这一个教程
其他的需要的知识
GDT表
GDT表虚拟内存
页表
任务切换
fork实现
elf文件加载

这一个是一个Linux下面的标准接口

这一个的实际作用的是执行一个可执行文件

把当前程序替换成要执行的程序, 而同时保留原程序运行的方法是,fork+exec

第二个参数是利用数组指针来传递给执行文件,并且需要以空指针(NULL)结束,最后一个参数则为传递给执行文件的新环境变量数组。

函数执行成功时没有返回值,执行失败时的返回值为-1.

#include<unistd.h>   
main()   
{   char *argv[ ]={"ls", "-al", "/etc/passwd", NULL};   char *envp[ ]={"PATH=/bin", NULL}   execve("/bin/ls", argv, envp);   
}  

实现的思路

CPU寄存器的初始化

在使用的时候需要一个新的页表, 记录这一个新的进程使用的地址信息

由于使用系调用的时候会记录进入的时候的CPU寄存器信息, 返回的时候弹出信息, 这一个新的进程再返回的时候, 首先使用是栈里面的记录的信息, 而不是tss表里面的信息

image-20240225191306270

返回的时候这里面的信息也需要进行更改, 如果不改变的话会返回之前的页表对应的位置

该变信息的时候可以使用tss里面的记录的esp0的值进行计算, 使用结构体syscall_frame_t(一个记录压栈时候寄存器顺序的结构体, 定位到对应的位置)

栈的初始化(参数传递)

在使用新的栈的时候, 设置esp需要减去一下系统调用的参数的位置(系统调用返回的时候使用retf会把栈里面的参数弹出来, 新的任务进入的时候栈里面没有这几个参数, 需要预留空间), 以及初始化一下main函数的参数在栈里面

image-20240225202348872

这里可以使用把所有的信息放在栈里面

实际的实现

//执行一个可执行文件
int sys_execve(char *name, char ** argv, char ** env){task_t *task = task_current();//获取当前的任务uint32_t new_page_dir = memory_create_uvm();//获取一个新的页表给任务使用uint32_t old_page_dir = task->tss.cr3;//记录一下现在使用的页表//使用这一个新的文件的名字初始化任务名字kernel_strncpy(task->name, get_file_name(name), TASK_NAME_SIZE);if(! new_page_dir){goto exec_failed;}//获取这一个的入口, 以及加载这一个文件到新的页表里面//这里实际是加载一个elf文件, 以及从文件头获取他的入口地址//这里需要注意的是实际使用的虚拟地址是还未使用的页表里面的//实际加载的时候需要对使用的内存申请, 映射, 复制uint32_t entry = load_elf_file(task, name, new_page_dir);if(entry == 0){goto exec_failed;} //预留一段空间放参数(main函数的参数)uint32_t stack_top = 栈的顶部虚拟地址 - 预留的参数保存地址;//为这一个任务的新页表申请一下栈空间int err = memory_alloc_for_page_dir(new_page_dir, MEM_TASK_STACK_TOP - MEM_TASK_STACK_SIZE(实际的虚拟地址最小值), MEM_TASK_STACK_SIZE()大小, 权限(用户可使用, 可写));if(err < 0){goto exec_failed;}int argc = strings_count(argv);//获取参数的个数//把这一个参数按照之前图里面的格式复制到栈里面预留的空间//之后main函数可以直接使用err = copy_args((char *)stack_top, new_page_dir, argc, argv);if(err < 0){goto exec_failed;}//获取记录了栈里信息的地址syscall_frame_t * frame = (syscall_frame_t *)(系统调用的时候记录的特权级esp - sizeof(syscall_frame_t)(实际压入的信息的大小));//改变特权级0的栈里面的信息用于返回frame->eip = entry;frame->eax = frame->ebx = frame->ecx = frame->edx = 0;frame->esi = frame->edi = frame->ebp = 0;frame->eflags = EFLAGS_DEFAULT | EFLAGS_IF; //预留一下栈里面参数的位置frame->esp = stack_top - sizeof(uint32_t) * SYSCALL_PARAM_COUNT;//栈里面需要有初始的参数的值task->tss.cr3 = new_page_dir;mmu_set_page_dir(new_page_dir);//销毁之前的页表memory_destroy_uvm(old_page_dir);return 0;exec_failed:if(new_page_dir){//错误处理}return -1;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/493288.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络设备和网络软件

文章目录 网络设备和网络软件网卡交换机交换机的三个主要功能交换机的工作原理第二层交换和第三层交换交换机的堆叠和级联 路由器路由器工作原理 网关网关的分类 无线接入点(AP)调制解调器网络软件 网络设备和网络软件 网卡 网络接口卡又称网络适配器&#xff0c;简称网卡。网…

五种多目标优化算法(MOFA、NSWOA、MOJS、MOAHA、MOPSO)性能对比(提供MATLAB代码)

一、5种多目标优化算法简介 多目标优化算法是用于解决具有多个目标函数的优化问题的一类算法。其求解流程通常包括以下几个步骤&#xff1a; 1. 定义问题&#xff1a;首先需要明确问题的目标函数和约束条件。多目标优化问题通常涉及多个目标函数&#xff0c;这些目标函数可能…

conda下tensorflow安装

conda create -n tf21 python3.7 conda activate tf21 conda install tensorflow-gpu2.1验证 import tensorflow as tf tf.test.is_built_with_cuda()

模版(初级)

一.泛型编程 当我们要写一个交换函数时&#xff0c;面对不同的类型&#xff0c;我们可能就需要向如下这么写&#xff1a; void Swap(int& left, int& right) {int temp left;left right;right temp; }void Swap(double& left, double& right) {double tem…

【随笔】固态硬盘数据删除无法恢复(开启TRIM),注意数据备份

文章目录 一、序二、机械硬盘和固态硬盘的物理结构与工作原理2.1 机械硬盘2.11 基本结构2.12 工作原理 2.2 固态硬盘2.21 基本结构2.22 工作原理 三、机械硬盘和固态硬盘的垃圾回收机制3.1 机械硬盘GC3.2 固态硬盘GC3.3 TRIM指令开启和关闭 四、做好数据备份 一、序 周末电脑突…

HQYJ 2024-2-26 作业

1.整理链表的代码 link.stack.h文件 #ifndef __LINK_STACK_H__ #define __LINK_STACK_H__ #include<stdio.h> #include<stdlib.h> typedef int datatype; typedef struct link_stack {datatype data;struct link_stack *next;}link_stack,*link_p; typedef struc…

【Java程序设计】【C00283】基于Springboot的校园志愿者管理系统(有论文)

基于Springboot的校园志愿者管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的校园志愿者管理系统 本系统分为系统功能模块、管理员功能模块以及志愿者功能模块。 系统功能模块&#xff1a;用户进入到系统…

vue3.0 ref的使用

一.在vue2中定义变量 在使用vue2的时候,我们定义变量会在data中进行定义&#xff0c;那么我们在vue3中是如何定义变量的呢&#xff1f;我们会使用ref来进行定义。 (1)我们通过一个简单的案例来看 代码&#xff1a; <template> <div><button click"coun…

matlab 凸轮轮廓设计

1、内容简介 略 46-可以交流、咨询、答疑 2、内容说明 略 4 取标段的分析 取标装置是贴标机的核心部件之一&#xff0c;是影响贴标质量和贴标精度的重要因素&#xff0c;取标段是通过取标板与标签的相切运动使得涂有胶水的取标板从标签盒中粘取标签纸[4]&#xff0c;理论…

DP读书:《半导体物理学(第八版)》(一)绪论 3min速通

DP读书&#xff1a;《半导体物理学&#xff08;第八版&#xff09;》刘恩科 3min速通半导体物理之绪论 DP读书&#xff1a;《半导体物理学&#xff08;第八版&#xff09;》刘恩科绪论第一章 半导体中的电子状态1.1 半导体的晶格结构和结合性质1.1.1 金刚石型结构和共价键1.1.2…

电子科技大学课程《操作系统原理与实践》(持续更新)

前言 本人学习采用的是学校老师出版的课本&#xff0c;教学顺序与部分内容可能有所不同&#xff0c;具体以自己老师的教学为准&#xff0c;适合同学期中和期末考试的复习。重点内容用#标记&#xff0c;#数量越多&#xff0c;越重要&#xff0c;电子科技大学学生可以先看附言&a…

C++ 学习之函数对象

C 函数对象基本概念 在C中&#xff0c;函数对象&#xff08;Function Objects&#xff09;是一种类或结构体&#xff0c;它重载了函数调用运算符operator()&#xff0c;因此可以像函数一样被调用。函数对象有时也被称为仿函数&#xff08;Functor&#xff09;。 以下是关于C函…