某站弹幕Protobuf协议逆向分析 | Go语言版本

2023-10-29 16:50

本文主要是介绍某站弹幕Protobuf协议逆向分析 | Go语言版本,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

​一杯敬明天,一杯敬过往。大家好,我是TheWeiJun,时间过得好快,转眼间春节已过,此刻大家都已经开始复工了吧!首先祝大家新年快乐、2023年一路旺旺旺。小编也是心情激动,才有了前面的开场白。直入主题:今天给大家带来某站弹幕protobuf协议逆向分析,全程高能,在阅读的同时不要忘记点赞+关注哦⛽️

特别声明:本公众号文章只作为学术研究,不用于其它不法用途;如有侵权请联系作者删除。

立即加星标

每天看好文

 目录

一、前言介绍

二、网站分析

三、Protobuf协议还原

四、完整代码实现

五、思路总结


新年展望

这是本公众号2023年的第一篇文章,今天写这篇文章是为了解决某个粉丝提到的问题:如何实现某站弹幕protubuf协议还原,最好是用Go语言去实现。小编看到粉丝提到的问题故写了这篇文章分享给各位,希望对大家提高技术有一定的帮助。然后给大家分享一个好消息,经过2022年坚持不懈的努力,作者创作了32篇文章,官方给予作者科技自媒体黄标认证。能拿到这个官方认证,我要感谢各位粉丝的陪伴和鼓励。也感谢对TheWeiJun提供技术指导的朋友,希望大家在2023年技术能更上一层楼⛽️。黄标公众号如下:

逆向与爬虫的故事

专注于网络爬虫、JS逆向、APP逆向、安全攻防实战经验分享及总结。

公众号


一、前言介绍

什么是protobuf协议?

前言:Protobuf (Protocol Buffers) 是谷歌开发的一款无关平台,无关语言,可扩展,轻量级高效的序列化结构的数据格式,用于将自定义数据结构序列化成字节流,和将字节流反序列化为数据结构。所以很适合做数据存储和为不同语言,不同应用之间互相通信的数据交换格式,只要实现相同的协议格式,即后缀为proto文件被编译成不同的语言版本,加入各自的项目中,这样不同的语言可以解析其它语言通过Protobuf序列化的数据。目前官方提供c++,java,go等语言支持。


二、网站分析

1、首先打开我们本次分析的网站,搜索指定弹幕内容,截图如下图所示:

环节说明由于弹幕内容使用了protobuf协议,所以无法直接搜索定位,我们需要分析response数据包请求,去定位具体的url链接。

2、分析Response数据包请求,定位到弹幕链接,截图如下所示:

环节说明:从截图中我们可以清楚看出,这就是弹幕的内容。但是毕竟该网站使用了protobuf协议编码,如果我们想还原出明文信息,接下来需要去进行JS断点调试分析了。

3、使用xhr/fetch对该请求打断点调试,截图如下图所示:

环节说明因为该请求是对response进行了protobuf协议编码,所以我们定位到该请求发包位置后,只需要关注后面的协议解码逻辑即可实现明文信息还原。

4、打好断点后,点击操作按钮,截图如下图所示:

说明:此刻r变量即为我们要访问的弹幕url地址,定位到url地址后,我们需要接下来继续执行断点进行跟栈。

5、继续执行断点,持续调式,截图如下图所示:

5.1、此刻我们打印变量r的值,截图如下所示:

说明:这不就是我们想要的明文信息么?接下来,我们只需要找到protobuf协议初始化参数id定义就可以还原明文了。

6、经过JS断点调试,最终定位到protobuf协议初始化参数如下:

7、将Console中的数据复制后进行JSON在线格式化解析,截图如下:

总结:知道response明文及protobuf协议定义的参数规则后,接下来我们只需要构建protoc文件即可完成对整个弹幕明文信息的还原。


三、Protobuf协议还原

1、还原protobuf协议,编辑go语言protobuf代码结构如下:

2、执行如下命令,编译为golang protobuf可执行文件:

protoc  --go_out=. *.proto

3、运行以上命令后,生成.pb.go代码文件,截图如下图所示:

总结:走到这里protobuf协议就完全还原了,接下来让我们进入完整go代码实现环节吧。


四、完整代码实现

1、整个项目完整代码如下:

package main
​
import ("fmt""github.com/golang/protobuf/proto"resp "hello/bilibili""io/ioutil""log""net/http"
)
​
func main() {client := &http.Client{}req, err := http.NewRequest("GET", "https://xxxx/x/v2/dm/web/seg.so?type=1&segment_index=1", nil)if err != nil {log.Fatal(err)}req.Header.Set("user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36")req.Header.Set("accept", "*/*")req.Header.Set("accept-language", "zh-CN,zh;q=0.9")req.Header.Set("cache-control", "no-cache")req.Header.Set("origin", "https://www.xxxx.com")req.Header.Set("pragma", "no-cache")req.Header.Set("sec-ch-ua-mobile", "?0")req.Header.Set("sec-ch-ua-platform", `"macOS"`)req.Header.Set("sec-fetch-dest", "empty")req.Header.Set("sec-fetch-mode", "cors")req.Header.Set("sec-fetch-site", "same-site")resp, err := client.Do(req)if err != nil {log.Fatal(err)}defer resp.Body.Close()bodyText, err := ioutil.ReadAll(resp.Body)if err != nil {log.Fatal(err)}processBody(bodyText)
}
​
func processBody(body []byte) {response := resp.Feed{}err := proto.Unmarshal(body, &response)if err != nil {log.Fatal(err)}messages := response.Messagefor _, message := range messages {fmt.Println(message.Content, message.IdStr)}
}

2、代码编辑完毕后,我们运行代码,截图如下图所示:


五、思路总结

回顾整个分析流程,本次难点主要概括为以下几点:

  • 如何快速定位加密协议的位置

  • 了解并熟练掌握protobuf协议

  • 能够通过源码还原proto文件

  • 如何在golang中使用protobuf

今天分享到这里就结束了,欢迎大家关注下期文章,我们不见不散⛽️


  往期回顾

▶ 某游戏社区App | So层逆向分析

▶ 某容器管理平台模拟登录(Go语言版本)

▶ 某麦最新analysis算法逆向分析(多种语言实现)

▶ B站弹幕protobuf协议还原分析

▶ GoLang - colly爬虫框架


    我是TheWeiJun,有着执着的追求,信奉终身成长,不定义自己,热爱技术但不拘泥于技术,爱好分享,喜欢读书和乐于结交朋友,欢迎加我微信与我交朋友。

    分享日常学习中关于爬虫、逆向和分析的一些思路,文中若有错误的地方,欢迎大家多多交流指正☀️

这篇关于某站弹幕Protobuf协议逆向分析 | Go语言版本的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/301986

相关文章

C语言中位操作的实际应用举例

《C语言中位操作的实际应用举例》:本文主要介绍C语言中位操作的实际应用,总结了位操作的使用场景,并指出了需要注意的问题,如可读性、平台依赖性和溢出风险,文中通过代码介绍的非常详细,需要的朋友可以参... 目录1. 嵌入式系统与硬件寄存器操作2. 网络协议解析3. 图像处理与颜色编码4. 高效处理布尔标志集合

Go语言开发实现查询IP信息的MCP服务器

《Go语言开发实现查询IP信息的MCP服务器》随着MCP的快速普及和广泛应用,MCP服务器也层出不穷,本文将详细介绍如何在Go语言中使用go-mcp库来开发一个查询IP信息的MCP... 目录前言mcp-ip-geo 服务器目录结构说明查询 IP 信息功能实现工具实现工具管理查询单个 IP 信息工具的实现服

C 语言中enum枚举的定义和使用小结

《C语言中enum枚举的定义和使用小结》在C语言里,enum(枚举)是一种用户自定义的数据类型,它能够让你创建一组具名的整数常量,下面我会从定义、使用、特性等方面详细介绍enum,感兴趣的朋友一起看... 目录1、引言2、基本定义3、定义枚举变量4、自定义枚举常量的值5、枚举与switch语句结合使用6、枚

Java程序进程起来了但是不打印日志的原因分析

《Java程序进程起来了但是不打印日志的原因分析》:本文主要介绍Java程序进程起来了但是不打印日志的原因分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java程序进程起来了但是不打印日志的原因1、日志配置问题2、日志文件权限问题3、日志文件路径问题4、程序

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

go 指针接收者和值接收者的区别小结

《go指针接收者和值接收者的区别小结》在Go语言中,值接收者和指针接收者是方法定义中的两种接收者类型,本文主要介绍了go指针接收者和值接收者的区别小结,文中通过示例代码介绍的非常详细,需要的朋友们下... 目录go 指针接收者和值接收者的区别易错点辨析go 指针接收者和值接收者的区别指针接收者和值接收者的

Python 迭代器和生成器概念及场景分析

《Python迭代器和生成器概念及场景分析》yield是Python中实现惰性计算和协程的核心工具,结合send()、throw()、close()等方法,能够构建高效、灵活的数据流和控制流模型,这... 目录迭代器的介绍自定义迭代器省略的迭代器生产器的介绍yield的普通用法yield的高级用法yidle

Go 语言中的select语句详解及工作原理

《Go语言中的select语句详解及工作原理》在Go语言中,select语句是用于处理多个通道(channel)操作的一种控制结构,它类似于switch语句,本文给大家介绍Go语言中的select语... 目录Go 语言中的 select 是做什么的基本功能语法工作原理示例示例 1:监听多个通道示例 2:带

C++ Sort函数使用场景分析

《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序

C语言函数递归实际应用举例详解

《C语言函数递归实际应用举例详解》程序调用自身的编程技巧称为递归,递归做为一种算法在程序设计语言中广泛应用,:本文主要介绍C语言函数递归实际应用举例的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录前言一、递归的概念与思想二、递归的限制条件 三、递归的实际应用举例(一)求 n 的阶乘(二)顺序打印