当前位置: 首页 > article >正文

告别黑盒:用Python手把手解析SMPP协议PDU,从抓包到解码一条龙

告别黑盒用Python手把手解析SMPP协议PDU从抓包到解码一条龙当你在深夜收到短信网关返回的一串十六进制数据时是否曾对着Wireshark抓包界面陷入沉思SMPP协议作为运营商短信系统的暗语其二进制PDU结构常让开发者望而生畏。本文将带你像法医解剖证据链一样逐字节拆解真实网络包中的SMPP协议数据单元。1. 从抓包到Python构建SMPP解析实验室在开始解码之前我们需要搭建一个可重现的分析环境。不同于标准文档中的理想化示例真实网络环境中的SMPP数据往往夹杂着各种噪音。必备工具清单Wireshark3.6.10及SMPP协议插件Python 3.8 并安装struct、binascii、dpkt库测试用pcapng文件建议包含Bind、Submit、Deliver三种操作# 读取抓包文件的Python示例 import dpkt def load_pcap(file_path): with open(file_path, rb) as f: pcap dpkt.pcap.Reader(f) for ts, buf in pcap: eth dpkt.ethernet.Ethernet(buf) if isinstance(eth.data, dpkt.ip.IP): ip eth.data if isinstance(ip.data, dpkt.tcp.TCP): tcp ip.data if len(tcp.data) 0: yield tcp.data注意实际抓包中TCP可能分片需实现重组逻辑。运营商网关通常使用默认端口2775但某些云服务商会使用随机端口。2. 庖丁解牛SMPP PDU结构深度解析SMPP协议的精髓在于其PDU协议数据单元的二进制结构。不同于HTTP等文本协议每个字段的字节偏移和编码方式都至关重要。2.1 Header的十六进制密码本每个SMPP PDU都以16字节的Header开头用Python的struct模块可以轻松解析import struct def parse_header(raw_data): 解析SMPP Header的四个关键字段 try: cmd_len, cmd_id, cmd_status, seq_num struct.unpack(4I, raw_data[:16]) return { command_length: cmd_len, command_id: f0x{cmd_id:08X}, command_status: cmd_status, sequence_number: seq_num } except struct.error as e: raise ValueError(fHeader解析失败: {str(e)})关键字段对照表字段名字节位置类型示例值说明command_length0-3uint320x00000045包含Header的完整PDU长度command_id4-7uint320x00000004Submit_SM操作码command_status8-11uint320x000000000表示成功sequence_number12-15uint320x000003A7请求响应匹配ID2.2 Body的迷宫导航Submit_SM的Body部分就像俄罗斯套娃每个字段都有特定的编码规则。以下是处理可变长度字符串的实用方法def parse_c_octet_string(data, max_len): 解析NULL结尾的C-Octet-String null_pos data.find(b\x00) if null_pos -1 and len(data) max_len: raise ValueError(Invalid C-Octet-String: missing NULL terminator) return data[:null_pos].decode(latin1)处理短信内容时需要特别注意编码问题。国内运营商常用的编码方式def decode_sms_content(raw_data, data_coding): 根据data_coding解码短信内容 if data_coding 0x00: # GSM7 return gsm0338.decode(raw_data) elif data_coding 0x08: # UCS2 return raw_data.decode(utf-16be) else: return raw_data.hex() # 未知编码返回十六进制3. 实战演练解析真实运营商PDU让我们解剖一个来自国内某运营商的真实Submit_SM响应00000045 80000004 00000000 000003A7 00 01 01 31 33 37 30 30 30 30 30 30 30 30 00 01 01 31 38 36 31 32 33 34 35 36 37 38 00 00 00 00 00 00 01 00 0B 48 65 6C 6C 6F 20 57 6F 72 6C 64逐步解析过程Header解析Command Length: 0x45 → 69字节Command ID: 0x80000004 → Submit_SM响应Sequence Number: 0x3A7 → 请求ID 935Body解析service_type: 空字符串第一个字节就是\x00source_addr_ton: 0x01国际号码source_addr_npi: 0x01ISDN编号source_addr: 13700000000dest_addr_ton: 0x01dest_addr_npi: 0x01destination_addr: 18612345678sm_length: 0x0B → 11字节short_message: Hello World4. 异常处理当PDU不按套路出牌真实的运营商环境远比标准复杂以下是三个常见陷阱及解决方案案例1长度字段与实际不符def validate_pdu_length(raw_data): declared_len struct.unpack(I, raw_data[:4])[0] if declared_len ! len(raw_data): print(f警告声明长度{declared_len} ≠ 实际长度{len(raw_data)}) # 尝试自动修复截断或补零 return raw_data[:declared_len] if declared_len len(raw_data) else raw_data.ljust(declared_len, b\x00) return raw_data案例2乱码的短信内容当遇到编码问题时可以尝试多种解码方式def safe_decode(content, data_coding): for encoding in [gsm0338, utf-16be, gb2312, latin1]: try: return content.decode(encoding) except UnicodeDecodeError: continue return content.hex()案例3神秘的TLV参数可选参数的解析需要特别注意字节对齐def parse_tlv_params(raw_data): params {} ptr 0 while ptr 4 len(raw_data): tag, length struct.unpack(HH, raw_data[ptr:ptr4]) ptr 4 if ptr length len(raw_data): break value raw_data[ptr:ptrlength] params[f{tag:04X}] value.hex() ptr length return params5. 进阶技巧长短信与状态报告处理国内运营商的长短信通常采用UDHGSM7编码方式需要特殊处理def parse_concatenated_sms(udh, content): ref_num udh[3] total_parts udh[4] part_num udh[5] return { reference_number: ref_num, total_parts: total_parts, part_number: part_num, content: content.decode(gsm0338) }对于状态报告Deliver_SM中的message_payload建议使用正则提取关键信息import re def parse_delivery_report(payload): pattern rid:(\d) sub:(\d) dlvrd:(\d) submit date:(\d) done date:(\d) stat:([A-Z]) err:(\d) match re.search(pattern, payload.decode(latin1)) if match: return { message_id: match.group(1), status: match.group(6), error_code: match.group(7) }6. 构建SMPP调试工具箱将上述方法封装成实用工具类class SmppDebugger: def __init__(self): self.sequence_map {} # 用于跟踪请求-响应 def analyze_pcap(self, pcap_path): results [] for pdu in load_pcap(pcap_path): try: header parse_header(pdu) body self.parse_body(header[command_id], pdu[16:]) results.append({**header, **body}) except Exception as e: print(f解析失败: {str(e)}) return results def parse_body(self, command_id, body_data): # 实现各命令类型的Body解析 pass最后分享一个实用技巧在测试环境使用subprocess启动Wireshark实时抓包import subprocess def start_capture(interfaceeth0, port2775): cmd [ tshark, -i, interface, -f, ftcp port {port}, -w, /tmp/smpp_capture.pcap ] return subprocess.Popen(cmd)

相关文章:

告别黑盒:用Python手把手解析SMPP协议PDU,从抓包到解码一条龙

告别黑盒:用Python手把手解析SMPP协议PDU,从抓包到解码一条龙 当你在深夜收到短信网关返回的一串十六进制数据时,是否曾对着Wireshark抓包界面陷入沉思?SMPP协议作为运营商短信系统的"暗语",其二进制PDU结构…...

极速获取全平台歌词:163MusicLyrics跨平台解析工具使用指南

极速获取全平台歌词:163MusicLyrics跨平台解析工具使用指南 【免费下载链接】163MusicLyrics Windows 云音乐歌词获取【网易云、QQ音乐】 项目地址: https://gitcode.com/GitHub_Trending/16/163MusicLyrics 你是否经常遇到想听的歌曲找不到匹配歌词的情况&a…...

革命性AI肖像动画工具LivePortrait:一键让静态照片“动“起来

革命性AI肖像动画工具LivePortrait:一键让静态照片"动"起来 【免费下载链接】LivePortrait Bring portraits to life! 项目地址: https://gitcode.com/GitHub_Trending/li/LivePortrait 你是否曾经想过让老照片中的亲人重新展露笑容?或…...

技术数据解析 | CALCE圆柱电池数据集:SOC估计的OCV测试基准

1. CALCE圆柱电池数据集的核心价值 CALCE电池数据集由马里兰大学先进生命周期工程中心发布,是目前全球最权威的公开电池测试数据之一。这个数据集最吸引我的地方在于它提供了完整的实验环境记录和标准化的测试流程,这对于电池状态估计算法的开发简直是雪…...

【PAT甲级真题】- Shopping in Mars (25)

题目来源 Shopping in Mars (25) 题目描述点击链接自行查看 注意点: 输出时按照区间左端点从小到大输出 思路简介 简单的滑动窗口 我做了一个小处理 因为题目实际上要求找的是大于等于目标值的区间 所以移动左指针的条件写成 l>r&&sum>m 这样我认…...

uni-app实战:驰腾打印机蓝牙对接与二维码打印全解析

1. 为什么选择uni-app对接驰腾打印机? 在移动开发领域,跨平台解决方案越来越受到开发者青睐。uni-app作为一款基于Vue.js的跨平台框架,可以一次开发同时发布到iOS、Android以及各种小程序平台。这种特性使得它成为对接硬件设备的理想选择&am…...

Vitis 2022.1下,Ultrascale+ MPSOC PL端lwIP以太网完整配置流程(含约束文件与时钟设置)

Vitis 2022.1环境下Ultrascale MPSOC PL端lwIP以太网全流程实战指南 当我们需要在Zynq Ultrascale MPSOC平台上实现高性能网络通信时,PL端以太网方案往往能提供比PS端更灵活的设计空间和更高的吞吐量。本文将手把手带你完成从Vivado工程创建到Vitis应用部署的完整流…...

AI头像生成器与SpringBoot集成实战:企业级应用开发指南

AI头像生成器与SpringBoot集成实战:企业级应用开发指南 你有没有想过,为什么现在很多电商平台的新用户注册后,头像都那么有个性,而且风格还挺统一?这背后其实不是设计师在加班加点,而是AI头像生成器在默默…...

3分钟终极解决方案:快速解除Cursor试用限制的完整指南

3分钟终极解决方案:快速解除Cursor试用限制的完整指南 【免费下载链接】go-cursor-help 解决Cursor在免费订阅期间出现以下提示的问题: Youve reached your trial request limit. / Too many free trial accounts used on this machine. Please upgrade to pro. We …...

避坑指南:在Windows 11上用Docker Compose一键部署Casdoor(含MySQL和持久化配置)

Windows 11容器化部署Casdoor全攻略:告别环境配置噩梦 "明明按照文档一步步操作,为什么我的Casdoor就是跑不起来?"这可能是许多Windows开发者初次接触开源身份认证系统时的共同困惑。传统部署方式需要手动配置Go、Node.js、Yarn、…...

保姆级教程:在银河麒麟V10上,用Qt Installer Framework打包Unity游戏(附快捷方式配置)

银河麒麟V10系统下Unity游戏打包全流程实战:从安装配置到桌面快捷方式优化 在国产操作系统生态逐渐成熟的今天,银河麒麟V10作为主流国产Linux发行版之一,为独立游戏开发者提供了新的发布平台选择。本文将深入讲解如何利用Qt Installer Frame…...

PP-DocLayoutV3跨平台文档处理方案:兼容Windows、Linux与macOS

PP-DocLayoutV3跨平台文档处理方案:兼容Windows、Linux与macOS 最近在折腾文档智能处理,发现了一个挺有意思的模型服务——PP-DocLayoutV3。简单来说,它能帮你自动分析文档图片,把里面的文字、表格、图片、标题什么的&#xff0c…...

GHelper:华硕笔记本性能调校神器,让你的ROG设备焕发新生

GHelper:华硕笔记本性能调校神器,让你的ROG设备焕发新生 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops. Control tool for ROG Zephyrus G14, G15, G16, M16, Flow X13, Flow X16, TUF, Strix, Scar and other mod…...

智能家居DIY实战:用海凌科HLK-V20-SUIT语音模块改造你的旧台灯/风扇(STM32核心)

智能家居DIY实战:用海凌科HLK-V20-SUIT语音模块改造旧家电 去年夏天,我在工作室里大汗淋漓地调试电路板时,突然冒出一个想法:如果能用语音控制身边的老式台灯和风扇该多方便?于是开始了这场旧物智能化的改造之旅。本文…...

解决Qt程序异常结束的终极指南:从pro文件配置到动态库加载

Qt程序异常崩溃全链路排查手册:从配置陷阱到动态库依赖治理 当你盯着QtCreator控制台里那个刺眼的"程序异常结束"提示时,内心是否在咆哮:"明明代码逻辑没问题,为什么还会崩溃?"这不是你一个人的困…...

图片木马检测与防御:如何用PHP代码识别恶意图片上传(2024最新版)

图片木马检测与防御:2024年PHP实战指南 在数字化浪潮中,图片上传功能已成为网站标配,但这也为攻击者提供了可乘之机。去年某电商平台因图片木马导致百万用户数据泄露的事件,再次敲响了安全警钟。本文将深入剖析如何用PHP构建坚不可…...

避开SDR通信的‘坑’:我在用Pluto做16QAM传输时遇到的相位偏移和同步问题

避开SDR通信的‘坑’:我在用Pluto做16QAM传输时遇到的相位偏移和同步问题 第一次用Pluto SDR搭建16QAM通信链路时,我盯着屏幕上扭曲的星座图发呆了半小时——理论上完美的16个星点,在实际接收时却像被无形的手揉成了一团毛线。这种挫败感想必…...

FreeRTOS系统时钟节拍配置指南:从1ms到100ms如何选择最优心跳频率(含STM32F4实测数据)

FreeRTOS系统时钟节拍配置实战:从理论到STM32F4调优全解析 在嵌入式实时操作系统领域,系统时钟节拍如同人体心跳般重要——它决定了系统处理延时、超时等时间相关事件的精度与效率。对于使用FreeRTOS的开发者而言,时钟节拍频率的选择绝非简单…...

计算机硕,是走算法岗还是开发岗?

咳咳,煮啵说句可能得罪人的话——这个问题本身就问错了。不是说这个问题不重要,而是大部分人在问这个问题的时候,脑子里的决策框架就是拧的。他们把”算法”和”开发”想象成两条泾渭分明的路,然后试图在岔路口做一个一劳永逸的选…...

保姆级教程:在RHEL 8上彻底搞定X-Server远程连接,让xeyes不再报‘Error can‘t open display‘

深度解析RHEL 8远程X11连接:从原理到实战的全链路解决方案 当你在RHEL 8服务器上尝试通过SSH转发X11图形界面时,是否遇到过xeyes测试程序报出"Error: Cant open display"的困扰?这看似简单的错误背后,实际上隐藏着新版R…...

CoPaw模型多轮对话效果深度评测:连贯性、逻辑性与知识准确性

CoPaw模型多轮对话效果深度评测:连贯性、逻辑性与知识准确性 1. 开场白:为什么关注多轮对话能力 最近测试了不下20个大语言模型,发现一个有趣现象:单轮问答表现都不错,但一到多轮对话就原形毕露。有的模型聊着聊着就…...

3步突破3D点云标注效率瓶颈,让训练数据生成速度提升60%

3步突破3D点云标注效率瓶颈,让训练数据生成速度提升60% 【免费下载链接】labelCloud 项目地址: https://gitcode.com/gh_mirrors/la/labelCloud 在自动驾驶、机器人导航和AR/VR等领域,3D点云标注是构建精确模型的关键步骤。然而,传统…...

GuwenBERT:让AI读懂千年古文,开启古籍智能处理新时代

GuwenBERT:让AI读懂千年古文,开启古籍智能处理新时代 【免费下载链接】guwenbert GuwenBERT: 古文预训练语言模型(古文BERT) A Pre-trained Language Model for Classical Chinese (Literary Chinese) 项目地址: https://gitcod…...

圣女司幼幽-造相Z-Turbo开发利器:VS Code与GitHub高效协作配置

圣女司幼幽-造相Z-Turbo开发利器:VS Code与GitHub高效协作配置 最近在折腾圣女司幼幽-造相Z-Turbo这个项目,发现团队协作效率是个大问题。代码在本地改完,传到服务器上跑,结果不对,又得拉下来改,一来二去时…...

终极美化指南:3步将你的foobar2000打造成专业音乐工作站

终极美化指南:3步将你的foobar2000打造成专业音乐工作站 【免费下载链接】foobox-cn DUI 配置 for foobar2000 项目地址: https://gitcode.com/GitHub_Trending/fo/foobox-cn 还在忍受foobar2000那单调乏味的默认界面吗?foobox-cn作为一款专为foo…...

Qwen3-ASR-0.6B与Anaconda环境配置:一站式语音识别开发平台

Qwen3-ASR-0.6B与Anaconda环境配置:一站式语音识别开发平台 1. 引言 语音识别技术正在改变我们与设备交互的方式,从智能助手到实时字幕,从会议记录到语音搜索,这项技术已经深入到我们生活的方方面面。今天我要跟大家分享的是如何…...

不止于采集:用BrainFlow解锁DeepBCI脑电信号的进阶玩法(特征提取与简单分类)

不止于采集:用BrainFlow解锁DeepBCI脑电信号的进阶玩法(特征提取与简单分类) 当你已经能够稳定采集到DeepBCI设备的脑电信号时,那些跳动的波形背后隐藏着怎样的秘密?本文将带你跨越数据采集的门槛,探索如何…...

DocSys文件管理系统实战:5分钟搞定Java版Web文件管理平台搭建

DocSys文件管理系统实战:5分钟搞定Java版Web文件管理平台搭建 在数字化转型浪潮中,企业文档管理正面临前所未有的挑战。传统FTP服务器权限粗放,云存储方案又存在数据主权顾虑,而自建系统往往需要投入大量开发资源。DocSys作为一款…...

终极美化指南:3步打造你的专业级foobar2000音乐播放器

终极美化指南:3步打造你的专业级foobar2000音乐播放器 【免费下载链接】foobox-cn DUI 配置 for foobar2000 项目地址: https://gitcode.com/GitHub_Trending/fo/foobox-cn 你是否还在使用foobar2000那单调乏味的默认界面?每天面对灰白色的播放列…...

CTF选手必看:RSA算法从数学原理到实战解题技巧(附常见题型解析)

CTF选手必看:RSA算法从数学原理到实战解题技巧(附常见题型解析) 1. RSA算法核心数学原理 RSA算法的安全性建立在大整数分解难题和欧拉定理之上。理解以下数学概念是解题基础: 欧拉函数φ(n):对于npq(p、q为…...