实现一个whoami 系统调用

系统调用的直观实现 问题+直观想法…

用户程序调用whoami, 一个字符串"systemcall "放在操作系统中(系统引导时载入) ,取出来打印,有什么问题?

  • 不能随意的调用数据,不能随意的jmp 。
  • 可以看到root 密码,可以修改它…
  • 可以通过显存看到别人word 里的内容…

地址:

main()

{ whoami();}

用户程序

。。。

whoami()

{

printf(100, 8);

}

内核,都在内存中,这内存不都是我买的吗…

100:

"systemcall"

内核( 用户) 态,内核( 用户)

将内核程序和用户程序 隔离!!!

区分 内核态和用户态 :一种处理器"硬件设计"

  • 内核态可以访问任何数据,用户态不能访问内核数据
  • 对于指令跳转也一样实现了隔离…

硬件提供了"主动进入内核的方法"

对于Intel x86 ,那就是中断指令int

  • int 指令将使CS 中的CPL 改成0 ,"进入内核"(此时,CPL=3 而DPL=0)
  • 这是用户程序发起的调用内核代码的唯一方式
  • 系统调用的核心:

(1) 用户程序 中包含一段包含int 指令 的代码

(2) 操作系统 写 中断处理 ,获取想调程序的编号

(3) 操作系统 根据编号执行相应代码

系统调用的实现

最终展开成包含int 指令的代码…

#include <unistd.h>

_syscall3(int, write, int, fd, const char *buf, off_t, count)

在linux/lib/write.c 中

#define _syscall3(type, name, ...) type name(...) \

{ __asm__ ("int 0x80" :"=a"(__res)...}

在linux/include/unistd.h 中

Linux 系统调用的实现细节!

将关于write 的故事完整的讲完…

在linux/include/unistd.h中    _syscall3 表示有3 个参数

#define _syscall3(type,name,atype,a,btype,b,ctype,c)\

type name(atype a, btype b, ctype c) \

{ long __res;\

__asm__ volatile("int 0x80":"=a"(__res):""(__NR_##name),

"b"((long)(a)),"c"((long)(b)),"d"((long)(c)))); if(__res>=0) return

(type)__res; errno=-__res; return -1;}

显然,__NR_write 是系统调用号,放在eax 中

在linux/include/unistd.h 中

#define __NR_write 4 // 一堆连续正整数( 数组下标,函数表索引)

同时eax 也存放返回值,ebx ,ecx ,edx 存放3 个参数

int 0x80 中断的处理

void sched_init(void)

{ set_system_gate(0x80,&system_call); }

显然,set_system_gate 用来设置0x80

在linux/include/asm/system.h 中

#define set_system_gate(n, addr) \

_set_gate(&idt[n],15,3,addr); //idt 是中断向量表基址

#define _set_gate(gate_addr, type, dpl, addr)\

__asm__("movw %%dx,%%ax\n\t" "movw %0,%%dx\n\t"\

"movl %%eax,%1\n\t" "movl %%edx,%2":\

:"i"((short)(0x8000+(dpl<<13)+type<<8))),"o"(*(( \

char*)(gate_addr))),"o"(*(4+(char*)(gate_addr))),\

"d"((char*)(addr),"a"(0x00080000))

中断处理程序: system_call

在linux/kernel/system_call.s

nr_system_calls=72

.globl _system_call

_system_call: cmpl $nr_system_calls-1,%eax //eax 中存放的是系统调用号

ja bad_sys_call

push %ds push %es push %fs

pushl %edx pushl %ecx pushl %ebx // 调用的参数

movl $0x10,%edx mov %dx,%ds mov %dx,%es // 内核数据

movl $0x17,%edx mov %dx,%fs //fs 可以找到用户数据

call _sys_call_table(,%eax,4) //a(,%eax,4)=a+4*eax

pushl %eax // 返回值压栈,留着ret_from_sys_call 时用

... // 其他代码

ret_from_sys_call: popl %eax, 其他pop, iret

_sys_call_table+4*%eax 就是相应系统调用处理函数入口

_sys_call_table

call _sys_call_table(,%eax,4) 就是call sys_write // eax=4 ,函数入口地址长度也为4

[No000036]操作系统Operating Systems系统调用的实现System_Call的更多相关文章

  1. [No00003D]操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock

    操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock 可以操刀了—从纸上到实际 从Linux 0.11 那里学点东西… 读磁盘 ...

  2. [No00003A]操作系统Operating Systems 内核级线程Kernel Threads内核级线程实现Create KernelThreads

    开始核心级线程 内核级线程对多核的支持怎么样? 和用户级相比,核心级线程有什么不同? ThreadCreate 是系统调用,内核管理TCB ,内核负责切换线程 如何让切换成型? − − 内核栈,TCB ...

  3. [No00003C]操作系统Operating Systems进程同步与信号量Processes Synchronization and Semaphore

    操作系统Operating Systems进程同步与信号量Processes Synchronization and Semaphore 进程合作:多进程共同完成一个任务 从纸上到实际:生产者− − ...

  4. [No000037]操作系统Operating Systems操作系统历史与硬件概况History of OS & Summaries!

    培根:读史使人明智 操作系统的简史 (1955-1965) 计算机非常昂贵,上古神机IBM7094 ,造价在250万美元以上 计算机使用原则:只专注于计算 批处理操作系统(Batch system) ...

  5. [No000039]操作系统Operating Systems用户级线程User Threads

    多进程是操作系统的基本图像 是否可以资源不动而切换指令序列? 进程 = 资源 + 指令执行序列 线程: 保留了并发的优点,避免了进程切换代价 实质就是映射表不变而PC 指针变 多个执行序列+ 一个地址 ...

  6. [No000038]操作系统Operating Systems -CPU

    管理CPU ,先要使用CPU… CPU 的工作原理 CPU上电以后发生了什么? 自动的取指 — 执行 CPU 怎么工作? CPU怎么管理? 管理CPU 的最直观方法 设好PC 初值就完事! 看看这样做 ...

  7. [No000031]操作系统 Operating Systems 之Open the OS!

    从打开电源开始… 这神秘的黑色背后发生着什么?… 打开电源,计算机执行的第一句指令什么? 计算模型(图灵机) ⇒ 我们要 关注 指针IP 及其 指向的内容 看看x86 PC (1) 刚开机时CPU 处 ...

  8. Modern Operating Systems(Ⅰ)——2014.12.15

    进程   进程模型     进程就是一个正在执行的程序的实例  值得注意的是,若一个程序运行了两遍,则算作两个进程 创建进程 在通用系统中,有四种主要事件导致进程的创建 ①系统的初始化 ②执行了 正在 ...

  9. Operating Systems (COMP2006)

    Operating Systems (COMP2006) 1st Semester 2019Page 1, CRICOS Number: 00301JOperating Systems (COMP20 ...

随机推荐

  1. SharePoint 2013 Designer 自定义操作菜单

    众所周知,我们在SharePoint的二次开发中,经常会添加ECB菜单或者Ribbon菜单,通常我们会采取Feature的方式去添加一个Xml,或者采取JavaScript的方式,当然,除此之外,还可 ...

  2. JavaScript MVC框架和语言总结[infoq]

    infoq关于javascript的语言和框架的总结,非常全面,值得一读. http://www.infoq.com/minibooks/emag-javascript Contents of the ...

  3. Java---Condition控制线程通信

    java中控制线程通信的方法有:1.传统的方式:利用synchronized关键字来保证同步,结合wait(),notify(),notifyAll()控制线程通信.不灵活. 2.利用Conditio ...

  4. Content-Type: application/vnd.ms-excel">

    如果要将查询结果导出到Excel,只需将页面的Context-Type修改一下就可以了:   header( "Content-Type: application/vnd.ms-excel& ...

  5. LinkedHashMap及其源码分析

    以下内容基于jdk1.7.0_79源码: 什么是LinkedHashMap 继承自HashMap,一个有序的Map接口实现,这里的有序指的是元素可以按插入顺序或访问顺序排列: LinkedHashMa ...

  6. Sqlite学习笔记(二)&&性能测试

    测试目标 获取SQlite的常规性能指标 测试环境 CPU:8核,Intel(R) Xeon(R) CPU E5-2430 0 @ 2.20GHz 内存:16G 磁盘:SSD Linux 2.6.32 ...

  7. 一次进程hang住问题分析。。。

    这两天有同学使用数据校验工具时发现进程hang住了,也不知道什么原因,我简单看了看进程堆栈,问题虽然很简单,但能导致程序hang住,也一定不是小问题.简单说明下程序组件的结构,程序由两部分构成,dbc ...

  8. hibernate总记录数查询和分页查询

    //参考代码 //第一种方法: String hql = "select count(*) from User as user"; Integer count = (Integer ...

  9. (1)编写一个接口ShapePara,要求: 接口中的方法: int getArea():获得图形的面积。int getCircumference():获得图形的周长 (2)编写一个圆类Circle,要求:圆类Circle实现接口ShapePara。 该类包含有成员变量: radius:public 修饰的double类型radius,表示圆的半径。 x:private修饰的double型变量x,

    package com.hanqi.test; //创建接口 public interface ShapePara { //获取面积的方法 double getArea(); //获取周长的方法 do ...

  10. Oracle12c安装出错

    Database Configuration Assistant安装失败 向广大园友求助