第一次写文章,难免会有差错,文章若有不妥之处,还请大家不吝赐教~
希望这篇文章对你有帮助,可以减轻入门protobuf的一些负担~
目标:
- 搭建window & Nexus6P(Kali NetHunter) 运行gRPC环境 ps:Nexus6P环境的搭建可有可无~
- 使用Python gRPC 实现: 客户端<-->服务端的protobuf的通信
- PC上 client.py 移植到Nexus6P (Kali NetHunter) 上 实现 android 与服务端(PC)交互 (ps:啥Android啊 那就是Linux.... 可有可无)
r0env2022 搭建 Android app 运行服务端环境 & 编译apk....案例Dem0可直接在r0env2022下编译运行,只需要提取出.proto文件 生成服务端代码就可直接使用~真的是太爽了,节省了时间- 拦截AndroidDem0 <--> PC 上 Python实现的服务端的通信
&反序列化
virtualenv Python310_LearningProtobuf
pip3 install virtualenv -i https://pypi.douban.com/simple
再执行 pip3 install virtualenvwrapper-win -i https://pypi.douban.com/simple
D:\Interpreter installation Directory\virtualenv
并加入系统环境PATH中mkvirtualenv Py310protobuf
并进入虚拟环境中...pip3 install protobuf grpcio grpcio-tools -i https://pypi.douban.com/simple
创建 example.proto 文件 来编写对应规则,创建了一个服务 以及两个数据格式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
syntax
=
"proto3"
;
package test;
service HelloDemo {
rpc Hello(HelloReq) returns(HelloReply){}
}
message HelloReq{
string name
=
1
;
int32 age
=
2
;
string sendtime
=
3
;
}
message HelloReply{
string result
=
1
;
}
|
利用 example.proto 通过 grpcio_tools protoc 来生成Python 客户端和服务端(grpc-server)文件 为踩坑记录
python -m grpcio_tools -I. --python_out=. --grpc_python_out=. example.proto
失败 ,原因-> 猜测应该使用./ 来 表示当前目录~protoc -I=. --python_out=. --grpc_python_out=. example.proto
对example进行编译 并生成 python客户端和服务端grpc代码python -m grpc_tools.protoc -I./ --python_out=./ --grpc_python_out=./ example.proto
生成了两份代码 根据生成的example_pb2_grpc.py编写 service.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
# coding:utf-8
import
grpc
import
example_pb2 as pb2
import
example_pb2_grpc as pb2_grpc
from
concurrent
import
futures
# 目的为了给服务器增加线程
# HelloDemo 为 .proto 文件中 service
class
HelloDemo(pb2_grpc.HelloDemoServicer):
# Hello 为 .proto 文件中 service 包含 rpc 方法名
def
Hello(
self
, request, context):
name, age, sendtime
=
request.name, request.age, sendtime
result
=
f
"My Name is {name},age is {age} years old!\n now time is {sendtime}"
# 返回数据类型为.proto 文件中 message HelloReply
return
pb2.HelloReply(result
=
result)
def
run():
grpc_server
=
grpc.server(
futures.ThreadPoolExecutor(max_workers
=
4
),
)
pb2_grpc.add_HelloDemoServicer_to_server(HelloDemo(),grpc_server)
# PC 上 监听 127.0.0.1 局域网连接 监听 0.0.0.0
ip_port
=
"127.0.0.1:5505"
grpc_server.add_insecure_port(ip_port)
grpc_server.start()
print
(f
"service start at {ip_port}"
)
grpc_server.wait_for_termination()
if
__name__
=
=
"__main__"
:
run()
|
根据生成的example_pb2.py 编写client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
# coding:utf-8
import
grpc
import
example_pb2 as pb2
import
example_pb2_grpc as pb2_grpc
from
concurrent
import
futures
def
run():
# 构建通道与服务器连接
conn
=
grpc.insecure_channel(
"127.0.0.1:5505"
)
# HelloDemoStub表示客户端 ,HelloDemoStub是 protoc 自动生成的
client
=
pb2_grpc.HelloDemoStub(channel
=
conn)
name, age, sendtime
=
"xiaozhu0513"
,
18
, datetime.now().strftime(
'%Y-%m-%d-%H:%M:%S'
)
# 相当于先生成一个 HelloReq 类型的数据 为 本地发送到客户端的数据, 然后传输 实例化客户端的
response
=
client.Hello(pb2.HelloReq(
name
=
name,
age
=
age,
sendtime
=
f
"{sendtime}"
))
print
(f
"客户端发送 {name} {age} {sendtime} -> 服务器"
)
print
(
"客户端接收到服务器返回信息 "
,response.result)
if
__name__
=
=
"__main__"
:
run()
|
先运行service.py 再运行 client.py 效果图如下
至此,完成了第一个小任务,最后查阅资料时,发现官方提供了Demo 以及教程....
目标:
在6P手机上配置好Python环境,grpc环境
运行client.py 与 PC上server.py进行交互
(未复现出)抓包拦截请求数据,尝试分析.... 当初以为只要运行在手机上就算是android了,,,后来才反应过来,,,,我是运行在linux上py程序不是android
- client.py 和 android app 走的系统底库不同(后续实现了App抓socket却可以抓到而client.py却不能抓到),
pip3 install protobuf grpcio grpcio-tools -i https://pypi.douban.com/simple
将服务端的监听端口由127.0.0.1 修改为 0.0.0.0,之后先启动server 再在6P手机上启动client.Py 实现交互
客户端启动失败! charles 抓的包为 Unknow 整体运行逻辑如下~
目标:
- 实现Android App 与 PC上建立的Python服务端进行通信
- 弄清楚普通i请求grpc 的执行流程 以及生成对应的Python服务器版本代码
- 最终实现效果可以使得二者可以正常通信,为抓包hook以及分析打下基础
只分析其中一个界面
进入对应解释器环境下 执行 python -m grpc_tools.protoc -I./ --python_out=./ --grpc_python_out=./ helloworld.proto
照猫画虎 写出对应的service.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
from
datetime
import
datetime
import
grpc
import
helloworld_pb2 as pb2
import
helloworld_pb2_grpc as pb2_grpc
from
concurrent
import
futures
class
Greeter(pb2_grpc.GreeterServicer):
def
SayHello(
self
, request, context):
name
=
request.name
sendtime
=
datetime.now().strftime(
'%Y-%m-%d-%H:%M:%S'
)
result
=
f
"My Name is {name}!!! send time is {sendtime} "
print
(f
"服务器接收到客户端参数 -> name = {name}"
)
print
(f
"服务器响应时间: {sendtime}"
)
return
pb2.HelloReply(message
=
result)
def
run():
grpc_server
=
grpc.server(
futures.ThreadPoolExecutor(max_workers
=
4
),
)
pb2_grpc.add_GreeterServicer_to_server(Greeter(),grpc_server)
# ip_port = "127.0.0.1:50051"
ip_port
=
"0.0.0.0:50051"
grpc_server.add_insecure_port(ip_port)
grpc_server.start()
print
(f
"service start at {ip_port}"
)
grpc_server.wait_for_termination()
if
__name__
=
=
"__main__"
:
run()
|
验证启动apk 能否正常通信
所有所有前期准备已经ok 准备使用hook抓包看能否抓到包~
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# 读取文件并处理
with
open
(
'my_protobuf.txt'
,
'r'
,encoding
=
'utf-8'
) as
file
:
lines
=
file
.readlines()
processed_lines
=
[]
for
line
in
lines:
# 进行处理操作
processed_line
=
"android hooking watch class "
+
line
# 将处理后的行插入到原来的列表中
processed_lines.append(processed_line)
# 将处理后的内容按行插入到原文件中
with
open
(
'my_protobuf_new.txt'
,
'w'
,encoding
=
'utf-8'
) as
file
:
for
processed_line
in
processed_lines:
file
.write(processed_line)
|
所有的输出信息如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
com.xuexiang.protobufdemo on (google:
8.1
.
0
) [usb]
# (agent) [e48kca70yae] Called com.google.protobuf.GeneratedMessageLite.toBuilder()
(agent) [e48kca70yae] Called com.google.protobuf.GeneratedMessageLite.dynamicMethod(com.google.protobuf.GeneratedMessageLite$MethodToInvoke)
(agent) [e48kca70yae] Called com.google.protobuf.GeneratedMessageLite.dynamicMethod(com.google.protobuf.GeneratedMessageLite$MethodToInvoke)
(agent) [
33h1vvf01vb
] Called com.google.protobuf.UnknownFieldSetLite.getDefaultInstance()
(agent) [r44a6fapyp] Called com.google.protobuf.GeneratedMessageLite$Builder.mergeFrom(com.google.protobuf.GeneratedMessageLite)
(agent) [r44a6fapyp] Called com.google.protobuf.GeneratedMessageLite$Builder.copyOnWrite()
(agent) [e48kca70yae] Called com.google.protobuf.GeneratedMessageLite.visit(com.google.protobuf.GeneratedMessageLite$Visitor, com.google.protobuf.GeneratedMessageLite)
(agent) [flxqngw0jns] Called com.google.protobuf.GeneratedMessageLite$MergeFromVisitor.visitString(boolean, java.lang.String, boolean, java.lang.String)
(agent) [flxqngw0jns] Called com.google.protobuf.GeneratedMessageLite$MergeFromVisitor.visitUnknownFields(com.google.protobuf.UnknownFieldSetLite, com.google.protobuf.UnknownFieldSetLite)
(agent) [
33h1vvf01vb
] Called com.google.protobuf.UnknownFieldSetLite.getDefaultInstance()
(agent) [r44a6fapyp] Called com.google.protobuf.GeneratedMessageLite$Builder.copyOnWrite()
(agent) [r44a6fapyp] Called com.google.protobuf.GeneratedMessageLite$Builder.build()
(agent) [r44a6fapyp] Called com.google.protobuf.GeneratedMessageLite$Builder.buildPartial()
(agent) [e48kca70yae] Called com.google.protobuf.GeneratedMessageLite.makeImmutable()
(agent) [e48kca70yae] Called com.google.protobuf.GeneratedMessageLite.dynamicMethod(com.google.protobuf.GeneratedMessageLite$MethodToInvoke)
(agent) [
33h1vvf01vb
] Called com.google.protobuf.UnknownFieldSetLite.makeImmutable()
(agent) [e48kca70yae] Called com.google.protobuf.GeneratedMessageLite.isInitialized()
(agent) [e48kca70yae] Called com.google.protobuf.GeneratedMessageLite.dynamicMethod(com.google.protobuf.GeneratedMessageLite$MethodToInvoke, java.lang.
Object
)
(agent) [
4fnnhkno676
] Called io.grpc.protobuf.lite.ProtoLiteUtils$MessageMarshaller.stream(java.lang.
Object
)
(agent) [
4fnnhkno676
] Called io.grpc.protobuf.lite.ProtoLiteUtils$MessageMarshaller.stream(com.google.protobuf.MessageLite)
(agent) [t74uyknf3ri] Called io.grpc.protobuf.lite.ProtoInputStream.available()
(agent) [
4gz3lfvhznc
] Called com.google.protobuf.CodedOutputStream.computeStringSize(
int
, java.lang.String)
(agent) [
4gz3lfvhznc
] Called com.google.protobuf.CodedOutputStream.computeTagSize(
int
)
(agent) [
75uwxvix9zw
] 【【【Called com.google.protobuf.WireFormat.makeTag(
int
,
int
)】】】
(agent) [
4gz3lfvhznc
] Called com.google.protobuf.CodedOutputStream.computeUInt32SizeNoTag(
int
)
(agent) [
4gz3lfvhznc
] Called com.google.protobuf.CodedOutputStream.computeStringSizeNoTag(java.lang.String)
(agent) [
78m3ko66u48
] Called com.google.protobuf.Utf8.encodedLength(java.lang.CharSequence)
(agent) [
4gz3lfvhznc
] Called com.google.protobuf.CodedOutputStream.computeLengthDelimitedFieldSize(
int
)
(agent) [
4gz3lfvhznc
] Called com.google.protobuf.CodedOutputStream.computeUInt32SizeNoTag(
int
)
(agent) [t74uyknf3ri] Called io.grpc.protobuf.lite.ProtoInputStream.drainTo(java.io.OutputStream)
(agent) [pi8dc23shb] 【【【Called com.google.protobuf.AbstractMessageLite.writeTo(java.io.OutputStream)】】】
(agent) [
4gz3lfvhznc
] Called com.google.protobuf.CodedOutputStream.computePreferredBufferSize(
int
)
(agent) [
4gz3lfvhznc
] Called com.google.protobuf.CodedOutputStream.newInstance(java.io.OutputStream,
int
)
(agent) [
2ira22725rq
] Called com.google.protobuf.CodedOutputStream$OutputStreamEncoder.writeString(
int
, java.lang.String)
(agent) [
2ira22725rq
] Called com.google.protobuf.CodedOutputStream$OutputStreamEncoder.writeTag(
int
,
int
)
(agent) [
75uwxvix9zw
] 【【【Called com.google.protobuf.WireFormat.makeTag(
int
,
int
)】】】
(agent) [
2ira22725rq
] Called com.google.protobuf.CodedOutputStream$OutputStreamEncoder.writeUInt32NoTag(
int
)
(agent) [
2ira22725rq
] Called com.google.protobuf.CodedOutputStream$OutputStreamEncoder.flushIfNotAvailable(
int
)
(agent) [
032rofd4w0eb
] Called com.google.protobuf.CodedOutputStream$AbstractBufferedEncoder.bufferUInt32NoTag(
int
)
(agent) [
4gz3lfvhznc
] Called com.google.protobuf.CodedOutputStream.access$
100
()
(agent) [
2ira22725rq
] Called com.google.protobuf.CodedOutputStream$OutputStreamEncoder.writeStringNoTag(java.lang.String)
(agent) [
4gz3lfvhznc
] Called com.google.protobuf.CodedOutputStream.computeUInt32SizeNoTag(
int
)
(agent) [
78m3ko66u48
] 【【【Called com.google.protobuf.Utf8.encode(java.lang.CharSequence, [B,
int
,
int
)】】】
(agent) [yozcy0715w] Called com.google.protobuf.Utf8$SafeProcessor.encodeUtf8(java.lang.CharSequence, [B,
int
,
int
)
(agent) [
2ira22725rq
] Called com.google.protobuf.CodedOutputStream$OutputStreamEncoder.writeUInt32NoTag(
int
)
(agent) [
2ira22725rq
] Called com.google.protobuf.CodedOutputStream$OutputStreamEncoder.flushIfNotAvailable(
int
)
(agent) [
032rofd4w0eb
] Called com.google.protobuf.CodedOutputStream$AbstractBufferedEncoder.bufferUInt32NoTag(
int
)
(agent) [
4gz3lfvhznc
] Called com.google.protobuf.CodedOutputStream.access$
100
()
(agent) [
2ira22725rq
] Called com.google.protobuf.CodedOutputStream$OutputStreamEncoder.writeLazy([B,
int
,
int
)
(agent) [
2ira22725rq
] 【【【Called com.google.protobuf.CodedOutputStream$OutputStreamEncoder.write([B,
int
,
int
)】】】
(agent) [
2ira22725rq
] Called com.google.protobuf.CodedOutputStream$OutputStreamEncoder.flush()
(agent) [
2ira22725rq
] Called com.google.protobuf.CodedOutputStream$OutputStreamEncoder.doFlush()
(agent) [
4fnnhkno676
] Called io.grpc.protobuf.lite.ProtoLiteUtils$MessageMarshaller.parse(java.io.InputStream)
(agent) [
4fnnhkno676
] Called io.grpc.protobuf.lite.ProtoLiteUtils$MessageMarshaller.parse(java.io.InputStream)
(agent) [
34xbsz3uxgl
] Called com.google.protobuf.CodedInputStream.newInstance([B,
int
,
int
)
(agent) [
34xbsz3uxgl
] Called com.google.protobuf.CodedInputStream.newInstance([B,
int
,
int
, boolean)
(agent) [
34xbsz3uxgl
] Called com.google.protobuf.CodedInputStream.pushLimit(
int
)
(agent) [
34xbsz3uxgl
] Called com.google.protobuf.CodedInputStream.recomputeBufferSizeAfterLimit()
(agent) [
34xbsz3uxgl
] Called com.google.protobuf.CodedInputStream.setSizeLimit(
int
)
(agent) [
4fnnhkno676
] Called io.grpc.protobuf.lite.ProtoLiteUtils$MessageMarshaller.parseFrom(com.google.protobuf.CodedInputStream)
(agent) [
6thpuwhq0js
] Called com.google.protobuf.AbstractParser.parseFrom(com.google.protobuf.CodedInputStream, com.google.protobuf.ExtensionRegistryLite)
(agent) [
6thpuwhq0js
] Called com.google.protobuf.AbstractParser.parseFrom(com.google.protobuf.CodedInputStream, com.google.protobuf.ExtensionRegistryLite)
(agent) [b7ksjxdkr9] Called com.google.protobuf.GeneratedMessageLite$DefaultInstanceBasedParser.parsePartialFrom(com.google.protobuf.CodedInputStream, com.google.protobuf.ExtensionRegistryLite)
(agent) [b7ksjxdkr9] Called com.google.protobuf.GeneratedMessageLite$DefaultInstanceBasedParser.parsePartialFrom(com.google.protobuf.CodedInputStream, com.google.protobuf.ExtensionRegistryLite)
(agent) [e48kca70yae] Called com.google.protobuf.GeneratedMessageLite.parsePartialFrom(com.google.protobuf.GeneratedMessageLite, com.google.protobuf.CodedInputStream, com.google.protobuf.ExtensionRegistryLite)
(agent) [e48kca70yae] Called com.google.protobuf.GeneratedMessageLite.dynamicMethod(com.google.protobuf.GeneratedMessageLite$MethodToInvoke)
(agent) [
33h1vvf01vb
] Called com.google.protobuf.UnknownFieldSetLite.getDefaultInstance()
(agent) [
34xbsz3uxgl
] Called com.google.protobuf.CodedInputStream.readTag()
(agent) [
34xbsz3uxgl
] Called com.google.protobuf.CodedInputStream.isAtEnd()
(agent) [
34xbsz3uxgl
] Called com.google.protobuf.CodedInputStream.readRawVarint32()
(agent) [
75uwxvix9zw
] Called com.google.protobuf.WireFormat.getTagFieldNumber(
int
)
(agent) [
34xbsz3uxgl
] Called com.google.protobuf.CodedInputStream.readStringRequireUtf8()
(agent) [
34xbsz3uxgl
] Called com.google.protobuf.CodedInputStream.readRawVarint32()
(agent) [
78m3ko66u48
] Called com.google.protobuf.Utf8.isValidUtf8([B,
int
,
int
)
(agent) [sa0emcwxaha] Called com.google.protobuf.Utf8$Processor.isValidUtf8([B,
int
,
int
)
(agent) [yozcy0715w] Called com.google.protobuf.Utf8$SafeProcessor.partialIsValidUtf8(
int
, [B,
int
,
int
)
(agent) [yozcy0715w] Called com.google.protobuf.Utf8$SafeProcessor.partialIsValidUtf8([B,
int
,
int
)
(agent) [
34xbsz3uxgl
] Called com.google.protobuf.CodedInputStream.readTag()
(agent) [
34xbsz3uxgl
] Called com.google.protobuf.CodedInputStream.isAtEnd()
(agent) [
34xbsz3uxgl
] Called com.google.protobuf.CodedInputStream.tryRefillBuffer(
int
)
(agent) [e48kca70yae] Called com.google.protobuf.GeneratedMessageLite.makeImmutable()
(agent) [e48kca70yae] Called com.google.protobuf.GeneratedMessageLite.dynamicMethod(com.google.protobuf.GeneratedMessageLite$MethodToInvoke)
(agent) [
33h1vvf01vb
] Called com.google.protobuf.UnknownFieldSetLite.makeImmutable()
(agent) [
6thpuwhq0js
] Called com.google.protobuf.AbstractParser.checkMessageInitialized(com.google.protobuf.MessageLite)
(agent) [e48kca70yae] Called com.google.protobuf.GeneratedMessageLite.isInitialized()
(agent) [e48kca70yae] Called com.google.protobuf.GeneratedMessageLite.dynamicMethod(com.google.protobuf.GeneratedMessageLite$MethodToInvoke, java.lang.
Object
)
(agent) [
34xbsz3uxgl
] Called com.google.protobuf.CodedInputStream.checkLastTagWas(
int
)
|
hook com.google.protobuf.Utf8.encode(java.lang.CharSequence, [B, int, int)
至此全部完结~
以上就是最近几天学习内容,接下来研究研究Java具体如何实现的,争取学会还原tag来实现无proto文件反解析出数据.
更多【 浅浅记录下学习Protubuf历程,最终实现App与本地Python服务器交互】相关视频教程:www.yxfzedu.com