c#如何实现程序加密隐藏

 更新时间:2023年08月15日 14:29:10   作者:tokengo  
LiteDB是一个轻量级的嵌入式数据库,它是用C#编写的,适用于.NET平台,这篇文章主要介绍了如何通过LiteDB将自己的程序进行加密,感兴趣的可以了解下

LiteDB

LiteDB是一个轻量级的嵌入式数据库,它是用C#编写的,适用于.NET平台。它的设计目标是提供一个简单易用的数据库解决方案,可以在各种应用程序中使用。

LiteDB使用单个文件作为数据库存储,这个文件可以在磁盘上或内存中。它支持文档存储模型,类似于NoSQL数据库,每个文档都是一个JSON格式的对象。这意味着你可以存储和检索任意类型的数据,而不需要预定义模式。

LiteDB提供了一组简单的API来执行各种数据库操作,包括插入、更新、删除和查询。它还支持事务,可以确保数据的一致性和完整性。

LiteDB还提供了一些高级功能,如索引、全文搜索和文件存储。索引可以加快查询的速度,全文搜索可以在文本数据中进行关键字搜索,文件存储可以将文件直接存储在数据库中。

LiteDB的优点包括易于使用、轻量级、快速和可嵌入性。它的代码库非常小,可以很容易地集成到你的应用程序中。此外,它还具有跨平台的能力,可以在Windows、Linux和Mac等操作系统上运行。

总之,LiteDB是一个简单易用的嵌入式数据库,适用于各种应用程序。它提供了一组简单的API来执行数据库操作,并支持一些高级功能。如果你需要一个轻量级的数据库解决方案,可以考虑使用LiteDB。

加密封装

创建LiteDB.Service的WebApi项目。

右键发布:

创建控制台LiteDB.Launch项目。

EntryPointDiscoverer.cs 用于寻找执行方法。

internal class EntryPointDiscoverer
{
    public static MethodInfo FindStaticEntryMethod(Assembly assembly, string? entryPointFullTypeName = null)
    {
        var candidates = new List<MethodInfo>();
        if (!string.IsNullOrWhiteSpace(entryPointFullTypeName))
        {
            var typeInfo = assembly.GetType(entryPointFullTypeName, false, false)?.GetTypeInfo();
            if (typeInfo == null)
            {
                throw new InvalidProgramException($"Could not find '{entryPointFullTypeName}' specified for Main method. See <StartupObject> project property.");
            }
            FindMainMethodCandidates(typeInfo, candidates);
        }
        else
        {
            foreach (var type in assembly
                         .DefinedTypes
                         .Where(t => t.IsClass)
                         .Where(t => t.GetCustomAttribute<CompilerGeneratedAttribute>() is null))
            {
                FindMainMethodCandidates(type, candidates);
            }
        }
        string MainMethodFullName()
        {
            return string.IsNullOrWhiteSpace(entryPointFullTypeName) ? "Main" : $"{entryPointFullTypeName}.Main";
        }
        if (candidates.Count > 1)
        {
            throw new AmbiguousMatchException(
                $"Ambiguous entry point. Found multiple static functions named '{MainMethodFullName()}'. Could not identify which method is the main entry point for this function.");
        }
        if (candidates.Count == 0)
        {
            throw new InvalidProgramException(
                $"Could not find a static entry point '{MainMethodFullName()}'.");
        }
        return candidates[0];
    }
    private static void FindMainMethodCandidates(TypeInfo type, List<MethodInfo> candidates)
    {
        foreach (var method in type
                     .GetMethods(BindingFlags.Static |
                                 BindingFlags.Public |
                                 BindingFlags.NonPublic)
                     .Where(m =>
                         string.Equals("Main", m.Name, StringComparison.OrdinalIgnoreCase)))
        {
            if (method.ReturnType == typeof(void)
                || method.ReturnType == typeof(int)
                || method.ReturnType == typeof(Task)
                || method.ReturnType == typeof(Task<int>))
            {
                candidates.Add(method);
            }
        }
    }
}

然后打开Program.cs文件,请注意修改SaveDb的参数为自己项目打包的地址

// 用于打包指定程序。
SaveDb(@"E:\Project\LiteDB-Application\LiteDB.Service\bin\Release\net7.0\publish");
// 打开db
var db = new LiteDatabase("Launch.db");
// 打开表。
var files = db.GetCollection<FileAssembly>("files");
// 接管未找到的程序集处理
AppDomain.CurrentDomain.AssemblyResolve += (sender, eventArgs) =>
{
    try
    {
        var name = eventArgs.Name.Split(",")[0];
        if (!name.EndsWith(".dll"))
        {
            name += ".dll";
        }
        var file = files.FindOne(x => x.Name == name);
        return file != null ? Assembly.Load(file.Bytes) : default;
    }
    catch (Exception)
    {
        return default;
    }
};
// 启动程序。
StartServer("LiteDB.Service", new string[] { });
Console.ReadKey();
void StartServer(string assemblyName, string[] args)
{
    var value = files!.FindOne(x => x.Name == assemblyName + ".dll");
    var assembly = Assembly.Load(value!.Bytes);
    var entryPoint = EntryPointDiscoverer.FindStaticEntryMethod(assembly);
    try
    {
        var parameters = entryPoint.GetParameters();
        if (parameters.Length != 0)
        {
            var parameterValues = parameters.Select(p =>
                    p.ParameterType.IsValueType ? Activator.CreateInstance(p.ParameterType) : null)
                .ToArray();
            entryPoint.Invoke(null, parameterValues);
        }
        else
        {
            entryPoint.Invoke(null, null);
        }
    }
    catch (Exception e)
    {
    }
}
// 扫描指定目录下所有文件和子目录,保存到LiteDB数据库中。
void SaveDb(string path)
{
    var files = ScanDirectory(path);
    using var db = new LiteDatabase("Launch.db");
    var col = db.GetCollection<FileAssembly>("files");
    col.InsertBulk(files);
}
// 实现一个方法,扫描指定目录下所有文件和子目录,返回一个集合。
List<FileAssembly> ScanDirectory(string path)
{
    var files = new List<FileAssembly>();
    var dir = new DirectoryInfo(path);
    var fileInfos = dir.GetFiles("*", SearchOption.AllDirectories);
    foreach (var fileInfo in fileInfos)
    {
        var file = new FileAssembly
        {
            Name = fileInfo.Name,
            Bytes = File.ReadAllBytes(fileInfo.FullName)
        };
        files.Add(file);
    }
    return files;
}
class FileAssembly
{
    /// <summary>
    /// 文件名
    /// </summary>
    public string Name { get; set; }
    /// <summary>
    /// 文件的内容
    /// </summary>
    public byte[] Bytes { get; set; }
}

点击LiteDB.Launch项目文件,添加LiteDB依赖,并且修改SDK为Microsoft.NET.Sdk.Web

<Project Sdk="Microsoft.NET.Sdk.Web">
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net7.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
    </PropertyGroup>
    <ItemGroup>
      <PackageReference Include="LiteDB" Version="5.0.17" />
    </ItemGroup>
</Project>

在启动项目的时候先将LiteDB.Service发布一下。然后修改SaveDb参数为发布的目录(会自动扫描所有文件打包到LiteDB的文件中。)

然后启动项目;

当我们启动了LiteDB.Launch以后在StartServer方法里面就会打开创建的LiteDB文件中搜索到指定的启动程序集。

然后在AppDomain.CurrentDomain.AssemblyResolve中会将启动程序集缺少的程序集加载到域中。

AppDomain.CurrentDomain.AssemblyResolve会在未找到依赖的时候触发的一个事件。

在存储到LiteDB的时候可以对于存储的内容进行加密,然后在AppDomain.CurrentDomain.AssemblyResolve触发的时候将读取LiteDB的文件的内容的时候进行解密。

到此这篇关于c#如何实现程序加密隐藏的文章就介绍到这了,更多相关c#程序加密隐藏内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • VsCode使用EmmyLua插件调试Unity工程Lua代码的详细步骤

    VsCode使用EmmyLua插件调试Unity工程Lua代码的详细步骤

    这篇文章主要介绍了VsCode使用EmmyLua插件调试Unity工程Lua代码,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08
  • c#版json数据解析示例分享

    c#版json数据解析示例分享

    JSON(全称为JavaScript Object Notation) 是一种轻量级的数据交换格式。它是基于JavaScript语法标准的一个子集。 JSON采用完全独立于语言的文本格式,可以很容易在各种网络、平台和程序之间传输。JSON的语法很简单,易于人阅读和编写,同时也易于机器解析和生成
    2014-03-03
  • C#函数式编程中的缓存技术详解

    C#函数式编程中的缓存技术详解

    这篇文章主要介绍了C#函数式编程中的缓存技术详解,本文我们将分成两部分来讲解,第一部分为预计算,第二部分则为缓存,需要的朋友可以参考下
    2015-01-01
  • c#一个定时重启的小程序实现代码

    c#一个定时重启的小程序实现代码

    今天有个朋友找我问有没有一些能像Windows一样计划任务重启的软件,我也不清楚。他它说能让我做一个给他它么?我考虑了一下,他的服务器都是有安装.NET框架的,那可以用.NET来使下~~!
    2008-09-09
  • 深入IComparable与IComparer的排序实例详解

    深入IComparable与IComparer的排序实例详解

    本篇文章是对IComparable与IComparer的排序实例进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • 字符串阵列String[]转换为整型阵列Int[]的实例

    字符串阵列String[]转换为整型阵列Int[]的实例

    下面小编就为大家分享一篇字符串阵列String[]转换为整型阵列Int[]的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-12-12
  • 浅谈C#手机号换成111XXXX1111 这种显示的解决思路

    浅谈C#手机号换成111XXXX1111 这种显示的解决思路

    下面小编就为大家带来一篇浅谈C#手机号换成111XXXX1111 这种显示的解决思路。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-11-11
  • 关于C#继承的简单应用代码分析

    关于C#继承的简单应用代码分析

    在本篇文章里小编给大家整理了一篇关于C#继承的简单应用代码分析内容,有兴趣的朋友们可以学习下。
    2021-05-05
  • C#实现抢红包算法的示例代码

    C#实现抢红包算法的示例代码

    很多商家都会使用红包进行促销,那么你知道红包算法是怎么实现的吗,本文主要介绍了C#实现抢红包算法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • C# Path类---文件路径解读

    C# Path类---文件路径解读

    这篇文章主要介绍了C# Path类---文件路径,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01

最新评论