public static async Task SaveAsync(TSyscallStats syscallInfo)
        {
            if (syscallInfo == null || syscallInfo.Count == 0)
            {
                return;
            }

            if (await Limiter.WaitAsync(1000, Config.Cts.Token))
            {
                try
                {
                    using var db = new ThumbnailDb();
                    foreach (var productCodeMap in syscallInfo)
                    {
                        var product = db.Thumbnail.AsNoTracking().FirstOrDefault(t => t.ProductCode == productCodeMap.Key)
                                      ?? db.Thumbnail.Add(new Thumbnail {
                            ProductCode = productCodeMap.Key
                        }).Entity;
                        if (product.Id == 0)
                        {
                            await db.SaveChangesAsync(Config.Cts.Token).ConfigureAwait(false);
                        }

                        foreach (var moduleMap in productCodeMap.Value)
                        {
                            foreach (var func in moduleMap.Value)
                            {
                                var syscall = db.SyscallInfo.AsNoTracking().FirstOrDefault(sci => sci.Module == moduleMap.Key.ToUtf8() && sci.Function == func.ToUtf8())
                                              ?? db.SyscallInfo.Add(new SyscallInfo {
                                    Module = moduleMap.Key.ToUtf8(), Function = func.ToUtf8()
                                }).Entity;
                                if (syscall.Id == 0)
                                {
                                    await db.SaveChangesAsync(Config.Cts.Token).ConfigureAwait(false);
                                }

                                if (!db.SyscallToProductMap.Any(m => m.ProductId == product.Id && m.SyscallInfoId == syscall.Id))
                                {
                                    db.SyscallToProductMap.Add(new SyscallToProductMap {
                                        ProductId = product.Id, SyscallInfoId = syscall.Id
                                    });
                                }
                            }
                        }
                    }
                    await db.SaveChangesAsync(Config.Cts.Token).ConfigureAwait(false);
                }
                finally
                {
                    Limiter.Release();
                }
            }
        }
Example #2
0
        public static async Task <(int funcs, int links)> FixInvalidFunctionNamesAsync()
        {
            var syscallStats = new TSyscallStats();
            int funcs = 0, links = 0;

            using (var db = new ThumbnailDb())
            {
                var funcsToFix = new List <SyscallInfo>(0);
                try
                {
                    funcsToFix = await db.SyscallInfo.Where(sci => sci.Function.Contains('(')).ToListAsync().ConfigureAwait(false);

                    funcs = funcsToFix.Count;
                    if (funcs == 0)
                    {
                        return(0, 0);
                    }

                    foreach (var sci in funcsToFix)
                    {
                        var productIds = await db.SyscallToProductMap.AsNoTracking().Where(m => m.SyscallInfoId == sci.Id).Select(m => m.Product.ProductCode).Distinct().ToListAsync().ConfigureAwait(false);

                        links += productIds.Count;
                        foreach (var productId in productIds)
                        {
                            if (!syscallStats.TryGetValue(productId, out var scInfo))
                            {
                                syscallStats[productId] = scInfo = new Dictionary <string, HashSet <string> >();
                            }
                            if (!scInfo.TryGetValue(sci.Module, out var smInfo))
                            {
                                scInfo[sci.Module] = smInfo = new HashSet <string>();
                            }
                            smInfo.Add(sci.Function.Split('(', 2)[0]);
                        }
                    }
                }
                catch (Exception e)
                {
                    Config.Log.Warn(e, "Failed to build fixed syscall mappings");
                    throw e;
                }
                await SaveAsync(syscallStats).ConfigureAwait(false);

                if (await Limiter.WaitAsync(1000, Config.Cts.Token))
                {
                    try
                    {
                        db.SyscallInfo.RemoveRange(funcsToFix);
                        await db.SaveChangesAsync().ConfigureAwait(false);
                    }
                    catch (Exception e)
                    {
                        Config.Log.Warn(e, "Failed to remove broken syscall mappings");
                        throw e;
                    }
                    finally
                    {
                        Limiter.Release();
                    }
                }
            }
            return(funcs, links);
        }