西门子S7comm协议解析 —— 利用Wireshark对报文逐字节进行解析详细解析S7comm所含功能码以及UserData功能(path1)

时间:2024-01-26 12:03:28

又一次成为懒蛋了,标题就这么改了改又是一篇新文章。

网上也有很多S7comm协议的解析,但还是如同我上一篇一样我只是做报文的解析对于S7comm的原理并进行阐述。

有些地方有错误的地方尽请大家指出,共同进步。

好了,言归正题。我们开始吧。

我还是按照功能码的顺序进行介绍吧。

s7抓包分析

 TPKT层和COTP层我也不多做介绍了,有兴趣的可以自己去了解。今天我们主要是解析S7comm这一层。

功能码附录:

0x00       CPU services CPU服务

0xf0        Setup communication  建立通信

0x04       Read Var      读取值

0x05       Write Var     写入值

0x1a       Request download 请求下载

0x1b       Download block   下载块

0x1c       Download ended   下载结束

0x1d       Start upload  开始上传

0x1e       Upload   上传

0x1f        End upload   上传结束

0x28       PI-Service     程序调用服务

0x29       PLC Stop      关闭PLC

1、0xF0建立通信

发包

 

我们来先看Header头部分。

Byte[0] 32 为协议ID   一般指定为0x32

Byte[1] 01 为 PDU类型  一般有0x01 Job 主设备发起请求 0x02 Ack 确认响应 0x03 Ack_data 确认数据响应一般作为确认0x01的请求 0x07 USERDATA     协议的扩展,参数字段包含请求/响应ID

Byte[2]Byte[3] 00 00冗余数据,通常为0×0000

Byte[4]Byte[5] 3e 02协议数据单元的参考、通过请求事件增加

Byte[6]Byte[7] 00 08参数的总长度也就是parameter的长度

Byte[8]Byte[9] 00 00数据的长度、也就是data部分数据的长度如果无即为0

继续看Parmeter部分。

根据上面的length得知,我们的Parameter部分应该是8个位,数一数看看是不是8位

Byte[0] f0 为PDU的类型也就是功能码

Byte[1] 00 冗余数据,通常为0×0000

Byte[2] Byte[3]  发送连接请求

Byte[4] Byte[5]  发送通信请求

Byte[6] Byte[7]  协商的PDU长度

回包

 

红框内跟发包是一样的,就不再描述了。

从Error Class开始。

Byte[10] 00 为错误类型 、错误类型也有很多种、以下是错误类型附录。

0x00       No error 没有错误

0x81       Application relationship     应用关系

0x82       Object definition  对象定义

0x83       No resources available 没有可用资源

0x84       Error on service processing 服务处理中错误

0x85       Error on supplies 请求错误

0x87       Access error  访问错误

Byte[11] 00 为错误码   文章最后会附录一下全部错误码(很长不贴在这里了,搜索 附录一)

这里可以理解为 错误类型规定错误的大体方向而错误码规定错误的具体事件。

接下来我们看Parameter这一部分

可以看出跟发包是完全一样的,还是那句话百变不离其宗,协议嘛逃脱不了一发一收对吧。

Byte[0] f0 为PDU的类型也就是功能码

Byte[1] 00 冗余数据,通常为0×0000

Byte[2] Byte[3]  确认连接请求

Byte[4] Byte[5]  确认通信请求

Byte[6] Byte[7]  协商的PDU长度

2、0x04 读取数据

发包

Header头部与之前都一样的不再描述了

我们直接看Parameter部分吧。

Byte[0]  04 功能码

Byte[1]  01 代表了Item的个数  为1 即为 一个

再继续往下扒。

Item部分

Byte[0] 12 结构标识通常都为0x12,代表变量规范

Byte[1] 0a 长度规范、自此往后的长度

Byte[2] 10  IDS的地址规范的格式类型常见值如下表

0x10        S7ANY  Address data S7-Any pointer-like DB1.DBX10.2

0x13        PBC-R_ID    R_ID for PBC

0x15        ALARM_LOCKFREE Alarm lock/free dataset

0x16        ALARM_IND      Alarm indication dataset

0x19        ALARM_ACK     Alarm acknowledge message dataset

0x1a        ALARM_QUERYREQ      Alarm query request dataset

0x1c        NOTIFY_IND      Notify indication dataset

0xa2        DRIVEESANY    seen on Drive ES Starter with routing over S7

0xb2        1200SYM      Symbolic address mode of S7-1200

0xb0        DBREAD      Kind of DB block read, seen only at an S7-400

0x82        NCK      Sinumerik NCK HMI access

Byte[3] 02 为数据传输的大小、常见值如下表

0 NULL

3  BIT  bit access, len is in bits

4  BYTE/WORD/DWORD  byte/word/dword access, len is in bits

5  INTEGER  integer access, len is in bits

6  DINTEGER  integer access, len is in bytes

7  REAL  real access, len is in bytes

9  OCTET STRING  octet string, len is in bytes

Byte[4]Byte[5] 00 01 即数据的长度

Byte[6]byte[7] 00 01  即 DB 编号,如果访问的不是DB区域,此处为0x0000

Byte[8] 84 即数据的区域常用的如下表

Byte[9] Byte[10]Byte[11]    要读取数据的地址

图示整体标注一下

 回包

 Header部分

除了红框内的其他都与发包一致

Error class 即错误类型

Error code 即具体错误码这两个在上面已经介绍了都有哪些错误类型,没有错误即0x00

Parameter部分

Byte[0] 04 功能码 Byte[1] 01 代表一个Item

Data部分

Byte[0] FF 为返回码  返回码常用值如下表

0x00       Reserved 未定义,预留

0x01       Hardware error   硬件错误

0x03       Accessing the object not allowed 对象不允许访问

0x05       Invalid address     无效地址,所需的地址超出此PLC的极限

0x06       Data type not supported     数据类型不支持

0x07       Data type inconsistent 日期类型不一致

0x0a       Object does not exist    对象不存在

0xff         Success  成功

Byte[1] 04  为数据传输大小 data数据传输大小值如下表

0     NULL

3     BIT bit access, len is in bits

4     BYTE/WORD/DWORD     byte/word/dword access, len is in bits

5     INTEGER    integer access, len is in bits

6     DINTEGER  integer access, len is in bytes

7     REAL    real access, len is in bytes

9     OCTET STRING octet string, len is in bytes

Byte[2]Byte[3]  为data数据的长度

Byte[4] 即数据

有时候会有填充数据即在byte[4]之后、如果数据长度不满足length的话会填充0x00

列如 byte[2]byte[3] 的长度值为3 就会在byte[4]后填充两个0x00

还是整体在图示一遍吧

 好了,这个功能算是啃完了,其他的功能也大致都一样,所以呢剩下的时候我可能会比较懒了哈哈。

3、0x05 写入数据

这就很好理解了吧,有读必有写。那写我们去推断一下,是不是在发包的时候比读数据会多一个Data段作为写入的值呢。答案是肯定的!

发包

Header  都与读取值一样的就不在说了

Parameter也一样图示一次吧

 叮叮叮,Data段来了

 

Byte[0]  00 返回码未定义就为00

Byte[1]  04 数据传输的大小

Byte[2]Byte[3] 数据的长度

Byte[4] 数据

是不是感觉这些都差不多一样,

计算机跟人类也是一样的。

我对你说“你好帅啊” 你是不是也会回我一句“你也好帅”,假设说你回了一句“我很帅,你很丑” 

这是不是不符合常理了,有可能你还要挨骂对吧。

那计算机也是啊,服务端发送数值,客户端不但不接受还骂服务端一句,那是不是服务端这边要报错呢。

可能例子不太恰当,意思到了就阔仪了。

言归正传,别爱我,没结果。

回包

引用上面我举的例子,那完全可以推断出来回包会会什么对吧。

发包写入了数据,那我回包是不是要回复写入成功或者失败呢。

Header部分和parameter部分都一样还是懒了些就不在描述了。

来看Data部分吧

Byte[0] FF 即为返回码

上面介绍有返回码的类型 整段的意思就是向0x000000地址写入成功

还有好多个功能码没有写,我会放到下一篇文章里。

原因:懒了懒了懒了

未完待续....

相关文件文档下载:https://download.csdn.net/download/Db2k_/12887086

 

附录一:错误码具体含义

0x0000

没有错误

0x0110

块号无效

0x0111

请求长度无效

0x0112

参数无效

0x0113

块类型无效

0x0114

找不到块

0x0115

块已存在

0x0116

块被写保护

0x0117

块/操作系统更新太大

0x0118

块号无效

0x0119

输入的密码不正确

0x011A

PG资源错误

0x011B

PLC资源错误

0x011C

协议错误

0x011D

块太多(与模块相关的限制)

0x011E

不再与数据库建立连接,或者S7DOS句柄无效

0x011F

结果缓冲区太小

0x0120

块结束列表

0x0140

可用内存不足

0x0141

由于缺少资源,无法处理作业

0x8001

当块处于当前状态时,无法执行请求的服务

0x8003

S7协议错误:传输块时发生错误

0x8100

应用程序,一般错误:远程模块未知的服务

0x8104

未在模块上实现此服务或报告了帧错误

0x8204

对象的类型规范不一致

0x8205

复制的块已存在且未链接

0x8301

模块上的内存空间或工作内存不足,或者指定的存储介质不可访问

0x8302

可用资源太少或处理器资源不可用

0x8304

无法进一步并行上传。存在资源瓶颈

0x8305

功能不可用

0x8306

工作内存不足(用于复制,链接,加载AWP)

0x8307

保持性工作记忆不够(用于复制,链接,加载AWP)

0x8401

S7协议错误:无效的服务序列(例如,加载或上载块)

0x8402

由于寻址对象的状态,服务无法执行

0x8404

S7协议:无法执行该功能

0x8405

远程块处于DISABLE状态(CFB)。该功能无法执行

0x8500

S7协议错误:帧错误

0x8503

来自模块的警报:服务过早取消

0x8701

寻址通信伙伴上的对象时出错(例如,区域长度错误)

0x8702

模块不支持所请求的服务

0x8703

拒绝访问对象

0x8704

访问错误:对象已损坏

0xD001

协议错误:非法的作业号

0xD002

参数错误:非法的作业变体

0xD003

参数错误:模块不支持调试功能

0xD004

参数错误:作业状态非法

0xD005

参数错误:作业终止非法

0xD006

参数错误:非法链路断开ID

0xD007

参数错误:缓冲区元素数量非法

0xD008

参数错误:扫描速率非法

0xD009

参数错误:执行次数非法

0xD00A

参数错误:非法触发事件

0xD00B

参数错误:非法触发条件

0xD011

调用环境路径中的参数错误:块不存在

0xD012

参数错误:块中的地址错误

0xD014

参数错误:正在删除/覆盖块

0xD015

参数错误:标签地址非法

0xD016

参数错误:由于用户程序错误,无法测试作业

0xD017

参数错误:非法触发号

0xD025

参数错误:路径无效

0xD026

参数错误:非法访问类型

0xD027

参数错误:不允许此数据块数

0xD031

内部协议错误

0xD032

参数错误:结果缓冲区长度错误

0xD033

协议错误:作业长度错误

0xD03F

编码错误:参数部分出错(例如,保留字节不等于0)

0xD041

数据错误:非法状态列表ID

0xD042

数据错误:标签地址非法

0xD043

数据错误:找不到引用的作业,检查作业数据

0xD044

数据错误:标签值非法,检查作业数据

0xD045

数据错误:HOLD中不允许退出ODIS控制

0xD046

数据错误:运行时测量期间非法测量阶段

0xD047

数据错误:“读取作业列表”中的非法层次结构

0xD048

数据错误:“删除作业”中的非法删除ID

0xD049

“替换作业”中的替换ID无效

0xD04A

执行\'程序状态\'时出错

0xD05F

编码错误:数据部分出错(例如,保留字节不等于0,...)

0xD061

资源错误:没有作业的内存空间

0xD062

资源错误:作业列表已满

0xD063

资源错误:触发事件占用

0xD064

资源错误:没有足够的内存空间用于一个结果缓冲区元素

0xD065

资源错误:没有足够的内存空间用于多个结果缓冲区元素

0xD066

资源错误:可用于运行时测量的计时器被另一个作业占用

0xD067

资源错误:“修改标记”作业过多(特别是多处理器操作)

0xD081

当前模式下不允许使用的功能

0xD082

模式错误:无法退出HOLD模式

0xD0A1

当前保护级别不允许使用的功能

0xD0A2

目前无法运行,因为正在运行的函数会修改内存

0xD0A3

I / O上活动的“修改标记”作业太多(特别是多处理器操作)

0xD0A4

\'强制\'已经建立

0xD0A5

找不到引用的作业

0xD0A6

无法禁用/启用作业

0xD0A7

无法删除作业,例如因为当前正在读取作业

0xD0A8

无法替换作业,例如因为当前正在读取或删除作业

0xD0A9

无法读取作业,例如因为当前正在删除作业

0xD0AA

处理操作超出时间限制

0xD0AB

进程操作中的作业参数无效

0xD0AC

进程操作中的作业数据无效

0xD0AD

已设置操作模式

0xD0AE

作业是通过不同的连接设置的,只能通过此连接进行处理

0xD0C1

访问标签时至少检测到一个错误

0xD0C2

切换到STOP / HOLD模式

0xD0C3

访问标记时至少检测到一个错误。模式更改为STOP / HOLD

0xD0C4

运行时测量期间超时

0xD0C5

块堆栈的显示不一致,因为块被删除/重新加载

0xD0C6

作业已被删除,因为它所引用的作业已被删除

0xD0C7

由于退出了STOP模式,因此作业被自动删除

0xD0C8

由于测试作业和正在运行的程序之间不一致,“块状态”中止

0xD0C9

通过复位OB90退出状态区域

0xD0CA

通过在退出前重置OB90并访问错误读取标签退出状态范围

0xD0CB

外设输出的输出禁用再次激活

0xD0CC

调试功能的数据量受时间限制

0xD201

块名称中的语法错误

0xD202

函数参数中的语法错误

0xD205

RAM中已存在链接块:无法进行条件复制

0xD206

EPROM中已存在链接块:无法进行条件复制

0xD208

超出模块的最大复制(未链接)块数

0xD209

(至少)模块上找不到给定块之一

0xD20A

超出了可以与一个作业链接的最大块数

0xD20B

超出了一个作业可以删除的最大块数

0xD20C

OB无法复制,因为关联的优先级不存在

0xD20D

SDB无法解释(例如,未知数)

0xD20E

没有(进一步)阻止可用

0xD20F

超出模块特定的最大块大小

0xD210

块号无效

0xD212

标头属性不正确(与运行时相关)

0xD213

SDB太多。请注意对正在使用的模块的限制

0xD216

无效的用户程序 - 重置模块

0xD217

不允许在模块属性中指定的保护级别

0xD218

属性不正确(主动/被动)

0xD219

块长度不正确(例如,第一部分或整个块的长度不正确)

0xD21A

本地数据长度不正确或写保护错误

0xD21B

模块无法压缩或压缩早期中断

0xD21D

传输的动态项目数据量是非法的

0xD21E

无法为模块(例如FM,CP)分配参数。系统数据无法链接

0xD220

编程语言无效。请注意对正在使用的模块的限制

0xD221

连接或路由的系统数据无效

0xD222

全局数据定义的系统数据包含无效参数

0xD223

通信功能块的实例数据块错误或超出最大背景数据块数

0xD224

SCAN系统数据块包含无效参数

0xD225

DP系统数据块包含无效参数

0xD226

块中发生结构错误

0xD230

块中发生结构错误

0xD231

至少有一个已加载的OB无法复制,因为关联的优先级不存在

0xD232

加载块的至少一个块编号是非法的

0xD234

块在指定的内存介质或作业中存在两次

0xD235

该块包含不正确的校验和

0xD236

该块不包含校验和

0xD237

您将要加载块两次,即CPU上已存在具有相同时间戳的块

0xD238

指定的块中至少有一个不是DB

0xD239

至少有一个指定的DB在装载存储器中不可用作链接变量

0xD23A

至少有一个指定的DB与复制和链接的变体有很大不同

0xD240

违反了协调规则

0xD241

当前保护级别不允许该功能

0xD242

处理F块时的保护冲突

0xD250

更新和模块ID或版本不匹配

0xD251

操作系统组件序列不正确

0xD252

校验和错误

0xD253

没有可用的可执行加载程序; 只能使用存储卡进行更新

0xD254

操作系统中的存储错误

0xD280

在S7-300 CPU中编译块时出错

0xD2A1

块上的另一个块功能或触发器处于活动状态

0xD2A2

块上的触发器处于活动状态。首先完成调试功能

0xD2A3

块未激活(链接),块被占用或块当前被标记为删除

0xD2A4

该块已被另一个块函数处理

0xD2A6

无法同时保存和更改用户程序

0xD2A7

块具有“未链接”属性或未处理

0xD2A8

激活的调试功能阻止将参数分配给CPU

0xD2A9

正在为CPU分配新参数

0xD2AA

当前正在为模块分配新参数

0xD2AB

当前正在更改动态配置限制

0xD2AC

正在运行的激活或取消激活分配(SFC 12)暂时阻止R-KiR过程

0xD2B0

在RUN(CiR)中配置时发生错误

0xD2C0

已超出最大工艺对象数

0xD2C1

模块上已存在相同的技术数据块

0xD2C2

无法下载用户程序或下载硬件配置

0xD401

信息功能不可用

0xD402

信息功能不可用

0xD403

服务已登录/注销(诊断/ PMC)

0xD404

达到的最大节点数。不再需要登录诊断/ PMC

0xD405

不支持服务或函数参数中的语法错误

0xD406

当前不可用的必需信息

0xD407

发生诊断错误

0xD408

更新已中止

0xD409

DP总线错误

0xD601

函数参数中的语法错误

0xD602

输入的密码不正确

0xD603

连接已合法化

0xD604

已启用连接

0xD605

由于密码不存在,因此无法进行合法化

0xD801

至少有一个标记地址无效

0xD802

指定的作业不存在

0xD803

非法的工作状态

0xD804

非法循环时间(非法时基或多个)

0xD805

不能再设置循环读取作业

0xD806

引用的作业处于无法执行请求的功能的状态

0xD807

功能因过载而中止,这意味着执行读取周期所需的时间比设置的扫描周期时间长

0xDC01

日期和/或时间无效

0xE201

CPU已经是主设备

0xE202

由于闪存模块中的用户程序不同,无法进行连接和更新

0xE203

由于固件不同,无法连接和更新

0xE204

由于内存配置不同,无法连接和更新

0xE205

由于同步错误导致连接/更新中止

0xE206

由于协调违规而拒绝连接/更新

0xEF01

S7协议错误:ID2错误; 工作中只允许00H

0xEF02

S7协议错误:ID2错误; 资源集不存在