linux kprobe实现原理

linux kprobe使用 kprobe 阅读详情

linux kprobes

kprobes出现了非常长的时间,最早是2.6.9版本中,最早能够追溯到2004年,距离现在15年,一直没有为人所知,但却是隐藏在诸多技术后的一个基础组件,例如ftrace,perf,SystemTap,LTTng还有最近非常火热的ebpf.

kprobes是什么?
它是kernel probes(我翻译成探针),是一种debug机制,它是由IBM开发的,最初计划用来和另外一个工具DProbes配套使用的,但是只有kprobe被合并到mainline了而Dprobe没有被接受,不过也成就了它现在的trace基础地位。裸的kprobes使用起来有些复杂,它需要单独编写module,所以为了降低使用复杂度,kprobe不停的寻找和他能够配合的框架,才有了我们现在看到的ftrace,perf等。

kprobes可以用来干什么?
kprobes通常被用来查找性能瓶颈,记录指定的事件,用来trace,它理论上能够监视任何的事件,但是有一点:它实现不了gdb的watch功能。目前它主要作为ftrace,ebpf,SystemTap等框架和工具的后端存在,主要用来做日志了,看起来它也混的挺憋屈的,有强大的功能就是没人用。

kprobes的组成:
它主要有三类:kprobe,kretprobe,jprobe,对外称为kprobes,最后好多人都弄混了kprobes/kprobe。不过哥三各有用途,kprobe作为最常用的,可能就是记录日志,但是它可以在任何指令位置插入probe点;而jprobe类似于kprobe的pre_handler,但是有个优点,不需要从寄存器中提取各种参数,直接就定义它的类型和原始函数的参数一致就可以直接使用了;而kretprobe可以查看这个函数执行结束后参数的变化,和jprobe一个在函数进入,一个在函数退出。而最新的内核中jprobe因为它的优势不明显已经被干掉了,原有的使用者可以迁移到trace-event或perf-probe.

插入位置用途
kprobe函数的任何位置(除了黑名单函数之外)记录日志
jprobe放到函数开始查看传入参数
kretprobe函数结束查看返回参数

原理

下面将会尝试从一个概括的角度看一个probe怎么工作的,介绍一个probe代表一个断点和断点触发后所要调用的函数。

kprobe

一个kprobe点可以有pre_handler和post_handler,分别在指令执行前和执行后被调用,我们可以通过保存的寄存器还原出在原始函数中代表的参数,在函数入口处还比较容易,如果在函数中间插入一个kprobe,要还原出有意义的参数内容需要对汇编部分有较深的了解。

先从一个图整体看它是如何工作的:
1.kprobe
1.系统初始化的时候会注册中断处理,在x86上会有两个trap:int1和int3,处理方法分别是do_debug和do_int3,这是kprobe在x86上实现的基石。
2.注册一个kprobe到指定指令位置,它会生成一个kprobe对象,做一些保存工作
1.保存1 byte指令信息到kprobe
2.替换指令为0xcc
3.当该位置的指令执行的时候,触发了int3,之后就会找到该位置信息对应的kprobe,执行pre_handler,之后设置成single_step[gdb中的单步执行],执行原始的指令,执行一条指令后触发了int1,之后找到对应的kprobe,执行post_handler
4.清除single-step,将rip指向probe点的下一条指令

kretprobe

先看一个比较低效的图,这种方式只是早期实现的,应该从OPTPROBES之后在x86上已经被优化实现了:
2.kretprobe-unopt
kretprobe的实现核心仍然是利用kprobe机制,用户可以定义一个entry_handler和一个handler,其中entry_handler会在函数入口处被调用,而handler会在函数退出的时候被调用。
kretprobe会注册成一个只有pre-handler的kprobe,pre-handler是由kretprobe自定实现的pre_handler_kretprobe,它会负责大部分的工作。

1.注册成一个kprobe,当执行流触发int3 trap时,会执行他的pre-handler:pre_handler_kretprobe,执行entry_handler,保存真实的函数返回地址,替换函数返回地址为kretprobe_trampoline,这样函数返回的时候先返回我们的trampoline,之后才由trampoline返回到原始的caller.

2.之后经过single-step过程,执行一条指令,尝试post_handler,这里为空,所以什么也不做,直接清除single-step,继续回到原始的callee处执行

3.当callee返回时,从栈上取出返回地址,这个已经被掉包了:kretprobe_trampoline(蹦床),首先处理用户定义的handler,之后它会找到真实的返回地址并设置回来,这样在trampoline函数退出的时候,就能通过校正后的返回地址回归到正常的执行流了。

但是实际上这种方式已经被优化掉了,现在的实现看下面经过优化过的kretprobe.

Jprobe

3.JProbeJProbe仍然是使用的kprobe的机制,但是这个过程相对来说就比较绕了,原图。

首先jprobe要求用户定义和需要probe相同的原型函数,这样就不需要分析寄存器就能简单地获取到可读参数的内容。

jprobe中对参数的操作不会对原始函数传入的参数造成影响,它所做的操作都是基于原始参数的一份拷贝上,但是只是一个拷贝,而且还是浅拷贝,所以仍然可以操作参数指针所指向的内存区域。

jprobe没有要求用户定义pre-handler而是自己定义了一个pre-handler:setjmp_pre_handler和另外一个break_heandler:longjmp_break_handler.

jprobe的实现过程可以简单划分成这三个阶段:

1.在函数起始地址处进行kprobe的指令替换,执行到这的时候会触发int3,之后就是do_int3->kprobe_int3_handler->setjmp_pre_handler,它保存栈的内容和寄存器内容,之后设置"返回地址=用户定义的handler",最终pre-handler返回1,这就不会设置single-step模式。在返回之后根据栈上的返回地址就会跳转到用户定义的handler,因为栈的排布和寄存器内容都是完全相同的(除了rip),这样就完全可以访问原始函数的参数。当用户定义的函数结束后需要通过jprobe_return的方式返回而不是通常的ret.

2.在上面jprobe_return中,它将栈恢复到原始函数的那一帧(更改rsp),将拷贝的栈帧扔掉,之后主动int3再次陷入异常,kprobe_int3_handler发现断点地址是用户定义的函数地址,并没有对应的注册的probe,而且当前cpu的kprobe正在激活状态,它把这种状态认为是Jprobe产生的,随后调用当前cpu kprobe的break_handler:longjmp_break_handler,恢复栈和寄存器的内容

3.典型的设置single-step模式执行被替换的指令,之后陷入int1,清除该模式,恢复到原始的执行流

优化的kprobe

通过上面的看到,每次都要经过trap过程,这个过程比较耗时,所以有了优化的kprobe,会优化成jmp指令跳转到kprobe处理处,但是不是所有的probe都可以优化成这种形式。

在优化前需要进行安全检查,不符合条件不可以进行优化

  1. jmp + 偏移的方式,目前偏移为32bit,所以共占据5个字节,可能会占据原来多条指令的位置,所以可能会截断原来的指令,这段被优化区域不能跨越函数。
  2. 不能有跳转到这块要被优化区域的指令,这块区域将会被jmp覆盖,指令都已经换了,再jmp过来按照原来的语义来解释这段指令,能不异常吗,结果可能是重复跳转到kprobe处理,也有可能遭遇指令异常
    1.这个函数不能包含非直接跳转
    2.函数不能包含有触发异常的指令,例如0xcc,另外也不能有访问异常表范围内的操作
    3.没有近跳转到被优化区域的指令
  3. 被优化区域的每条指令都可以单独执行

优化准备
kprobe准备一个detour的buffer,里面要包含如下功能的指令:

  • 能够将cpu寄存器压栈(模拟int3的trap过程)
  • 调用trampoline的函数,完成原始的kprobe逻辑过程,调用用户定义的handler
  • 恢复寄存器
  • 被优化区域的指令拷贝到buffer中
  • 跳转回原始执行流的代码

如果kprobe注册时有下面的情况,也是不能优化的

  • 包含break_handler或者post_handler,例如jprobe中用户没有设置这两个handler,但是jprobe在以kprobe形式管理的时候它设置了break_handler,所以它是不能被优化的。
  • 处于被优化区域内有其他的指令已经被probe了
  • 这个probe处于disable的状态,就是没有激活

如果kprobe可以被优化,Kprobes会将kprobe加入到待优化链表,然后启动kprobe-optimizer工作队列来优化它。如果在优化前已经触发了trap,会通过设置到detour buffer中指令,这样可以避免未优化时的single-step,也就是放弃这次的触发捕捉.
Kprobe-optimizer并不会立即插入jmp指令,而是先调用synchronize_sched()等待进入一个安全的上下文,因为很可能在执行待优化区域代码的过程中被中断。CONFIG_PREEMPT=n配置下synchronize_sched()可以保证在它返回的时候所有的中断都是打开的,所以优化的前提就是只在CONFIG_PREEMPT=n配置的内核上。

之后会调用stop_machine()来用jmp指令来替代优化区域,指向detour buffer中的指令.

恢复优化区域的代码:
当优化过的kprobe被注销,disable或者被其他的kprobe阻塞时,都会解除优化。如果优化还没有完成,只需要从待优化队列中删除就可以了。如果优化已经完成,需要使用text_poke_smp()来将原来的指令拷贝回来,并且第一个字节恢复成int3,就是恢复成未优化的状态。

这种安全优化的检查可能会被ksplice在支持CONFIG_PREEMPT=y的内核上使用的stop-machine方式取代掉。

对于geeker来说,经过优化之后会对hacker的方法有些影响

使用jmp来优化的方式会和原来没有优化的pre_handler行为表现有差异,在没有优化的情况下,pre_handler通过改变regs->ip并且返回1的方式可以改变内核的执行路径,即完成劫持。但是当被优化后,这种方式就失效了。所以如果你想改变内核执行流,需要抑制这种优化:

1.指定不做任何事的函数给post_handler或者break_handler
2.通过`sysctl -w debug.kprobes_optimization=n`来显式阻止优化

优化之后的kretprobe

4.kretprobe-opt经过优化的kretprobe过程如上图所示:

在插入probe点之后对其进行了优化:
为kprobe关联一个optimized_kprobe对象,它有一个detour buffer,保存有一段指令,之后是通过jmp跳转回原始函数。
这段指令是经过组装而来的,最初是保存在代码段中,是一段指令范式,但是预留了一些空间(就和小学中的填空题一样,有主题上下文,有些空白的地方预留给学生写)可以动态填写地址。

优化的主要过程:

  • 1.获取一段可执行的内存
  • 2.直接复制这段指令到内存
  • 3.这里面有些占位指令用来放置动态的地址的,将地址动态的填充到固定的偏移上,这样就组装成了一段指令集
  • 4.之后只需要为它设置可执行属性
  • 5.刷新icache

优化之后的执行流

1.在执行流到probe点时,不再是int3 trap而是直接jmp到detour buff中,里面存的是指令,这段指令分为三个阶段:
  1.1准备工作  
    在栈上填充一份pt_regs,填充寄存器:rdi,rsi分别指向optimized_kprobe对象和pt_regs
  1.2.实际工作  
    调用optimized_callback这样就能通过optimized_callback调用到kretprobe的pre_handler_kretprobe,设置上一帧的返回地址为:kretprobe_trampoline
  1.3.恢复现场
    把栈上保存的寄存器数据恢复到寄存器中,之后jmp到被优化区域的下一条指令地址
2.函数执行完毕后  
这部分就和优化前的处理是相同的,通过kretprobe_trampoline先将正确的返回地址设置到栈帧中,然后调用用户注册的handler,之后ret到正确的caller

kprobes的注意事项

1.kprobe允许在同一地址注册多个kprobes,但是不能同时在该地址上有多个jprobes

2.如果注册了jprobe或者带有post_handler的kprobe,这个probe点是不会被转化成优化的probepoint

3.理论上用户可以在内核的任何位置注册探测点,设置可以在中断处理函数中注册探测点,但是也有一些例外的放。
如果用户尝试在实现kprobe的代码(包括kernel/kprobes.c和arch/*/kernel/kprobes.c以及do_page_fault和notifier_call_chain中注册探测点,register_*probe将返回-EINVAL.

4.gcc可能将一个函数隐式地优化成一个内联函数,此时向其上注册探测点,kprobe不会尝试注册,此时会注册失败,此时你可能需要检查/proc/kallsyms或者System.map。

5.一个探测点处理函数能够修改被探测函数的上下文,如修改内核数据结构,寄存器等。因此,kprobe可以用来热升级或进行一些错误注入。

6.如果一个探测处理函数调用了另一个探测点,该探测点的处理函数不将运行,但是它的nmissed数将加1。
多个探测点处理函数或同一处理函数的多个实例能够在不同的CPU上同时运行。

7.除了注册和卸载,kprobe不会使用mutexe或分配内存。

8.探测点处理函数在运行时是禁止抢占的,而且在不同的架构上,探测点处理函数运行时也可能是禁止中断的。因此,对于任何探测点处理函数,不要使用导致睡眠或进程调度的任何内核函数(如尝试获得semaphore)。

9.kretprobe是通过取代返回地址为预定义的trampoline的地址来实现的,因此栈回溯和gcc内嵌函数__builtin_return_address()调用将返回trampoline的地址而不是真正的被探测函数的返回地址。

10.如果一个函数的调用次数与它的返回次数不相同,那么在该函数上注册的kretprobe探测点可能产生无法预料的结果,如果你看到下面的错误提示,那就是kprobe出现了问题,检查所有kretprobe在每个cpu上的状态(在处理前和退出后会将kprobe保存到current_kprobe).

kretprobe BUG!: Processing kretprobe d000000000041aa8 @ c00000000004f48c

11.当进入或退出一个函数时,如果CPU正运行在一个非当前任务所有的栈上,那么该函数的kretprobe探测可能产生无法预料的结果,因此kprobe并不支持在x86_64上对__switch_to()的返回探测,如果用户对它注册探测点,注册函数将返回-EINVAL。

总之:对调用的任何方法检查它的返回值是非常有必要的,稳健的程序需要对各种异常都能够有处理方法。

reference

1.An introduction to KProbes
2.Documentation/kprobes.txt
3.Kernel- and User- Probes in Linux: Magic?

深入解析Linux热补丁技术:从kprobe到ftrace的实现原理与架构限制 本文深入解析Linux热补丁技术(Livepatch)的实现原理与架构限制,详细介绍了从kprobe的动态插桩到ftrace的函数追踪技术。通过分析热补丁的工作流程、一致性模型及不同架构的支持差异,帮助开发者理解如何在运行时无缝替换内核函数,确保高可用服务器环境中的系统稳定性。 阅读详情

相关推荐

深入浅出Livepatch:从kprobe到ftrace的Linux热补丁实现原理

本文深入解析Linux热补丁技术Livepatch的实现原理,详细介绍了kprobe和ftrace如何协同工作,实现在不重启系统的情况下动态修复内核漏洞。文章涵盖热补丁的应用场景、底层机制、实现架构及性能优化,为开发者提供全面的技术指南和实践建议。

weixin_30576827的博客 446

Linux kprobe的使用

Linux kprobe的简单使用

小立仔 5331

trace系列4 - kprobe学习笔记

1.前言 本文主要是根据阅码场 《Linux内核tracers的实现原理与应用》视频课程在aarch64上的实践。通过观察钩子函数的创建过程以及替换过程,理解trace的原理。本文同样以blk_update_request函数为例进行说明function trace kprobe的工作原理,此处的kprobe是基于function trace来实现。 kernel版本:5.10 平台:arm64 2. function trace钩子函数替换过程 2.1 编译阶段 同Linux ftrace学习笔记中编

HZero 3597

Linux kprobe原理

Linux kprobe原理,以及其优化简介

小立仔 3974

Linux内核动态调试工具:kprobe与jprobe深入解析

Linux操作系统由于其开源特性,在企业和个人用户中广受欢迎。随着技术发展,内核模块复杂性不断增加,使得开发者和维护人员面临越来越多的挑战。为了解决这些挑战,各种动态探测工具应运而生,它们能够在不重新编译和重启系统的情况下,对正在运行的内核进行实时探测和调试。kprobe是Linux内核提供的一个强大的动态追踪机制,允许用户在几乎不影响系统性能的情况下,在运行时动态地插入探测点到内核函数中。kprobe通过修改目标函数指令流中的第一条指令,来实现对函数执行过程的监控。

weixin_42405592的博客 1324

Redis简介和项目应用

内存优先架构简介Redis的读写操作都是在内存中执行的,计算机内存的读写速度极快,比机械硬盘的读写快很多,因此也会比MySql采用机械读写的方式性能更高。但是这样会产生一个问题,当Redis重启之后,内存中的数据就会丢失,为了保证数据不会因为服务器重启而丢失,Redis实现了数据持久化的机制,这个机制会把数据存储到磁盘中,当服务器重启的时候,能够从磁盘中恢复原有的数据。

人工智能、机器学习 754

Linux内核调试技术之kprobes:基本原理与使用

Linux kprobes技术是一种可以跟踪内核函数执行状态的轻量级内核调试技术,利用kprobes技术可以在运行的内核中动态的插入探测点,当内核运行到该探测点后可以执行用户预定义的回调函数,以收集所需的调试状态信息而基本不影响内核原有的执行流程。{return 0;}.symbol_name = "do_fork", // 要追踪的内核函数为 do_fork.pre_handler = handler_pre // pre_handler 回调函数。

Aspiresky的专栏 3160

基于springboot医院医疗仪器管理系统

基于Spring Boot的医院医疗仪器管理系统是一款专门为医院设计的高效管理工具。

2201_75927219的博客 1009

kprobe 的 3 种使用

知识背景:会编写基础内核模块 kprobe用处:用来跟踪、记录、打桩。最常见的使用就是需要打印内核函数的执行流程,比如排查问题时、或者学习内核流程时需要用到。 准备工作:找一份和自己linux系统相同版本的源码(方法自行Google,ubuntu、centos、redhat各自有各自方法) 内核模块跟踪指定函数 官方文档: https://www.kernel.org/doc/Documentation/kprobes.txt 在 内核源码目录samples/kprobes/有几个kprobe模块例子,.

Network, Linux Kernel 6205

AXI 1G/2.5G Ethernet Subsystem IP核使用过程中参数配置全解

AXI 1G/2.5G Ethernet Subsystem 是一个为FPGA设计的以太网子系统,它支持1Gbps和2.5Gbps的数据传输速率,使得FPGA能够直接进行高速以太网通信。这个子系统通常包含以太网MAC控制器、GMII(千兆媒体独立接口)或RGMII(简化GMII)接口、以及可选的PHY(物理层)接口支持。

u011565038的博客 1万+

【训练】Qwen2.5VL 多机多卡 Grounding Box定位

之前的相关文章:【深度学习】LLaMA-Factory微调sft Qwen2-VL进行印章识别使用LLaMA-Factory微调sft Qwen2-VL-7B-Instruct构建最新的LLaMA-Factory镜像。

q742971636的博客 2573

【原创】Linux kprobe 实现原理 图文详解 (一) kprobe实现原理

图文详解 linux kprobe 底层实现原理

h_b__k的博客 2107

esp32s3 spi camera gc6133调试

gc6133 spi只有master模式,同时需要esp32提供主时钟,需要有主时钟然后才能通过i2c进行初始化.测试了几种方式,记录如下。

hclydao的专栏 1557

Linux内核调试利器|kprobe 原理与实现

本文主要介绍了 kprobe 的原理与实现,正如本文开始时所说,kprobe 机制的细节很多,所以本文不可能对所有细节进行分析。如果大家对 kprobe 的所有实现细节有兴趣,可以自行阅读源码。

weixin_60043341的博客 794

第01章 Hermes Agent 是什么

如果读者所在的开发团队已经引入了 Cursor、Claude Code 这类 AI IDE,可能会有一个困惑:写代码已经有 AI 帮忙了,还需要 Hermes Agent 做什么?这一章将给出答案。Hermes Agent 不是另一个写代码的 AI,而是一个常驻在团队里的"AI 协作成员",专门负责写代码之外的协作环节——讨论需求、审查代码、查日志、监控告警、生成报告。学完本章,读者将清楚 Hermes 的定位以及它在团队里的角色。

亢少军的博客 70

CVE-2021-22205 GITLAB 未授权 RCE 漏洞

简介 GitLab是由GitLab Inc.开发的一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,可通过Web界面访问公开或私人项目。由于GitLab存在未授权的端点,导致该漏洞在无需进行身份验证的情况下即可进行利用。 漏洞利用 上工具 python3 poc import sys import requests from bs4 import BeautifulSoup requests.packages.urllib3.disable_warnings() def .

qq_32445755的博客 877

【原创】Linux kprobe 实现原理 图文详解 (三) kprobe跳转优化

图文详细介绍kprobe跳转优化的底层实现原理

h_b__k的博客 964

openclaw通俗入门系列6——记忆系统

记忆 = 智能体的笔记本,分长期(MEMORY.md)和每日(memory/日期.md)。只有写到文件里的才能记住!支持语义搜索(理解意思)+ 关键词搜索,还能自动在压缩前保存重要内容。

m0_60605453的博客 400

【原创】Linux kprobe 实现原理 图文详解 (二) kretprobe实现原理

目录 一、kretprobe 基本介绍 二、kretprobe 使用示例 三、kretprobe 实现原理 四、具体代码 (代码:linux 6.3.1,架构:arm64) One look is worth a thousand words. —— Tess Flanders 一、kretprobe 基本介绍 Kretprobe是一种基于Kprobe的探测技术,用于探测内核函数的入口点、返回点。在这两处可以调用用户注册的钩子函数,该技术一般用于获取:函数运行时间、函数返回

h_b__k的博客 2302

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

【原创】Linux kprobe 实现原理 图文详解 (四) 指令替换、cpu stopper

本文主要介绍kprobe指令替换的细节,并介绍cpu stopper机制的实现原理

h_b__k的博客 1571

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

kprobe 原理详细分析

内核调试机制 kprobe 原理详细分析,使用 kprobe 可以在内核任意位置设置 hook 并跟踪调试

看我眼色行事的博客 1639

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

int3和SingleStep联合实现Linux系统键盘监控(kprobe原理)

就着Linux系统键盘监控这个话题,再写点什么。 前面已经写了三篇,可以一起汇总着看,算是一个简单的一题多解吧: 标准inline hook的方法: https://blog.csdn.net/dog250/article/details/106425811 手工push/ret jmp inline hook的方法: https://blog.csdn.net/dog250/article/details/106481123 手工构造push %rbp效果的方法: https://blog.csdn.n

TCP/IP 1万+

深入拆解Linux热补丁:从kprobe到ftrace的底层实现原理

本文深入解析Linux热补丁技术,从kprobe动态插桩到ftrace函数追踪的底层实现原理,详细探讨了x86与ARM64架构下的实现差异。通过/proc/version修改案例,揭示如何在不重启系统的前提下动态修复内核代码,适用于高可用性生产环境。

weixin_29306261的博客 379

Linux调试追踪: kprobe实现简析

Linux,Kprobe

JiMoKuangXiangQu的专栏 755

Linux内核kprobe机制实现浅析

refer from    Kprobe机制是内核提供的一种调试机制,它提供了一种方法,能够在不修改现有代码的基础上,灵活的跟踪内核函数的执行。它的基本工作原理是:用户指定一个探测点,并把一个用户定义的处理函数关联到该探测点,当内核执行到该探测点时,相应的关联函数被执行,然后继续执行正常的代码路径。      Kprobe提供了三种形式的探测点,一种是最基本的kprobe,能

samssm的专栏 2377

深入ftrace kprobe原理解析

至此,我们知道Kprobe实现的本质是breakpoint和single-step的结合,这一点和大多数调试工具一样,比如kgdb/gdb。当 kprobe 被注册后,内核会将对应地址的指令进行拷贝并替换为断点指令(比如 X86 中的int 3)随后当内核执行到对应地址时,中断会被触发从而执行流程会被重定向到我们注册的函数当对应地址的原始指令执行完后,内核会再次执行从而实现指令级别的内核动态监控。也就是说,kprobe 不仅可以跟踪任意带有符号的内核函数,也可以跟踪函数中间的任意指令。

奇小葩 5457
上一篇: ftrace系统实现原理
下一篇: linux内核态hook模块
Frank-Wang
博客等级 码龄16年 163粉丝 96原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值