Exemplo n.º 1
0
        public async Task <R> Send <P, R>(HttpMethod method, string url, P obj, Func <HttpWebResponse, Task <R> > responseParser)
        {
            R result = default(R);
            await Retry.Do(retryTimes, retryDelay, async() =>
            {
                var client    = await GetHttpClient(url).ConfigureAwait(false);
                client.Method = method.ToString();
                var data      = JsonConvert.SerializeObject(obj);
                using (var content = new StringContent(data))
                {
                    client.ContentType = content.Headers.ContentType.ToString();

                    using (var output = await client.GetRequestStreamAsync().ConfigureAwait(false))
                    {
                        await content.CopyToAsync(output).ConfigureAwait(false);
                    }
                }

                using (var response = (HttpWebResponse)await client.GetResponseAsync().ConfigureAwait(false))
                {
                    if (!response.IsSuccessStatusCode())
                    {
                        return(await LogBadResponse(response).ConfigureAwait(false));
                    }

                    result = await responseParser(response).ConfigureAwait(false);
                }
                return(true);
            }, GeneralExceptionProcessor).ConfigureAwait(false);

            return(result);
        }
 public async Task Invoke(HttpContext context)
 {
     if (context == null)
     {
         throw new ArgumentNullException(nameof(context));
     }
     if (!verifySuccess || (verifySuccess && (DateTime.Now - preverifyTime).TotalMinutes > 10))
     {
         string msg = LicenseHelper.Verify();
         if (!string.IsNullOrEmpty(msg))
         {
             verifySuccess = false;
             context.Response.ContentType = "application/json";
             context.Response.StatusCode  = (int)HttpStatusCode.OK;
             var result = new ApiResult <string>
             {
                 Code = ResultCode.License_Error,
                 Msg  = msg
             };
             var sc = new StringContent(serializer.Serialize(result));
             await sc.CopyToAsync(context.Response.Body);
         }
         else
         {
             verifySuccess = true;
             preverifyTime = DateTime.Now;
             await _next.Invoke(context);
         }
     }
     else
     {
         await _next.Invoke(context);
     }
 }
        public Task ExecuteResultAsync(ActionContext context)
        {
            var stringContent = new StringContent(statement.ToJson(format), Encoding.UTF8, MediaTypes.Application.Json);

            if (statement.Attachments.Any(x => x.Payload != null))
            {
                var multipart = new MultipartContent("mixed")
                {
                    stringContent
                };
                foreach (var attachment in statement.Attachments)
                {
                    if (attachment.Payload != null)
                    {
                        var byteArrayContent = new ByteArrayContent(attachment.Payload);
                        byteArrayContent.Headers.ContentType = new MediaTypeHeaderValue(attachment.ContentType);
                        byteArrayContent.Headers.Add(ApiHeaders.ContentTransferEncoding, "binary");
                        byteArrayContent.Headers.Add(ApiHeaders.XExperienceApiHash, attachment.SHA2);
                        multipart.Add(byteArrayContent);
                    }
                }

                return(multipart.CopyToAsync(context.HttpContext.Response.Body));
            }

            return(stringContent.CopyToAsync(context.HttpContext.Response.Body));
        }
Exemplo n.º 4
0
        public Task ExecuteResultAsync(ActionContext context)
        {
            var stringContent = new StringContent(result.ToJson(format), Encoding.UTF8, MediaTypes.Application.Json);

            var attachmentsWithPayload = result.Statements.SelectMany(x => x.Attachments.Where(a => a.Payload != null));

            if (attachmentsWithPayload.Count() > 0)
            {
                string boundary = Guid.NewGuid().ToString();
                using var multipart = new MultipartContent("mixed", boundary)
                      {
                          stringContent
                      };

                foreach (var attachment in attachmentsWithPayload)
                {
                    var byteArrayContent    = new ByteArrayContent(attachment.Payload);
                    var attachmentMediaType = MediaTypeHeaderValue.Parse(attachment.ContentType);

                    byteArrayContent.Headers.ContentType = attachmentMediaType;
                    byteArrayContent.Headers.Add(ApiHeaders.ContentTransferEncoding, "binary");
                    byteArrayContent.Headers.Add(ApiHeaders.XExperienceApiHash, attachment.SHA2);
                    multipart.Add(byteArrayContent);
                }

                // Write Content-Type header with Boundary parameter
                var mediaType = MediaTypeHeaderValue.Parse(MediaTypes.Multipart.Mixed);
                mediaType.Parameters.Add(new NameValueHeaderValue("boundary", boundary));
                context.HttpContext.Response.ContentType = mediaType.ToString();

                return(multipart.CopyToAsync(context.HttpContext.Response.Body));
            }

            return(stringContent.CopyToAsync(context.HttpContext.Response.Body));
        }
Exemplo n.º 5
0
        public async Task ExecuteResultAsync(ActionContext context)
        {
            StringContent content = new StringContent(JsonConvert.SerializeObject(this));

            context.HttpContext.Response.Headers.Add("content-type", "application/json");
            context.HttpContext.Response.StatusCode = (int)this.StatusCode;
            await content.CopyToAsync(context.HttpContext.Response.Body);
        }
Exemplo n.º 6
0
        public void CopyToAsync()
        {
            var sc = new StringContent("gt");

            var dest = new MemoryStream();
            var task = sc.CopyToAsync(dest);

            task.Wait();
            Assert.AreEqual(2, dest.Length, "#1");
        }
Exemplo n.º 7
0
        public void CopyToAsync_Invalid()
        {
            var sc = new StringContent("");

            try {
                sc.CopyToAsync(null);
                Assert.Fail("#1");
            } catch (ArgumentNullException) {
            }
        }
Exemplo n.º 8
0
        public async Task Ctor_UseCustomEncodingAndMediaType_EncodingUsedAndContentTypeHeaderUpdated()
        {
            // Use UTF-8 encoding to serialize a chinese string.
            string sourceString = "\u4f1a\u5458\u670d\u52a1";

            var content = new StringContent(sourceString, Encoding.UTF8, "application/custom");

            Assert.Equal("application/custom", content.Headers.ContentType.MediaType);
            Assert.Equal("utf-8", content.Headers.ContentType.CharSet);

            var destination = new MemoryStream(12);
            await content.CopyToAsync(destination);

            string destinationString = Encoding.UTF8.GetString(destination.ToArray(), 0, (int)destination.Length);

            Assert.Equal(sourceString, destinationString);
        }
Exemplo n.º 9
0
        public async Task Ctor_UseCustomEncodingAndMediaType_EncodingUsedAndContentTypeHeaderUpdated()
        {
            // Use UTF-8 encoding to serialize a chinese string.
            string sourceString = "\u4f1a\u5458\u670d\u52a1";

            var content = new StringContent(sourceString, Encoding.UTF8, "application/custom");

            Assert.Equal("application/custom", content.Headers.ContentType.MediaType);
            Assert.Equal("utf-8", content.Headers.ContentType.CharSet);

            var destination = new MemoryStream(12);
            await content.CopyToAsync(destination);

            string destinationString = Encoding.UTF8.GetString(destination.ToArray(), 0, (int)destination.Length);

            Assert.Equal(sourceString, destinationString);
        }
        public async Task ExecuteResultAsync(ActionContext context)
        {
            StringContent content = new StringContent(JsonConvert.SerializeObject(this));

            context.HttpContext.Response.Headers.Add("content-type", "application/json");

            if (this.AutoAssignHttpStatusCode && this.Validations?.Count > 0)
            {
                this.SetToUnprocessableEntity("Unprocessable entity");
                context.HttpContext.Response.StatusCode = (int)this.HttpStatusCode;
            }
            else
            {
                context.HttpContext.Response.StatusCode = (int)this.HttpStatusCode;
            }

            await content.CopyToAsync(context.HttpContext.Response.Body);
        }
Exemplo n.º 11
0
        private async Task <StreamContent> CompressAsync(StringContent content)
        {
            var ms = new MemoryStream();

            using (var gzipStream = new GZipStream(ms, CompressionMode.Compress, true))
            {
                await content.CopyToAsync(gzipStream);

                await gzipStream.FlushAsync();
            }

            ms.Position = 0;
            var compressedStreamContent = new StreamContent(ms);

            compressedStreamContent.Headers.ContentType = new MediaTypeHeaderValue(_contentType.MimeType());
            compressedStreamContent.Headers.Add("Content-Encoding", "gzip");

            return(compressedStreamContent);
        }
Exemplo n.º 12
0
        public async Task Ctor_DefineNoEncoding_DefaultEncodingUsed()
        {
            string sourceString = "\u00C4\u00E4\u00FC\u00DC";
            var content = new StringContent(sourceString);
            Encoding defaultStringEncoding = Encoding.GetEncoding("utf-8");

            // If no encoding is defined, the default encoding is used: utf-8
            Assert.Equal("text/plain", content.Headers.ContentType.MediaType);
            Assert.Equal(defaultStringEncoding.WebName, content.Headers.ContentType.CharSet);

            // Make sure the default encoding is also used when serializing the content.
            var destination = new MemoryStream();
            await content.CopyToAsync(destination);

            Assert.Equal(8, destination.Length);

            destination.Seek(0, SeekOrigin.Begin);
            string roundTrip = new StreamReader(destination, defaultStringEncoding).ReadToEnd();
            Assert.Equal(sourceString, roundTrip);
        }
Exemplo n.º 13
0
        public async Task Ctor_DefineNoEncoding_DefaultEncodingUsed()
        {
            string   sourceString          = "\u00C4\u00E4\u00FC\u00DC";
            var      content               = new StringContent(sourceString);
            Encoding defaultStringEncoding = Encoding.GetEncoding("utf-8");

            // If no encoding is defined, the default encoding is used: utf-8
            Assert.Equal("text/plain", content.Headers.ContentType.MediaType);
            Assert.Equal(defaultStringEncoding.WebName, content.Headers.ContentType.CharSet);

            // Make sure the default encoding is also used when serializing the content.
            var destination = new MemoryStream();
            await content.CopyToAsync(destination);

            Assert.Equal(8, destination.Length);

            destination.Seek(0, SeekOrigin.Begin);
            string roundTrip = new StreamReader(destination, defaultStringEncoding).ReadToEnd();

            Assert.Equal(sourceString, roundTrip);
        }
Exemplo n.º 14
0
        public async Task InvokeAsync(HttpContext context, IWebHostEnvironment webHostEnvironment)
        {
            var cancellationToken = context.RequestAborted;
            var requestEncoding   = _options.RequestEncoding ?? Encoding.UTF8;
            var excludeUrls       = _options.ExcludeUrls;
            var modifyResponse    = excludeUrls == null || !excludeUrls.Any(bl => context.Request.Path.Value != null &&
                                                                            context.Request.Path.Value.ToLowerInvariant().Contains(bl));

            if (!modifyResponse)
            {
                await _next(context);

                return;
            }

            var responseBodyPooledStream = new DisposablePooledStream(_pooledStreamManager, nameof(I18NMiddleware));

            context.Response.RegisterForDisposeAsync(responseBodyPooledStream);

            var httpResponseBodyFeature = context.Features.Get <IHttpResponseBodyFeature>();
            var httpResponseFeature     = context.Features.Get <IHttpResponseFeature>();

            var streamResponseBodyFeature = new StreamResponseBodyFeature(responseBodyPooledStream);

            context.Features.Set <IHttpResponseBodyFeature>(streamResponseBodyFeature);

            await _next(context).ConfigureAwait(false);

            // Force dynamic content type in order reset Content-Length header.
            httpResponseFeature.Headers.ContentLength = null;

            var httpResponseBodyStream = (Stream)responseBodyPooledStream;

            httpResponseBodyStream.Seek(0, SeekOrigin.Begin);

            var contentType       = GetRequestContentType(context);
            var validContentTypes = _options.ValidContentTypes;
            var replaceNuggets    = validContentTypes != null && validContentTypes.Contains(contentType);

            if (replaceNuggets)
            {
                var requestCultureInfo = GetRequestCultureInfo(context);
                var cultureDictionary  = _localizationManager.GetDictionary(requestCultureInfo, !_options.CacheEnabled);

                _logger?.LogDebug(
                    $"Request path: {context.Request.Path}. Culture name: {cultureDictionary.CultureName}. Translations: {cultureDictionary.Translations.Count}.");

                var responseBody = await ReadResponseBodyAsStringAsync(httpResponseBodyStream, requestEncoding);

                string responseBodyTranslated;
                if (webHostEnvironment.IsDevelopment())
                {
                    var sw = new Stopwatch();
                    sw.Restart();
                    responseBodyTranslated = _nuggetReplacer.Replace(cultureDictionary, responseBody);
                    sw.Stop();

                    _logger?.LogDebug($"Replaced body in {sw.ElapsedMilliseconds} ms.");
                    const string i18NMiddlewareName = "X-" + nameof(I18NMiddleware) + "-Ms";
                    httpResponseFeature.Headers[i18NMiddlewareName] = sw.ElapsedMilliseconds.ToString();
                }
                else
                {
                    responseBodyTranslated = _nuggetReplacer.Replace(cultureDictionary, responseBody);
                }

                var stringContent = new StringContent(responseBodyTranslated, requestEncoding, contentType);
#if NET50
                await stringContent.CopyToAsync(httpResponseBodyFeature.Stream, cancellationToke);
#else
                await stringContent.CopyToAsync(httpResponseBodyFeature.Stream);
#endif

                return;
            }

            await httpResponseBodyStream.CopyToAsync(httpResponseBodyFeature.Stream, cancellationToken).ConfigureAwait(false);
        }
Exemplo n.º 15
0
        /// <summary>
        /// There are 2 paths through Run()
        ///
        /// The primary route is the PageHash JSON protocol that validates hash entries sent by the client
        /// performs relocations and soforth.
        ///
        /// The other sequence is to return a given file that the client wants to manually inspect.
        ///
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="name"></param>
        /// <param name="log"></param>
        /// <returns></returns>
        public async static Task Run(HttpContext ctx, string name, ILogger log)
        {
            Dictionary <string, string> entries = null;
            DeLocate      rere = null;
            MemPageHash   mph = null;
            StringContent failure = null;
            ulong         BaseAddress = 0;
            long          content_Len = 0L, RVA = 0L, SecOffset = 0L;
            var           block = new Byte[0x1000];
            MiniSection   ms = MiniSection.Empty;
            string        modName = string.Empty, targetName = string.Empty, hash = string.Empty;
            var           req  = ctx.Request;
            var           resp = ctx.Response;

            resp.StatusCode = (int)HttpStatusCode.NoContent;

            try {
                content_Len = req.ContentLength ?? 0;
                entries     = req.Query.ToDictionary(q => q.Key, q => (string)q.Value);

                // attempt to just dump back the binary we would of hashed
                if (req.Method == "GET")
                {
                    if (!entries.ContainsKey("file") || string.IsNullOrWhiteSpace(entries["file"]))
                    {
                        log.LogWarning($"Get requests require a file parameter, none was sent.");
                        resp.StatusCode = (int)HttpStatusCode.NotFound;
                        return;
                    }
                    var return_file   = entries["file"].ToLower();
                    var ret_file_base = Path.GetFileName(return_file);
                    if (!GoldImages.DiskFiles.ContainsKey(ret_file_base))
                    {
                        log.LogInformation($"Unknown file requested from client [{ret_file_base}].");
                        return;
                    }

                    var file_set = GoldImages.DiskFiles[ret_file_base];
                    foreach (var x in file_set)
                    {
                        if (x.Item3.Substring(2).Equals(return_file.Substring(2), StringComparison.InvariantCultureIgnoreCase))
                        {
                            resp.StatusCode = (int)HttpStatusCode.OK;
                            targetName      = x.Item3;
                            using (var fout = File.Open(targetName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                            {
                                // return the file rerelocated
                                if (entries.ContainsKey("mapped"))
                                {
                                    fout.Read(block, 0, 0x1000);
                                    var e = Extract.IsBlockaPE(block);

                                    // PS sends this in base 10
                                    var parsed = ulong.TryParse(entries["mapped"], out BaseAddress);

                                    log.LogInformation($"Requested relocation address of returned image  [{BaseAddress:x}], performing relocations.");

                                    if (e.SizeOfHeaders < block.Length)
                                    {
                                        Buffer.BlockCopy(nullBuff, 0, block, (int)e.SizeOfHeaders, block.Length - (int)e.SizeOfHeaders);
                                    }
                                    if (e.ImageBase != BaseAddress)
                                    {
                                        var reRawData = Extract.ExtractRelocData(targetName);
                                        if (reRawData != null)
                                        {
                                            e.ReReState = rere = new DeLocate(e.ImageBase, reRawData);
                                            rere.RelocData.Processed      = DeLocate.ProcessRelocs(reRawData, null);
                                            rere.RelocData.ProcessedArray = rere.RelocData.Processed.ToArray();
                                        }
                                        AttemptDelocate(block, e, 0, 0, BaseAddress, rere);
                                    }
                                    // send header out
                                    await resp.Body.WriteAsync(block, 0, 0x1000).ConfigureAwait(false);

                                    // loop over the rest of the file
                                    RVA += 0x1000;
                                    do
                                    {
                                        for (int i = 0; i < e.NumberOfSections; i++)
                                        {
                                            if (RVA >= e.Sections[i].VirtualAddress && RVA < (e.Sections[i].VirtualAddress + e.Sections[i].VirtualSize))
                                            {
                                                ms = e.Sections[i];
                                                break;
                                            }
                                        }
                                        SecOffset     = (RVA - ms.VirtualAddress);
                                        fout.Position = ms.RawFilePointer + (RVA - ms.VirtualAddress);
                                        fout.Read(block, 0, 0x1000);
                                        if (rere != null && e.ImageBase != BaseAddress)
                                        {
                                            AttemptDelocate(block, e, e.ImageBase - BaseAddress, RVA, e.ImageBase, rere);
                                        }

                                        await resp.Body.WriteAsync(block, 0, 0x1000).ConfigureAwait(false);

                                        RVA += 0x1000;
                                    } while (RVA < e.SizeOfImage);
                                }
                                else
                                {
                                    await fout.CopyToAsync(resp.Body).ConfigureAwait(false);

                                    return;
                                }
                            }
                        }
                    }
                    log.LogTrace("Get request serviced.");
                    return;
                }
            } catch (Exception ex) { log.LogWarning($"Handling exception {ex}"); }

            if (req.Method != "POST")
            {
                log.LogWarning($"POST or GET allowed only, client sent {req.Method}");
                return;
            }

            var rv = new HashSet <PageHashBlockResult>();
            var cv = CODEVIEW_HEADER.Init(entries);

            try {
                var buffer    = new byte[content_Len];
                var bytesRead = 0;
                while (bytesRead < buffer.Length)
                {
                    var count = await req.Body.ReadAsync(buffer, bytesRead, buffer.Length - bytesRead);

                    bytesRead += count;
                }
                log.Log <string>(LogLevel.Trace, new EventId(2, "Read"), $"read post body {bytesRead}", null, (state, ex) => $"{state}");

                hash = Encoding.Default.GetString(buffer);
                // preconfigure return buffer so we will always return FALSE for failure
                mph = JsonConvert.DeserializeObject <MemPageHash>(hash);
                if (mph == null)
                {
                    log.LogWarning($"Client sent a serialized JSON POST content that were unable to handle Data:[{hash}], len:[{content_Len}]");
                    return;
                }

                rv.Add(new PageHashBlockResult()
                {
                    Address = mph.AllocationBase, HashCheckEquivalant = false
                });
                foreach (var ph in mph.HashSet)
                {
                    rv.Add(new PageHashBlockResult()
                    {
                        Address = ph.Address, HashCheckEquivalant = false
                    });
                }

                //configure failure case
                var rx = JsonConvert.SerializeObject(rv, Formatting.Indented);
                failure = new StringContent(rx, Encoding.Default, "application/json");
                // after here we can send 200 back but everything is a fail
                resp.StatusCode = (int)HttpStatusCode.OK;

                // sanitation & isolation of file name portion of input string (hopefully:)
                modName = mph.ModuleName.Split(Path.DirectorySeparatorChar).LastOrDefault();
                if (modName.Length <= 3 || modName.Contains(".."))
                {
                    await failure.CopyToAsync(resp.Body).ConfigureAwait(false);

                    log.LogWarning($"Client filename [{mph.ModuleName}] invalid or Likely dynamic code at address [{mph.BaseAddress}:x]");
                    return;
                }

                if (!string.IsNullOrWhiteSpace(modName) &&
                    modName.Any((x) => x ==
                                Path.AltDirectorySeparatorChar ||
                                InvalidFileNameChars.Contains(x) ||
                                char.IsSurrogate(x) ||
                                char.IsSymbol(x) ||
                                char.IsControl(x) ||
                                x == Path.VolumeSeparatorChar ||
                                x == Path.PathSeparator))
                {
                    await failure.CopyToAsync(resp.Body).ConfigureAwait(false);

                    log.LogWarning($"Client filename invalid or possibly evil [{mph.ModuleName}]");
                    return;
                }

                // should be redundant given were already at the last '\\'
                modName = Path.GetFileName(modName);
            }
            catch (Exception ex)
            {
                await failure.CopyToAsync(resp.Body).ConfigureAwait(false);

                log.LogWarning($"Failure, check exception {ex}");
                return;
            }

            cv.Name          = modName.ToLower();
            cv.TimeDateStamp = mph.TimeDateStamp;
            cv.VSize         = mph.ImageSize;

            log.LogTrace($"Performing lookup on client requested dtails [{mph.ModuleName}] [{cv.TimeDateStamp:x}] [{cv.VSize:x}]");

            if (cv.TimeDateStamp == 0 || cv.VSize == 0)
            {
                await failure.CopyToAsync(resp.Body).ConfigureAwait(false);

                log.LogWarning($"Client timestamp is out of range [{cv.TimeDateStamp:x}]");
                return;
            }
            // if we do not have this binary locally cached
            // attempt to retrieve it

            var localGoldBinaryFound = GoldImages.DiskFiles.ContainsKey(cv.Name);

            // update targetname if we can find it in the local ngen cache
            if (localGoldBinaryFound)
            {
                log.LogTrace("Found candidates for client integrity check.");

                localGoldBinaryFound = false;
                var goldEntries = GoldImages.DiskFiles[cv.Name];

                foreach (var ng in goldEntries.Where((x) => x.Item3.Substring(3).Equals(mph.ModuleName.Substring(3), StringComparison.InvariantCultureIgnoreCase)))
                {
                    if (ng.Item1 == cv.VSize && ng.Item2 == cv.TimeDateStamp)
                    {
                        targetName           = ng.Item3;
                        localGoldBinaryFound = true;
                        log.LogInformation($"Matched candiate for client [{targetName}]");
                        break;
                    }
                }
                if (!localGoldBinaryFound)
                {
                    foreach (var ng in goldEntries)
                    {
                        if (ng.Item1 == cv.VSize && ng.Item2 == cv.TimeDateStamp)
                        {
                            targetName           = ng.Item3;
                            localGoldBinaryFound = true;
                            log.LogInformation($"Matched candiate for client {targetName}");
                            break;
                        }
                    }
                }
            }

            if (!localGoldBinaryFound)
            {
                if (!Program.Settings.Host.ProxyToExternalgRoot)
                {
                    await failure.CopyToAsync(resp.Body).ConfigureAwait(false);

                    log.LogInformation($"Unable to locate a candiate that fits required criteria to requeted info, find original media for client requested file {modName} and store into golden image filesystem.7");
                    return;
                }
                else // proxy is enabled
                {
                    if (Program.Settings.External != null && !string.IsNullOrWhiteSpace(Program.Settings.External.gRoot))
                    {
                        log.LogInformation($"Remote service call started");
                        resp.StatusCode = (int)HttpStatusCode.OK;
                        try {
                            await WebAPI.ProxyObject(hash, resp.Body);
                        } catch (Exception ex)  {
                            log.LogWarning($"exceptoin in calling external gRoot server.  {ex}");
                            resp.StatusCode = (int)HttpStatusCode.NotFound;
                        }
                        log.LogInformation($"External server handled request.");
                        return;
                    }
                }
            }
            // setup connection to desired originating input so we can hash it and determine if
            // the caller is investigating the same binary
            using (var fr = new FileStream(targetName, FileMode.Open, FileAccess.Read))
            {
                fr.Read(block, 0, 0x1000);
                // parse the binary
                var e = Extract.IsBlockaPE(block);
                // fatal error
                if (e == null)
                {
                    await failure.CopyToAsync(resp.Body).ConfigureAwait(false);

                    log.LogWarning($"Corrupt image or some failure, unable to determine PE information for request {targetName}");
                    return;
                }

                if (e.SizeOfHeaders < block.Length)
                {
                    Buffer.BlockCopy(nullBuff, 0, block, (int)e.SizeOfHeaders, block.Length - (int)e.SizeOfHeaders);
                }

                var LocalHeaderHash = Convert.ToBase64String(hasher.ComputeHash(block));

                var  HdrMatch          = (mph.HdrHash == LocalHeaderHash);
                bool NeededHdrDelocate = false;

                if ((long)e.ImageBase != mph.AllocationBase && !HdrMatch)
                {
                    var reRawData = Extract.ExtractRelocData(targetName);
                    if (reRawData != null)
                    {
                        e.ReReState = rere = new DeLocate(e.ImageBase, reRawData);
                        rere.RelocData.Processed      = DeLocate.ProcessRelocs(reRawData, null);
                        rere.RelocData.ProcessedArray = rere.RelocData.Processed.ToArray();
                    }

                    AttemptDelocate(block, e, 0, 0, (ulong)mph.AllocationBase, rere);
                    LocalHeaderHash = Convert.ToBase64String(hasher.ComputeHash(block));
                    HdrMatch        = NeededHdrDelocate = (mph.HdrHash == LocalHeaderHash);
                }

                var rvenum = rv.GetEnumerator();
                // we injected one for the header so move to it here
                rvenum.MoveNext();
                rvenum.Current.HashCheckEquivalant = HdrMatch;

                // now we have structured access to the file VA's etc..
                // go through each hash and match
                foreach (var h in mph.HashSet)
                {
                    RVA = h.Address - mph.AllocationBase;
                    if (RVA > uint.MaxValue || RVA < 0)
                    {
                        await failure.CopyToAsync(resp.Body).ConfigureAwait(false);

                        log.LogWarning($"RVA in client JSON request seems invalid, aborting. {RVA:x}");
                        return;
                    }

                    for (int i = 0; i < e.NumberOfSections; i++)
                    {
                        if (RVA >= e.Sections[i].VirtualAddress && RVA < (e.Sections[i].VirtualAddress + e.Sections[i].VirtualSize))
                        {
                            ms = e.Sections[i];
                            break;
                        }
                    }
                    // since RVA is calculated from the AllocationBase, section VA may be anywhere above it
                    // RawFilePointer to get file POS + (RVA - SectionVA)
                    SecOffset   = (RVA - ms.VirtualAddress);
                    fr.Position = ms.RawFilePointer + (RVA - ms.VirtualAddress);

                    // we should be file-aligned to the appropriate location to read a page and check the hash now
                    fr.Read(block, 0, 0x1000);

                    var localHashCheck = hasher.ComputeHash(block);
                    var check64        = Convert.ToBase64String(localHashCheck);

                    if (rvenum.MoveNext())
                    {
                        rvenum.Current.HashCheckEquivalant = (check64 == h.Hash);
                    }

                    if (!rvenum.Current.HashCheckEquivalant && rere != null && e.ImageBase != (ulong)mph.AllocationBase)
                    {
                        AttemptDelocate(block, e, e.ImageBase - (ulong)mph.AllocationBase, RVA, e.ImageBase, rere);

                        check64 = Convert.ToBase64String(hasher.ComputeHash(block));
                        rvenum.Current.HashCheckEquivalant = (check64 == h.Hash);
                    }
                }
            }
#if FALSE
            // find a better way todo this...
            if (Program.Settings.Host.ProxyFailedOrMissing)
            {
                if (rv.Any((x) => !x.HashCheckEquivalant))
                {
                    HttpResponseMessage prox_rv = null;
                    log.LogInformation($"At least one hash check failed, ProxyFailedOrMissing check to double check results");
                    try {
                        prox_rv = WebAPI.POST(hash).Result;
                    } catch (Exception ex)
                    {
                        log.LogWarning($"Error in contacting remote server. {ex}");
                    }
                    if (prox_rv == null)
                    {
                        return;
                    }

                    try
                    {
                        var prox_data = await prox_rv.Content.ReadAsByteArrayAsync();

                        var prox_r = JsonConvert.DeserializeObject <HashSet <PageHashBlockResult> >(Encoding.Default.GetString(prox_data));
                        HashSet <PageHashBlockResult> CombinedLookups = new HashSet <PageHashBlockResult>();
                        var enumer = rv.GetEnumerator();
                        enumer.MoveNext();
                        foreach (var pbr in prox_r)
                        {
                            if (enumer.Current.Address != pbr.Address)
                            {
                                log.LogInformation("Server and local results are not aligne, unable to corolate checks further");
                                break;
                            }
                            // build combined list checking if local passed, use it, if not use the server result, maybe it passed ? ;)
                            CombinedLookups.Add(enumer.Current.HashCheckEquivalant ? enumer.Current : pbr);
                            enumer.MoveNext();
                        }
                        log.LogInformation($"Using combined lookups Orig Pass count[{rv.Count((x) => x.HashCheckEquivalant)}] New pass count [{CombinedLookups.Count((x) => x.HashCheckEquivalant)}]");
                        rv = CombinedLookups;
                    } catch (Exception ex)
                    {
                        log.LogWarning($"Error in corolation processing {ex}");
                    }
                }
            }
#endif
            // since we made it this far we should re-serialize our state since we currently are holding onto
            // and object that is used for a fast path error exit (all failed)
            var r = JsonConvert.SerializeObject(rv, Formatting.Indented);
            resp.StatusCode = 200;
            var success = new StringContent(r, Encoding.Default, "application/json").CopyToAsync(resp.Body).ConfigureAwait(false);
            log.LogInformation($"Finished client service call, hash check results sent.");
        }