fremag/MemoScope.Net

View on GitHub
MemoScope/Modules/Strings/StringAnalysis.cs

Summary

Maintainability
A
1 hr
Test Coverage
using System.Collections.Generic;
using MemoScope.Core;
using System.Linq;
using MemoScope.Core.Data;
using WinFwk.UIMessages;
using WinFwk.UIModules;
using System.Threading;

namespace MemoScope.Modules.Strings
{
    public class StringAnalysis
    {
        internal static List<StringInformation> Analyse(ClrDump clrDump, MessageBus msgBus)
        {
            var stringType = clrDump.GetClrType(typeof(string).FullName);
            var stringInstances = clrDump.EnumerateInstances(stringType);
            int nbStrings = clrDump.CountInstances(stringType);
            Dictionary <string, List<ulong>> result = new Dictionary<string, List<ulong>>();
            CancellationTokenSource token = new CancellationTokenSource();
            msgBus.BeginTask("Analyzing strings...", token);
            int n = 0;
            clrDump.Run(() =>
            {
                foreach (var address in stringInstances)
                {
                    if( token.IsCancellationRequested)
                    {
                        return;
                    }
                    n++;
                    var value = SimpleValueHelper.GetSimpleValue(address, stringType, false) as string;
                    if (value == null)
                    {
                        continue;
                    }
                    List<ulong> addresses;
                    if( ! result.TryGetValue(value, out addresses))
                    {
                        addresses = new List<ulong>();
                        result[value] = addresses;
                    }
                    addresses.Add(address);
                    if( n  % 1024 == 0)
                    {
                        float pct = (float)n / nbStrings;
                        msgBus.Status($"Analyzing strings: {pct:p2}, n= {n:###,###,###,##0} / {nbStrings:###,###,###,##0}");
                    }
                }
            });
            msgBus.EndTask($"Strings analyzed. Instances: {n:###,###,###,##0}, unique values: {result.Count:###,###,###,##0}");

            var strings = result.Select(kvp => new StringInformation(kvp.Key, kvp.Value)).ToList();
            return strings;
        }
    }
}