问题记录: 在内核模块中拦截报文并保存到文件

ubuntu20.04安装全志sunxi-livesuite烧录工具 Q1: make[2]: *** 没有规则可制作目标“arch/x86/entry/syscalls/syscall_32.tbl”,由“arch/x86/include/generated/uapi/asm/unistd_32.h” 需求。A2: 重启电脑,在 BIOS 中关闭 secure boot 功能保存并重启。A1: 修改Makefile的SUBDIRS字符为M就可以编译通过的到ko文件。Q2: insmode 的时候提示错误。使用 dmesg 查看发现如下提示。 阅读详情

Release log:

2021-04-24 六: 完成初版

原文地址

背景介绍

最近在跟进一个网络相关的问题,需要查看经过 __netif_receive_skb 的报文是否有异常。如果打印所有的包,由于打印太多会影响性能,并且打印的内容也不会太详细。所以决定,把监听到的报文全部保存到 pcap 文件中,然后通过 wireshark 查看
这里对需要用到的知识做一个整理

知识点分析

  1. 怎么在内核模块中读写文件
  2. pcap 的文件格式是怎样的

怎么在内核中读写文件

一段简单的实例代码如下:

// main.c
#include <linux/module.h>	// 包含了对模块的结构定义以及模块的版本控制
#include <linux/kernel.h>	// 包含常用的内核函数
#include <linux/fs.h>

MODULE_LICENSE("Dual BSD/GPL");

static int __init skb2pcap_init(void)
{
	struct file *fp = filp_open("/tmp/kernel_rw", O_CREAT | O_WRONLY | O_TRUNC, 0644);
	const char *wstr = "write from kernel";
	int len = 0;
	mm_segment_t old_fs;

	if (IS_ERR(fp)) 
	{
		printk("[%s] open file failed\n", __func__);
		return -1;
	}

	old_fs = get_fs();
	/* 改变 kernel 对内存地址检查的处理方式, 如果此处被抢占是否会有风险 */
	set_fs(KERNEL_DS);
	len = vfs_write(fp, wstr, strlen(wstr), &fp->f_pos);
	set_fs(old_fs);
	filp_close(fp, NULL);

	printk("[%s] write len: %d\n", __func__, len);
    return 0;
}

static void __exit skb2pcap_exit(void)
{
	struct file *fp = filp_open("/tmp/kernel_rw", O_RDONLY, 0);
	int len = 0;
	char buf[128] = {0};
	mm_segment_t old_fs;

	if (IS_ERR(fp))
	{
		printk("[%s] open file failed\n", __func__);
		return;
	}

	old_fs = get_fs();
	set_fs(KERNEL_DS);
	len = vfs_read(fp, buf, sizeof(buf) - 1, &fp->f_pos);
	set_fs(old_fs);
	filp_close(fp, NULL);

	printk("[%s] get str[%d]: %s\n", __func__, len, buf);
}

module_init(skb2pcap_init);
module_exit(skb2pcap_exit);

# Makefile
# 如果已定义 KERNELRELEASE,则说明是从内核构造系统调用的,因此可利用其内建语句
ifneq ($(KERNELRELEASE), )
	obj-m := skb2pcap.o
	skb2pcap-objs := main.o
# 否则,是直接从命令行调用的,这时要用内核构造系统
else
	KERNELDIR ?= /lib/modules/$(shell uname -r)/build
	PWD := $(shell pwd)

default:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

clean:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) clean
	# rm -f *.o *.cmd .*.cmd *.mod modules.order *.mod.c
endif

需要注意,vfs_read 和 vfs_write 原型中,buffer 指针是用 __user 修饰的,如果直接使用内核地址作为参数会返回失败。所以在使用前需要调用 set_fs 改变 kernel 对内存地址的检查方式

遇到问题

insmode 的时候提示错误

$ sudo insmod ./skb2pcap.ko 
insmod: ERROR: could not insert module ./skb2pcap.ko: Operation not permitted

使用 dmesg 查看,发现如下提示

Lockdown: insmod: unsigned module loading is restricted; see man kernel_lockdown.7

解决办法: 重启电脑,在 BIOS 中关闭 secure boot 功能,保存并重启。这个时候 insmod 就没问题了

但 insmode 时会发现,终端没有 printk 内容输出。其实输出内容可以在 dmesg 中看到

pcap 的文件格式是怎样的

pcap 文件的总体结构是: 文件头–数据包头1–数据包1–数据包头2–数据包2…

其中文件头的格式如下:

struct pcap_file_header {
	uint32_t magic;			// 为 0xa1b2c3d4 或者 0xd4c3b2a1,用来识别字节顺序,前者为大端模式,后者为小端模式
	uint16_t version_major;	// 主版本号,一般为 0x0200
	uint16_t version_minor;	// 次版本号,一般为 0x0400
	uint32_t thiszone;		// GMT 和本地时间的差值,单位秒。一般为零
	uint32_t sigfigs;		// 时间戳的精度,一般为全零
	uint32_t snaplen;		// 设置所抓获的数据包的最大长度,如果所有数据包都要抓获,将该值设置为65535
	uint32_t linktype;		// 链路类型
};
/* 链路类型对应关系如下
   0  					BSD loopback devices, except for later OpenBSD
   1  					Ethernet, and Linux loopback devices
   6  					802.5  Token Ring
   7  					ARCnet
   8  					SLIP
   9  					PPP
   10 					FDDI
   100					LLC/SNAP-encapsulated  ATM 
   101					"raw IP", with no link
   102					BSD/OS  SLIP
   103					BSD/OS  PPP
   104					Cisco  HDLC
   105					802.11
   108					later OpenBSD loopback devices (with the AF_value in network byte order)
   113					special  Linux  "cooked"  capture
   114					LocalTalk
   */

数据包头的格式如下:

struct pcap_pkt_header {
	uint32_t ts_s;			// 时间戳高位,精确到秒,从 GMT 开始记
	uint32_t ts_ms;			// 时间戳低位,精确到毫秒
	uint32_t caplen;		// 抓获到数据帧的长度
	uint32_t len;			// 离线数据长度,网路中实际数据帧的长度,一般不大于Caplen,多数情况下和Caplen值一样
};

一段简单的解析 pcap 报文的代码如下:

int main(int argc, char *argv[])
{
	int fd = -1;
	struct pcap_file_header fhdr = {0};
	struct pcap_pkt_header phdr = {0};
	uint8_t databuf[2048] = {0};
	int datalen = 0;

	if (2 != argc)
	{
		printf("usage: %s pcap_file_name\n", argv[0]);
		return 0;
	}

	if ((fd = open(argv[1], O_RDONLY)) < 0)
	{
		printf("open %s failed: %s\n", argv[1], strerror(errno));
		goto leave;
	}

	if (sizeof(fhdr) != read(fd, &fhdr, sizeof(fhdr)))
	{
		printf("read file failed: %s\n", strerror(errno));
		goto leave;
	}

	printf("file header info: magic(0x%08x), major_version(0x%04x), "
			"minor_version(0x%04x), thiszone(0x%08x), sigfigs(0x%08x), "
			"snaplen(0x%08x), linktype(0x%08x)\n", 
			fhdr.magic, fhdr.version_major, fhdr.version_minor, 
			fhdr.thiszone, fhdr.sigfigs, fhdr.snaplen, fhdr.linktype);

	while (sizeof(phdr) == read(fd, &phdr, sizeof(phdr)))
	{
		int i = 0;

		datalen = read(fd, databuf, phdr.caplen);
		if (phdr.caplen != datalen)
		{
			printf("read data len err(%d - %d): %s\n", phdr.caplen, datalen, strerror(errno));
			break;
		}

		printf("packet header info: ts_s(%d), ts_ms(%d), caplen(%d), len(%d):", 
				phdr.ts_s, phdr.ts_ms, phdr.caplen, phdr.len);

		for (i = 0; i < phdr.caplen; i ++)
		{
			if (0 == i % 16) printf("\n");
			else if (0 == i % 8) printf(" ");

			printf("%02x ", databuf[i]);
		}
		printf("\n");
	}

leave:
	if (fd >= 0) close(fd);

	return 0;
}
CANoe数据过滤实战:3种方法精准抓取目标报文,告别Trace窗口信息轰炸 本文详细介绍了CANoe数据过滤的3种实战方法,帮助工程师精准抓取目标报文,有效应对Trace窗口信息过载问题。从硬件通道配置层的硬过滤、Trace窗口的动态显示过滤,到Logging模块的智能记录过滤,层层递进提升测试效率。特别适用于高负载CAN网络和长期监控场景,显著降低CPU负载并提高关键报文捕获率。 阅读详情

相关推荐

告别CANoe高成本:用这款国产CANas软件,手把手教你搭建DBC解析与报文回放环境

本文详细介绍了国产CANas软件如何替代高成本的CANoe,实现DBC解析与报文回放功能。通过对比核心功能、硬件配置、DBC文件操作及曲线显示优化,帮助用户低成本搭建CAN总线分析环境,特别适合预算有限的开发者和小型团队。

weixin_29163581的博客 448

linux不能加载驱动模块的解决

这个周又开始看scull了,希望能在内核层面上做一些有趣的事情 本来不想发这个csdn,但是还是坚持写下来记录下排查问题的过程吧 今天make模块成功后,突然出现了 ERROR: could not insert module main.ko: Operation not permitted 天啊 这到底是什么原因,权限不足吗?自己 sudo make sudo insmod main.ko 发现还是这个问题,于是自己 sudo dmesg -c Linux dmesg命令用于显示开机信息。 kerne

qq_32783703的博客 6359

CANoe从入门到精通:安装配置、报文解析与自动化测试实战

在车载总线测试领域,CANoe作为主流的开发与验证工具,其价值在于支持CAN、LIN、以太网等多总线环境的仿真与测试。理解虚拟CAN口、DBC数据库文件与Trace窗口的配合,是解析报文和定位通信问题的关键。通过合理设置采样点,可有效降低错误帧,提升总线通信稳定性。进一步结合诊断Seed&Key DLL、XCP标定、Python脚本控制以及COM多实例并发,能够实现从手动测试到自动化回归测试的完整落地。本文提供从环境准备、工程配置到高频故障排查的工程实践路径,适用于汽车电子工程师进行ECU功能验证、网络诊断

cuixie2370的博客 217

Linux 驱动开发笔记(二)

Linux最简单的驱动,编写,装载卸载全过程

qq_45061393的博客 919

Burp Suite代理配置指南:Firefox与Edge浏览器HTTPS流量拦截实战

HTTP代理是网络通信中的关键中间件,其核心原理是在客户端与服务器之间建立转发通道,实现对网络请求与响应的监控与修改。这一机制在Web安全测试、接口调试和网络问题诊断中具有重要技术价值,尤其在渗透测试和开发调试场景下,能够帮助工程师深入分析应用行为。HTTPS流量解密则依赖于中间人攻击的合法应用,通过安装自签名CA证书,使代理工具能够解密并查看加密通信内容。本文以Burp Suite为例,详细演示了如何在Firefox和Edge浏览器中配置代理并安装证书,实现HTTP/HTTPS流量的完整拦截与修改,涵盖代

cuiyingchan0663的博客 624

Ethernet/IP调试工具V2.2.0实战:设备扫描、标签读写与报文分析

在工业自动化领域,Ethernet/IP协议凭借CIP对象模型和显式/隐式消息机制,成为PLC、机器人、远程IO等设备的主流通讯标准。其底层基于标准以太网TCP/IP协议栈,但应用层采用CIP协议,导致通用抓包工具难以解析标签寻址与对象字典。专用调试工具通过内置CIP协议栈,实现设备扫描发现、标签读写监控、报文捕获解析及网络负载分析,将原始字节流翻译为可读标签与数值,显著提升现场调试与故障排查效率。在产线联调、设备集成与预防性维护等场景中,这类工具帮助工程师快速定位网络层、设备层与应用层问题。Etherne

weixin_34185512的博客 721

The Linux Kernel Module Programming Guide

 The Linux Kernel Module Programming GuidePeter Jay SalzmanMichael BurianOri PomerantzCopyright © 2001 Peter Jay Salzman The Linux Kernel Module Programming Guide is a free book; you

Linux 内核,驱动, Android系统开发, MAC/Android APP开发 1317

Modbus Poll与Slave调试实战:从下载配置到报文分析

Modbus协议是工业自动化领域广泛使用的通讯标准,基于主从架构实现设备间数据交互。其核心原理是通过功能码定义读写操作,利用CRC校验保证报文完整性。掌握Modbus调试技术,能够快速定位通讯故障,提升工控系统开发与维护效率。典型应用场景包括PLC与上位机通讯、传感器数据采集、变频器控制等。在实际工程中,调试工具的参数配置与报文分析是关键环节。本文以Modbus Poll和Modbus Slave为例,详解调试工具选型、参数对齐、功能码解析及常见问题排查,帮助开发者从模拟器平滑过渡到真实设备调试。

weixin_33800463的博客 232

kernel module signing

============================== KERNEL MODULE SIGNING FACILITY ============================== CONTENTS Overview. Configuring module signing. Generating signing keys. Public keys in the k

lyf's blog 5663

Burp Suite实战:5种文件上传漏洞绕过姿势深度解析

文件上传功能是Web应用中的常见模块,其安全性直接关系到服务器安全。其核心原理在于服务器对用户提交的文件进行类型、内容及路径的校验。如果校验逻辑存在缺陷,攻击者可能上传恶意脚本文件,从而获取服务器控制权,技术价值在于这是Web渗透测试中获取初始权限的关键突破口。常见的应用场景包括网站头像上传、文档管理、媒体资源提交等。本文聚焦于使用Burp Suite这一渗透测试工具,深入剖析针对文件上传漏洞的五种核心绕过技术,涵盖客户端校验、MIME类型检查、黑名单绕过、文件内容校验及服务器解析漏洞,并融入**SDcms

lvwenwen 386

Detours Hook实战:拦截ws2_32.dll的send函数并记录发送数据

API Hook是Windows网络调试中常用的技术,通过在函数入口修改执行流,可以在不修改目标程序的前提下捕获其内部调用。理解Hook的工作原理,尤其是Inline Hook替代IAT Hook的优势,是构建可靠拦截工具的基础。Detours库提供了成熟的事务化挂接机制,简化了指令修补和函数跳转的复杂度。在实际工程中,拦截send函数可将应用层发送的原始字节落盘为ob文件,结合时间戳、线程ID和调用栈信息,快速定位协议拼接错误或异常的对外通信场景。本文技术要点源自一次完整的Hook项目实践,覆盖从签名匹配

weixin_34127717的博客 319

使用Springboot的AOP日志拦截获取前端网站的操作记录

随着我们的不断学习,我们的技术不断沉淀,做出来的项目也不断成熟所以,我们的网站怎么能没有日志记录呢annotation包下面的Log,是自定义注解,字段的解释下面的注释中很清晰哦/*** @author 徐一杰* Aop日志拦截自定义注解。

泡泡的博客 1573

JHU ICBM DTI Atlas纤维束模板介绍

JHU ICBM DTI atlas 纤维束的定位与功能介绍

machinelearning_er的博客 6423

经纬恒润VBA免费总线分析工具实测:CAN报文收发、DBC解析与VCI申请指南

在汽车电子研发与测试中,CAN/LIN总线报文分析是验证ECU功能与排查故障的基础环节。传统商用总线工具虽功能强大,但授权成本高,对个人开发者、高校实验室和小型团队并不友好。总线分析工具的核心原理是:通过VCI硬件将PC命令转换为总线电信号,再由软件完成报文收发、DBC解码与曲线显示。高效的DBC解析能免去人工对照信号表的繁琐,显著提升调试效率。这类工具广泛应用于总线测试、数据录波、故障复现等场景。经纬恒润将其VBA总线分析软件免费开放,并接受VCI硬件申请,为低成本搭建总线测试环境提供了可行路径。本文实测

weixin_34302561的博客 328

【面试经验】京东-技术产品经理一面:从紧张到反思的全流程复盘

本文详细复盘了京东技术产品经理一面的全流程,从面试前的简历打磨、业务理解和技术基础准备,到面试中的高压对话和突发状况应对,再到面试后的深度反思与改进方案。文章特别强调了技术产品经理需要具备的技术理解力、数据敏感度和商业思维,并提供了实用的面试建议和准备技巧。

weixin_28730927的博客 162

使用LoRa远程控制路灯(PWM调光以及LoRaWAN单播、组播、广播)

PWM调光 1、使用有pwm波输出的引脚,本例子使用timer0,PA0引脚; 2、由于timer时钟的原因,mcu不能进入休眠; 3、主控使用EFM32,代码实现如下: #define MAX_PULSE (CPU_FREQ/1000-1) #define UNIT_PULSE MAX_PULSE/100 //单位脉宽 void pwminit(void) { ...

freemote的博客 2944

HTTP/HTTPS核心协议详解:从报文结构到状态码排查实战

HTTP作为应用层的请求-响应模型,奠定了客户端与服务端通信的基本范式,而HTTPS则通过TLS加密为传输安全提供了保障。理解报文结构、请求头与响应头字段,是排查接口联调问题的关键。状态码如502 Bad Gateway,往往并非服务端代码逻辑错误,而是网关到上游节点的连接或健康检查失效。同时,掌握HTTP连接复用机制,可以减少TCP握手开销,显著提升接口吞吐能力。在实际开发中,无论是携带Token的请求头配置、HTTPS抓包原理,还是413、504等状态码的排查,都离不开对协议底层逻辑的扎实理解。从基础报

weixin_34290631的博客 298

Demo2Reward:用人类演示动态优化VLM奖励模型提示

多模态大模型(VLM)的奖励建模正面临核心瓶颈——静态提示导致语义鸿沟与泛化失效。其本质是将人类判断标准固化为不可更新的文本模板,使奖励信号脱离真实任务意图。Demo2Reward提出范式级改进:以结构化人类演示为元信号,驱动提示权重连续优化,实现从‘结果打分’到‘过程理解’的跃迁。该方法不修改VLM主干,却显著提升RLHF收敛效率与OOD鲁棒性,在医疗、工业质检等场景验证了跨任务迁移与热修复能力。它重新定义了提示工程的技术价值:不是前端微调,而是奖励系统的认知校准基础设施。

weixin_34302798的博客 408

Burp Suite抓包实战:从代理配置到HTTPS证书与安全测试

在Web安全与渗透测试领域,HTTP协议分析与请求改包是入门的关键技能。Burp Suite作为一款功能强大的拦截代理工具,通过代理监听、证书信任和请求重放机制,帮助安全工程师观察并修改浏览器与服务器之间的原始报文。理解HTTP请求头、响应状态码与参数传递原理,是进行漏洞挖掘的基础。实际工程中,从配置本地代理、安装HTTPS证书,到使用Repeater进行手工越权测试、利用Intruder执行密码爆破,这些操作都建立在扎实的协议理解之上。本文从Burp Suite的版本选择与环境搭建讲起,逐步拆解代理配置、

weixin_33935636的博客 207

记一次Nacos线程数飙升排查

Nacos线程飙升问题排查

叭嘣的博客 2631

基于Java的OPC UA Server开发指南:从零开始构建高效服务器

本文介绍了如何使用开源项目org.eclipse.milo创建Java OPC UA Server。通过创建Spring Boot项目,添加Milo SDK依赖,定义Namespace类,服务器启动类以及监听器,详细阐述了建立OPC UA Server服务的步骤。启动后,服务器默认监听地址为opc.tcp://localhost:12685,可使用Softing OPC Client进行连接。

洛阳泰山的博客 3023

Burp Suite与Fiddler实战对比:手把手教你拦截移动端App网络请求

在移动应用开发和安全测试领域,网络请求拦截与分析是一项基础且关键的技能。其核心原理基于中间人代理技术,通过在客户端与服务器之间建立代理通道,实现对HTTP/HTTPS流量的捕获、解密与审查。这项技术的核心价值在于,它使开发者能够透视应用的数据交换过程,进行安全审计、协议分析、性能调试和故障排查。无论是进行API接口调试、分析数据传输逻辑,还是检测潜在的数据泄露与安全漏洞,网络请求拦截都是不可或缺的实践手段。本文聚焦于两大主流工具Burp Suite和Fiddler的实战应用,详细解析如何配置代理、安装CA证

weixin_34380948的博客 401

课堂练习及课后作业2.1:外部中断

本关任务:通过相关知识以及实验回答:版本 1 内核的第 6 次时钟中断发生时,断点和恢复点(指令地址)分别是多少?本关任务:修改版本 0 内核,使得每发生 100 次时钟中断,就在屏幕上输出一个字符‘t’和当时的进程号,如“t(0)”表示0号进程运行时发生了时钟中断。本关任务:通过实际操作回答在输出第一行 0/1 字符的过程中(如下图所示),共发生了几次时钟中断?本关任务:修改版本 1 内核源码,使得每次时钟中断发生时,都在屏幕上输出字符‘t’。分析版本1内核,找到第一次时钟中断的恢复点地址。

Junds0的博客 1万+

CAN总线实战入门:VCU与MCU通信报文抓取与解析

CAN总线是汽车电子和嵌入式系统中广泛使用的通信协议,其核心原理包括报文仲裁、位定时和错误处理机制。在新能源汽车领域,VCU与MCU之间的CAN通信质量直接影响动力系统的实时性与可靠性。通过CANalyzer等工具进行报文抓取与解析,可以深入理解总线负载、周期抖动和信号物理值转换等关键概念。典型应用场景包括整车控制器与电机控制器的握手交互、状态反馈及故障诊断。本文以VCU与MCU通信为例,详细介绍了从硬件连接到DBC文件编写、从Trace窗口配置到报文解析的完整实战流程,帮助读者快速掌握CAN总线分析的基本

weixin_28292761的博客 290

【WRF教程第3.5期】预处理系统 WPS 详解:以4.5版本为例

预处理系统 WPS 详解:以4.5版本为例

WW、forever的博客 1422

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

cosmos 网络模块实战:用 Python 原始套接字实现 Packet Sniffer 抓包与逐层协议解析

> 本篇以 cosmos 仓库中 [packetsniffer 模块](https://link.gitcode.com/i/e7139492ac2838ed284d3c1bbdded565) 为主线,讲解如何用 Linux 原始套接字(`PF_PACKET` + `SOCK_RAW`)在数据链路层捕获每一个网络帧,依次解封装 Ethernet、IPv4、TCP/UDP 直至 HTTP 载荷,同时

gitblog_00139的博客 1078

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

上一篇: gdb 使用方法整理(基础篇)
下一篇: 并发与竞态——信号量与互斥体
wax5798
博客等级 码龄9年 5粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值