JOS lab3 部分用户程序分析


JOS lab3 部分用户程序分析


在lab 4的分支里面,会有各种好玩的用户程序.如下:

JOS lab3 部分用户程序分析_第1张图片


觉得还是有必要一一对其进行简要的分析.自顶向下的了解OS的机制

分析的用户程序顺序随意,不按照难度排序


badsegment.c:

JOS lab3 部分用户程序分析_第2张图片

这里的唯一一行嵌入式汇编尝试把 0x28这个数赋值给数据段寄存器 DS


看这里Global describe table -- gdt, 

JOS lab3 部分用户程序分析_第3张图片


0x28就是对于CPU0来说的TSS0段的选择子.

JOS lab3 部分用户程序分析_第4张图片


把TSS0选择子移入ds数据寄存器是违法的,会触发异常保护T_GPFLT

修改各种段寄存器都要满足CPL和DPL关系条件的.必须触发系统调用,进入内核态,才能修改.

当前用户态的段CPL是3,那么就只能修改DPL是3的权限段,不能比这个权限高的,我们这里尝试修改原来的测试badsegment.c

如下:我该成了0x20,用户的数据段描述符.

JOS lab3 部分用户程序分析_第5张图片

运行情况,如下:

JOS lab3 部分用户程序分析_第6张图片

没有panic了....yes. 继续


breakpoint.c:

int $3尝试调用3号中断.

JOS lab3 部分用户程序分析_第7张图片

下面是 运行后挂掉的 trap frame

JOS lab3 部分用户程序分析_第8张图片



buggyhello.c:

JOS lab3 部分用户程序分析_第9张图片

这里尝试通过系统调用打印地址 0x1出的一个字符.系统完成启动之后,0x200000以下的内容都是empty memory.

这里太明显了,去访问没有映射的指针,会被我们之前lab4写好的 mem_check里的断言挂掉



buggyhello2.c:


JOS lab3 部分用户程序分析_第10张图片



这里尝试输出hello标记地址处的字符串,从注释里面会发现,作者的意图是直接销毁这个进程,但是,这里由于我们之前又写了断言在sys_cputs里面,于是这里要注释掉这行断言你才能看到预期的输出

JOS lab3 部分用户程序分析_第11张图片

输出如下:

JOS lab3 部分用户程序分析_第12张图片


divezero.c:

JOS lab3 部分用户程序分析_第13张图片


单步调试跟进去看:

JOS lab3 部分用户程序分析_第14张图片

是在指令ldiv的时候触发divide_error的


JOS lab3 部分用户程序分析_第15张图片


evilhello.c:

邪恶的hello,究竟怎么个邪恶法.

JOS lab3 部分用户程序分析_第16张图片

这里尝试用系统调用输出 0xf010000c地址出的100个字符.

我们知道虚拟地址0xf010000c对应的物理地址是0x10000c,这是刚开始的时候内核的入口地址

由于之前又做好了错误检查的部分.这里需要注释掉下图中的注释部分,不然访问内核高地址的尝试都没门..

这里需要把两个检测项都注释掉,因为,对于用户来说不仅仅内核高地址没有 PTE_U而且没有PTE_P,

JOS lab3 部分用户程序分析_第17张图片


输出会发现一开始还是尝试去解释这块地址出的一些数据,解释成字符,不过都是乱码.尔后进程被强制释放.

JOS lab3 部分用户程序分析_第18张图片



faultread.c:

这里我们初学C语言的时候,指针没学好,或警惕性不高的时候,没进行非空检查的话,就可能对NULL指针dereference.这是非法的.

JOS lab3 部分用户程序分析_第19张图片

上面这个测试程序会直接触发异常,然后挂掉系统.这里我们还没进行到lab 4,没有构建起用户空间触发的page fault的异常处理机制.后续到lab 4我会特别把这里例子再单独开一贴分析

JOS lab3 部分用户程序分析_第20张图片



faultreadkernel.c:

下面是尝试读取内核区数据的例子,用户程序是不允许访问这里的数据的

可以和上面那个 faultread.c做比较,上面的是访问0x00这个地址没有映射,于是出现的问题是确实PTE_P

这里的内核地址是有PTE_P,但是这里是不允许用户访问的.protection. 同是page fault,他们之间还是有稍许区别的.

JOS lab3 部分用户程序分析_第21张图片


JOS lab3 部分用户程序分析_第22张图片


关于 faultwrite.c faultwritekernel.c的分析和上述 faultread.c faultreadkernel.c同理.不再赘述.



hello.c:

JOS lab3 部分用户程序分析_第23张图片

深深的无力,感觉没啥好说的,这里就是访问thisenv这个全局变量,指向当前进程的struct env 

打印thisenv->env_id.相当于Linux里面的输出进程pid : )

值得说一下的是这里的输出信息,先从内核态通过trap进入了用户态打印输出了hello, world

而后由于thisenv指向的结构体都是由刚开始分配内存的时候envs指向的一连串结构体储存在内核地址内,于是这里需要访问内核,势必触发trap,进入内核态,访问并打印thisenv指针指向的结构体内的成员 env_id

JOS lab3 部分用户程序分析_第24张图片




testbss.c:

我们知道,未初始化的的全局变量会放入到可执行程序的bss段.

这里的bigarray就是个例子.分配了很大的空间这个为初始化的全局变量

JOS lab3 部分用户程序分析_第25张图片


程序先测试验证,全局未初始化的变量都默认初始值为0.

然后一个个赋值.检测也没问题.前面三个for循环都正常

尝试在申请的数组范围之外写入数据就会触发page fault.因此我们看不到后面的panic输出信息.(这还是在lab3的基础上的分析,因为这里没有用户态的page fault handler,如果是lab 4的话,系统不会这样挂掉,但是如果正常的处理机制还是不应该让程序继续运行了 : )

JOS lab3 部分用户程序分析_第26张图片



lab 3的分析告一段落~



JOS lab3 部分用户程序分析_第27张图片



你可能感兴趣的:(JOS lab3 部分用户程序分析)