读Kernel感悟-伪装现场-系统调用参数

基于Landsat-8数据的山西省吕梁市地表温度反演研究过程(大气校正法) 1.数据下载:本实验采用的数据是 ①从地理空间数据云下载的来自landsat8 卫星,云量<=1%,时间为2017年5月12日的山西省吕梁市影像数据。为全面覆盖吕梁市,选用了两片影像。 ②吕梁市边界矢量图 2.数据预处理 ... 阅读详情

文章来源:http://www.top-e.org/jiaoshi/class/


内核支配了整个计算机的硬件资源,好像一位独裁者,高高在上。他有时候必须像法官一样公正,有时候则必须像狐狸一样狡猾。伪装现场就是他的拿手好戏。

系统调用是很特别的函数,因为它里面实现了用户态到内核态的转换。应用程序要创建新进程,不可能在用户态直接调用sys_fork()。这就需要内核为sys_fork()伪装一下调用现场。

比如fork()系统调用,它有一个简洁得不能再简洁的接口。不过它在内核中的对应函数中的声明却是:

asmlinkage int sys_fork(struct pt_regs regs)

如果有兴趣看早期的Linux源代码版本(0.95),它的声明是这样的:

int sys_fork(long ebx,long ecx,long edx,

 

long esi, long edi, long ebp, long eax, long ds,

 

long es, long fs, long gs, long orig_eax,

 

long eip,long cs,long eflags,long esp,long ss)

这些参数是如何来的呢。为什么用户态参数与内核态参数不一致?

又如clone(),vfork()这几个系统调用在用户态的参数个数和类型都不一样。但在内核态都致。

asmlinkage int sys_clone(struct pt_regs regs)

asmlinkage int sys_vfork(struct pt_regs regs)

接下去,我们可以看到,内核是多么巧妙地设置堆栈,让内核的函数感觉就好像上层函数在调用它一样。

 

我们很容易得知,这些参数是在系统调用进入内核时由int 0x80指令和SAVE_ALL宏把一些寄存器压入内核堆栈的。压入的寄存器数量和顺序是一致的,它们恰好与struct pt_regs一一对应。从这个角度讲,所有的系统调用获得的参数是形式是一样的。

026 struct pt_regs {

 

027         long ebx;

 

028         long ecx;

 

029         long edx;

 

030         long esi;

 

031         long edi;

 

032         long ebp;

 

033         long eax;

 

034         int  xds;

 

035         int  xes;

 

036         long orig_eax;

 

037         long eip;

 

038         int  xcs;

 

039         long eflags;

 

040         long esp;

 

041         int  xss;

 

042 };

其中xss到eip由int指令压入内核堆栈。orig_eax到ebx为ENTRY(system_call)压入堆栈。orig_eax为系统调用号。eax作为返回值。ebp~ebx作为系统调用的参数。

 

linux的系统调用在内核中对应函数如sys_fork()的声明前都有一个asmlinage的宏。它被定义为:

#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))

也就是说,所有的参数都通过堆栈传递。注意,这里的堆栈传递已经在内核态了,与系统调用参数通过寄存器传递并不矛盾(那个是之前在用户态到内核态的切换过程中)。

这样就意味着我们只要巧妙地设置好堆栈,让sys_fork()产生一种错觉,好像是上层的一个函数直接调用sys_fork()一样。事实上sys_fork()也的确可以在内核态直接调用。

我们又观察到:内核中_syscall0,_syscall1,_syscall2,。。。这些宏用来封装系统调用(只是内核自己用,glibc不用这些宏而已。)传递参数的方式是这样的:参数1~参数6正好放在ebx ecx edx esi edi ebp中,这恰好与pt_regs中的顺序相对应。为什么采用这样的一种顺序呢?

1.这与编译器的编译规则有关。标准的C函数编译时,总是从右往左依次把参数压入堆栈。执行到函数内部时,就根据这样的规则依次从堆栈中取出参数。所以在内核中也不例外。当应用程序执行系统调用,进入到内核态中的ENTRY(system_call)调用

call *sys_call_table(,%eax,4)

时,所有的参数都在堆栈中准备就绪。

具体这些参数怎么理解,就取决于函数的定义了。

如果认为内核堆栈中放的是个结构体pt_regs,就可以定义为

asmlinkage int sys_fork(struct pt_regs regs)

如果认为内核堆栈中放的是一个个整数,就可以定义为

asmlinkage int sys_fork(long ebx,long ecx,long edx,

 

long esi, long edi, long ebp, long eax, long ds,

 

long es, long fs, long gs, long orig_eax,

 

long eip,long cs,long eflags,long esp,long ss)

其它的系统调用也类似。

通过巧妙的构造堆栈,达到调用内核函数的目的。

除了系统调用,还有其它函数如do_page_fault()等等,也是用类似的手段。

51单片机也能玩转信号发生器?手把手教你用DAC0832和LM358输出四种标准波形 本文详细介绍了如何使用51单片机和DAC0832芯片搭配LM358运放,自制低成本信号发生器,实现正弦波、矩形波、三角波和锯齿波四种标准波形的输出。从硬件选型、电路设计到编程实现,手把手教你完成这一实用电子项目,总成本不到50元,适合电子爱好者和学生实践。 阅读详情

相关推荐

手把手教你用ROS2控制PX4无人机画个圆:从C++代码到Gazebo仿真全流程解析

本文详细解析了如何使用ROS2控制PX4无人机实现圆形轨迹飞行,涵盖从C++代码编写到Gazebo仿真的全流程。重点介绍了Offboard模式下的控制算法实现、圆形轨迹生成的数学原理,以及解决通信延迟和坐标系转换等常见问题的实用技巧。通过实战案例,帮助开发者快速掌握无人机轨迹跟踪仿真的核心技术。

weixin_30839881的博客 59

Linux 进程管理之内核栈和struct pt_regs

Linux 进程管理之内核栈和struct pt_regs简介

小立仔 5066

【ChangeCLIP】Remote sensing change detection with multimodal vision-language representation learning

ChangeCLIP论文及代码使用详解。持续更新变化检测最新论文,欢迎订阅本专栏。

向上生长的程序媛的博客 1300

Ptrace学习(1)

跟随玩转ptrace的文章跑示例的时候提示出错。 代码: #include #include #include #include #include /* For constantsORIG_EAX etc */ int main() { pid_t child;longorig_eax; child =fork(); if(child ==0) { ptrace(PTR

u011288590的专栏 800

linux内核-系统调用

如果说外部中断是使CPU被动地、异步地进入系统空间的一种手段,那么系统调用就是CPU主动地、同步地进入系统空间的手段。这里所谓主动,是指CPU自愿的、事先计划好了的行为。而同步则是说,CPU(实际上是软件的设计人员)确切地知道在执行哪一条指令以后就一定会进入系统空间。相比之下,中断的发生带有很大的不可预测性。但是,尽管有着这样的区别,二者之间还是由很大的共性。这是因为,在使CPU的运行状态从用户态转入系统态,也就是从用户空间进入系统空间,这一个基本点上二者是一致的。当然,中断有可能发生在CPU已经运行在系统

guoguangwu的专栏 1137

ORIG_EAX

代码: 00050: EBX       = 0x00 00051: ECX       = 0x04 00052: EDX       = 0x08 00053: ESI       = 0x0C 00054: EDI       = 0x10 00055: EBP       = 0x14 00056: EAX       = 0x18 00057: DS       =

zuihoudebingwen的专栏 3266

中断学习之下半部深入理解

Linux 软中断机制分析http://blog.jobbole.com/107057/linux 内核软中断详解http://blog.sae.sina.com.cn/archives/4103总结一下linux软中断的实现http://blog.chinaunix.net/uid-145571-id-2798845.htmlkernel中断分析七——tasklethttps://blog.cs............

shipinsky的博客 559

Kernel感悟-伪装现场-内核线程

文章来源:http://www.top-e.org/jiaoshi/class/众所周知,内核中创建一个内核线程是通过kernel_thread实现的。声明如下:int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);我们知道,用户态创建线程调用clone(),如果要在内核态创建线程,首先想到的是在内核

李亚锋老师 1743

pt_regs结构

struct pt_regs { long ebx;                  //可执行文件路径的指针(regs.ebx中 long ecx;                  //命令行参数的指针(regs.ecx中) long edx;                  //环境变量的指针(regs.edx中)。 long esi; long edi; long ebp;

helloworlddm的博客 7343

Linux进程管理(三)内核栈与结构体struct pg_regs、struct thread_info

Linux内核需要存储每个进程的PCB信息, linux内核是支持不同体系的的, 而不同的体系结构可能进程需要存储的信息不尽相同, 这就需要实现一种通用的方式将体系结构相关的部分和无关的部门进行分离,而thread_info就保存了特定体系结构的汇编代码段需要访问的那部分进程的数据。

weixin_44555799的博客 1429

Linux中pt_regs结构体

系统调用所需要的参数pt_regs在include/asm-i386/ptrace.h文件中定义:struct pt_regs {long ebx;                  //可执行文件路径的指针(regs.ebx中long ecx;                  //命令行参数的指针(regs.ecx中)long edx;                  //环境变量的指针(...

weixin_33788244的博客 876

真实样本分析堆栈欺骗技术

调用堆栈欺骗并不是一种新技术,但在过去几年中它变得越来越流行。调用堆栈是EDR软件的遥测源,可用于确定进程是否执行了可疑操作(向类进程请求句柄、将可疑代码写入新分配的区域,等等)。该技术的目的是构建一个模拟合法调用堆栈的假调用堆栈,以隐藏可能被EDR或其他安全软件检测到的可疑活动。

博客地址 www.sec0nd.top 1268

struct pt_regs 中存的内容

23 /* this struct defines the way the registers are stored on the 24    stack during a system call. */25 26 struct pt_regs {27         long ebx;28         long ecx;29         long edx;30         long

abo8888882006的专栏 4554

关于Linux线程的线程栈以及TLS

说明: a.本文描述Linux NPTL的线程栈简要实现以及线程本地存储的原理,实验环境中Linux内核版本为2.6.32,glibc版本是2.12.1,Linux发行版为ubuntu,硬件平台为x86的32位系统。b.对于Linux NPTL线程,有很多话题。本文挑选了原则上是每线程私有的地址空间来讨论,分别是线程栈和TLS。原则山私有并不是真的私有,因为大家都知道线程的特点就是共享地址空间,原...

系统运维 468

linux内核-页面异常的进入返回

我们在内存管理中介绍内对页面异常处理时,是从do_page_fault开始的。当时因为尚未介绍CPU的中断和异常机制,所以暂时跳过了对页面异常的响应过程,也就是从发生异常至CPU到达do_page_fault之间的那一段路程,以及do_page_fault返回之后到CPU返回到用户空间这一段路程。我们可以来补上这个缺口了。 与外设中断不同,各种异常都有为其保留的专用中断向量,因此相应的初始化也是直截了当的,这一点我们已经在初始化的博客中看到了。 为页面异常设置的中断门指向程序入口page_fault(见

guoguangwu的专栏 511

ptrace使用简介

ptrace 提供了一种机制使得父进程可以观察和控制子进程的执行过程,ptrace 还可以检查和修改子进程的可执行文件在内存中的image及子进程所使用的寄存器中的值。通常来说,主要用于实现对进程插入断点和跟踪子进程的系统调用。 用法示例 #include <sys/ptrace.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <linux/us

我的博客 1314

linux系统学习1:系统调用

glibc 对系统调用的封装 在用户态进程里面调用 open 函数 int open(const char *pathname, int flags, mode_t mode) 64 位系统调用过程: x86_64 下的 sysdep.h 文件 /* The Linux/x86-64 kernel expects the system call parameters in registers according to the following table: syscall nu...

Linzhongyilisha的专栏 1148

【深入理解计算机系统csapp】程序的机器级表示|x86-64寄存器

文章目录x86-64寄存器名称x86-64寄存器作用操作数种类立即数表示寻址方式mov指令leap指令位移指令乘法指令跳转指令call指令AT&T入栈及出栈tips x86-64寄存器名称 x86-64寄存器起名:8位,%al;16位,%ax;32位,%eax;64位,%rax x86-64寄存器作用 %rax: 返回值 %rbx: 被调用者保存 %rcx: 第4个参数 %rdx: 第3个参数 %rsi: 第2个参数 %rdi: 第1个参数 %rbp: 被调用者保存 %rsp: 栈指针 %r8: 第

m0_52427832的博客 2481

如何查出某个宏定义在哪个头文件内?

yang@yang:~$ sudo find /usr/include/ -name *.h | xargs grep 'ORIG_EAX' /usr/include/reg.h:# define ORIG_EAX 11 /usr/include/x86_64-linux-gnu/asm/ptrace-abi.h:#define ORIG_EAX 11

杨龙飞的博客 4097

poi-ooxml-5.4.0.jar中文文档.zip

1、压缩文件中包含:中文文档、jar包下载地址、Maven依赖、Gradle依赖、源代码下载地址。2、使用方法:解压最外层zip,再解压其中的zip包,双击 【index.html】 文件,即可用浏览器打开、进行查看。3、特殊说明:(1)本文档为人性化翻译,精心制作,请放心使用;(2)只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等;(3)不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。4、温馨提示:(1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地);(2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅本篇描述,以确保这就是你需要的文件。5、本文件关键字:jar中文文档.zip,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册。

BesIII软件系统强化课程PPT.ppt

BesIII软件系统强化课程PPT.ppt

上一篇: 读Kernel感悟-Linux内核启动-链接脚本
下一篇: 读Kernel感悟-伪装现场-内核线程
TopEmbedded
博客等级 码龄18年 58粉丝 61原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值