コード例 #1
0
        private async Task OnRequest(object sender, SessionEventArgs e)
        {
            if (e.WebSession.Request.RequestUri.Host != "pgorelease.nianticlabs.com")
            {
                return;
            }

            // Get session data
            var callTime = DateTime.Now;

            byte[] bodyBytes = await e.GetRequestBody();

            var codedInputStream = new CodedInputStream(bodyBytes);
            var requestEnvelope  = RequestEnvelope.Parser.ParseFrom(codedInputStream);

            // Initialize the request block
            var requestBlock = new MessageBlock
            {
                MessageInitialized = callTime,
                ParsedMessages     = new Dictionary <RequestType, IMessage>()
            };

            // Parse all the requests
            foreach (Request request in requestEnvelope.Requests)
            {
                // Had to add assembly name to end of typeName string since protocs cs files are in a different assembly
                var type = Type.GetType("POGOProtos.Networking.Requests.Messages." + request.RequestType + "Message,PoGo Proxy.Protocs");

                if (type == null)
                {
                    if (Out != StreamWriter.Null)
                    {
                        Out.WriteLine("[*] GetType returns null for requestType: " + request.RequestType);
                    }
                    if (Out != StreamWriter.Null)
                    {
                        Out.WriteLine("[*] Check if POGOProtos.Networking.Requests.Messages." + request.RequestType + "Message exists.");
                    }
                    if (Out != StreamWriter.Null)
                    {
                        Out.WriteLine("[*]\n");
                    }

                    requestBlock.ParsedMessages.Add(request.RequestType, default(IMessage));
                }
                else
                {
                    var instance = (IMessage)Activator.CreateInstance(type);
                    instance.MergeFrom(request.RequestMessage);

                    requestBlock.ParsedMessages.Add(request.RequestType, instance);
                }
            }

            // TODO check if there is a double response or if a response already exists
            if (_apiBlocks.ContainsKey(requestEnvelope.RequestId))
            {
                if (Out != StreamWriter.Null)
                {
                    Out.WriteLine($"[*] Request Id({requestEnvelope.RequestId}) already exists.");
                    Out.WriteLine($"[*] Old request:\n{_apiBlocks[requestEnvelope.RequestId].RequestBlock}");
                    Out.WriteLine($"[*] New request:\n{requestBlock}");
                }

                if (_apiBlocks[requestEnvelope.RequestId].ResponseBlock == null)
                {
                    if (Out != StreamWriter.Null)
                    {
                        Out.WriteLine($"[*] Response for the old request doesn't - replacing old request");
                    }
                    _apiBlocks[requestEnvelope.RequestId].RequestBlock = requestBlock;
                }
                else
                {
                    if (Out != StreamWriter.Null)
                    {
                        Out.WriteLine($"[*] Response for the old request exists - do nothing");
                    }
                }
                Out.WriteLine("[*]\n");
                return;
            }

            // Initialize a new request/response paired block and track it to update response
            var args = new RequestHandledEventArgs
            {
                RequestId    = requestEnvelope.RequestId,
                RequestBlock = requestBlock
            };

            _apiBlocks.Add(args.RequestId, args);
        }
コード例 #2
0
        private async Task OnResponse(object sender, SessionEventArgs e)
        {
            if (e.WebSession.Request.RequestUri.Host != "pgorelease.nianticlabs.com")
            {
                return;
            }

            if (e.WebSession.Response.ResponseStatusCode == "200")
            {
                // Get session data
                var    callTime  = DateTime.Now;
                byte[] bodyBytes = await e.GetResponseBody();

                var codedInputStream = new CodedInputStream(bodyBytes);
                var responseEnvelope = ResponseEnvelope.Parser.ParseFrom(codedInputStream);

                // Initialize the response block
                var responseBlock = new MessageBlock
                {
                    MessageInitialized = callTime,
                    ParsedMessages     = new Dictionary <RequestType, IMessage>()
                };

                // Grab the paired request
                var args = _apiBlocks[responseEnvelope.RequestId];

                // Grab request types
                var requestTypes = args.RequestBlock.ParsedMessages.Keys.ToList();

                // The case of missmatched requests and responses seems to be a handshake. The inital request sends 5 messages and gets back 2 that are empty bytestrings
                if (args.RequestBlock.ParsedMessages.Count != responseEnvelope.Returns.Count)
                {
                    if ((args.RequestBlock.ParsedMessages.Count == 5 && responseEnvelope.Returns.Count == 2) &&
                        (responseEnvelope.Returns[0].IsEmpty && responseEnvelope.Returns[1].IsEmpty))
                    {
                        if (Out != StreamWriter.Null)
                        {
                            Out.WriteLine($"[*] Handshake complete\n");
                        }
                        _apiBlocks.Remove(args.RequestId);
                        return;
                    }

                    // If there is a case of missmatched requests and responses, and it doesn't look like a handshake, log it
                    if (Out != StreamWriter.Null)
                    {
                        Out.WriteLine($"[*] Request messages count ({args.RequestBlock.ParsedMessages.Count}) is different than the response messages count ({responseEnvelope.Returns.Count}).");

                        Out.WriteLine("Request:");
                        Out.WriteLine(args.RequestBlock);

                        Out.WriteLine("Response:");
                        Out.WriteLine("Not sure yet how to read this without knowing what it is.");

                        Out.WriteLine($"[*]\n");
                    }

                    // This section converts all of the responses into all of the request types that exist to see which one fits
                    int responseIndex = 0;

                    foreach (var responseBytes in responseEnvelope.Returns)
                    {
                        int start = responseIndex;
                        int end   = responseIndex + requestTypes.Count - responseEnvelope.Returns.Count;

                        // Parse the responses
                        for (int i = start; i < end; i++)
                        {
                            var type = Type.GetType("POGOProtos.Networking.Responses." + requestTypes[i] + "Response,PoGo Proxy.Protocs");

                            var instance = (IMessage)Activator.CreateInstance(type);
                            instance.MergeFrom(responseBytes);

                            Out.WriteLine($"[*] Parsing as response {responseIndex} as {requestTypes[i]}");
                            Out.WriteLine(JsonConvert.SerializeObject(instance));
                        }

                        responseIndex++;
                        Out.WriteLine();
                    }
                    Out.WriteLine($"[*]\n");
                }

                // Parse the responses
                for (int i = 0; i < responseEnvelope.Returns.Count; i++)
                {
                    // Had to add assembly name to end of typeName string since protocs.cs files are in a different assembly
                    var type = Type.GetType("POGOProtos.Networking.Responses." + requestTypes[i] + "Response,PoGo Proxy.Protocs");

                    if (type == null)
                    {
                        if (Out != StreamWriter.Null)
                        {
                            Out.WriteLine("[***] GetType returns null for requestType: " + requestTypes[i]);
                        }
                        if (Out != StreamWriter.Null)
                        {
                            Out.WriteLine("[***] Check if POGOProtos.Networking.Requests.Messages." + requestTypes[i] + "Message exists.");
                        }
                        if (Out != StreamWriter.Null)
                        {
                            Out.WriteLine("[*]\n");
                        }

                        responseBlock.ParsedMessages.Add(requestTypes[i], default(IMessage));
                    }
                    else
                    {
                        var instance = (IMessage)Activator.CreateInstance(type);
                        instance.MergeFrom(responseEnvelope.Returns[i]);

                        responseBlock.ParsedMessages.Add(requestTypes[i], instance);
                    }
                }

                // Have not seen this issue yet - here just in case
                if (!_apiBlocks.ContainsKey(responseEnvelope.RequestId))
                {
                    if (Out != StreamWriter.Null)
                    {
                        Out.WriteLine($"[*] Request doesn't exist with specified RequestId ({responseEnvelope.RequestId}).");
                        Out.WriteLine($"Response:\n{responseBlock}");
                        Out.WriteLine("[*]\n");
                    }
                }

                // Remove block from dictionary and invoke event handler
                args.ResponseBlock = responseBlock;
                _apiBlocks.Remove(args.RequestId);

                RequestHandled?.Invoke(this, args);
            }
        }