forked from JAL9302/mitmdump_decoder
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdecode.py
More file actions
160 lines (132 loc) · 4.86 KB
/
decode.py
File metadata and controls
160 lines (132 loc) · 4.86 KB
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#!/usr/bin/env python
import time
import sys
import os
from collections import deque
from mitmproxy.script import concurrent
from mitmproxy.models import decoded
import site
site.addsitedir("/usr/local/Cellar/protobuf/3.0.0-beta-3/libexec/lib/python2.7/site-packages")
sys.path.append("/usr/local/lib/python2.7/site-packages")
sys.path.append("/usr/local/Cellar/protobuf/3.0.0-beta-3/libexec/lib/python2.7/site-packages")
from protocol.bridge_pb2 import *
from protocol.clientrpc_pb2 import *
from protocol.gymbattlev2_pb2 import *
from protocol.holoholo_shared_pb2 import *
from protocol.platform_actions_pb2 import *
from protocol.remaining_pb2 import *
from protocol.rpc_pb2 import *
from protocol.settings_pb2 import *
from protocol.sfida_pb2 import *
from protocol.signals_pb2 import *
from get_map_objects_handler import GetMapObjectsHandler
import flask
from flask import Flask, request
#We can often look up the right deserialization structure based on the method, but there are some deviations
mismatched_apis = {
'RECYCLE_INVENTORY_ITEM': 'RECYCLE_ITEM',
'USE_INCENSE': 'USE_INCENSE_ACTION',
'GET_PLAYER_PROFILE': 'PLAYER_PROFILE',
#'SFIDA_ACTION_LOG': This one is mismatches, but so bad that it had to be fixed in the protobuf
'GET_ASSET_DIGEST': 'ASSET_DIGEST_REQUEST',
'DOWNLOAD_REMOTE_CONFIG_VERSION': 'GET_REMOTE_CONFIG_VERSIONS',
}
#http://stackoverflow.com/questions/28867596/deserialize-protobuf-in-python-from-class-name
def deserialize(message, typ):
import importlib
module_name, class_name = typ.rsplit(".", 1)
#module = importlib.import_module(module_name)
MyClass = globals()[class_name]
instance = MyClass()
instance.ParseFromString(message)
return instance
def underscore_to_camelcase(value):
def camelcase():
while True:
yield str.capitalize
c = camelcase()
return "".join(c.next()(x) if x else '_' for x in value.split("_"))
app = Flask("events", static_folder='ui')
app.config['SECRET_KEY'] = 'amanaplanacanalplama'
app.debug = True
@app.route('/')
def index():
return app.send_static_file('index.html')
@app.route('/pgo.pac')
def pac():
return app.send_static_file('pgo.pac')
#Its possible I didn't need to make these explicit, but its late and I'm tired
@app.route('/css/<path:filename>')
def css(filename):
return flask.send_from_directory(os.path.join('ui', 'css'), filename)
@app.route('/js/<path:filename>')
def js(filename):
return flask.send_from_directory(os.path.join('ui', 'js'), filename)
@app.route('/player.json')
def player():
return getMapObjects.player()
@app.route('/get_map_objects.json')
def get_map_objects():
return getMapObjects.get_map_objects()
def start(context, argv):
context.app_registry.add(app, "events", 80)
context.methods_for_request = {}
context.filter_methods = argv[1:]
print("Filter methods: %s; Empty is no filtering" % context.filter_methods)
getMapObjects = GetMapObjectsHandler()
def request(context, flow):
if not flow.match("~u plfe"):
return
try:
env = RpcRequestEnvelopeProto()
env.ParseFromString(flow.request.content)
except Exception, e:
print("Deserializating Envelop exception: %s" % e)
return
context.methods_for_request[env.request_id] = deque([])
for parameter in env.parameter:
key = parameter.key
value = parameter.value
context.methods_for_request[env.request_id].append(key)
name = Method.Name(key)
if (len(context.filter_methods) > 0 and name not in context.filter_methods):
continue
name = mismatched_apis.get(name, name) #return class name when not the same as method
klass = underscore_to_camelcase(name) + "Proto"
try:
mor = deserialize(value, "." + klass)
print("Deserialized Request %i: %s" % (env.request_id, name))
except:
print("Missing Request API: %s" % name)
continue
print(mor)
if (key == GET_MAP_OBJECTS):
getMapObjects.request(mor, env)
def response(context, flow):
if not flow.match("~u plfe"):
return
with decoded(flow.response):
try:
env = RpcResponseEnvelopeProto()
env.ParseFromString(flow.response.content)
except Exception, e:
print("Deserializating Envelop exception: %s" % e)
return
keys = context.methods_for_request.pop(env.response_id)
for value in env.returns:
key = keys.popleft()
name = Method.Name(key)
if (len(context.filter_methods) > 0 and name not in context.filter_methods):
continue
name = mismatched_apis.get(name, name) #return class name when not the same as method
klass = underscore_to_camelcase(name) + "OutProto"
try:
mor = deserialize(value, "." + klass)
print("Deserialized Response %i: %s" % (env.response_id, name))
except:
print("Missing Response API: %s" % name)
continue
print(mor)
if (key == GET_MAP_OBJECTS):
getMapObjects.response(mor, env)
# vim: set tabstop=2 shiftwidth=2 expandtab : #