经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C# » 查看文章
c# 如何将程序加密隐藏?
来源:cnblogs  作者:tokengo  时间:2023/8/16 9:14:55  对本文有异议

下面将介绍如何通过LiteDB将自己的程序进行加密,首先介绍一下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 用于寻找执行方法。

  1. internal class EntryPointDiscoverer
  2. {
  3. public static MethodInfo FindStaticEntryMethod(Assembly assembly, string? entryPointFullTypeName = null)
  4. {
  5. var candidates = new List<MethodInfo>();
  6. if (!string.IsNullOrWhiteSpace(entryPointFullTypeName))
  7. {
  8. var typeInfo = assembly.GetType(entryPointFullTypeName, false, false)?.GetTypeInfo();
  9. if (typeInfo == null)
  10. {
  11. throw new InvalidProgramException($"Could not find '{entryPointFullTypeName}' specified for Main method. See <StartupObject> project property.");
  12. }
  13. FindMainMethodCandidates(typeInfo, candidates);
  14. }
  15. else
  16. {
  17. foreach (var type in assembly
  18. .DefinedTypes
  19. .Where(t => t.IsClass)
  20. .Where(t => t.GetCustomAttribute<CompilerGeneratedAttribute>() is null))
  21. {
  22. FindMainMethodCandidates(type, candidates);
  23. }
  24. }
  25. string MainMethodFullName()
  26. {
  27. return string.IsNullOrWhiteSpace(entryPointFullTypeName) ? "Main" : $"{entryPointFullTypeName}.Main";
  28. }
  29. if (candidates.Count > 1)
  30. {
  31. throw new AmbiguousMatchException(
  32. $"Ambiguous entry point. Found multiple static functions named '{MainMethodFullName()}'. Could not identify which method is the main entry point for this function.");
  33. }
  34. if (candidates.Count == 0)
  35. {
  36. throw new InvalidProgramException(
  37. $"Could not find a static entry point '{MainMethodFullName()}'.");
  38. }
  39. return candidates[0];
  40. }
  41. private static void FindMainMethodCandidates(TypeInfo type, List<MethodInfo> candidates)
  42. {
  43. foreach (var method in type
  44. .GetMethods(BindingFlags.Static |
  45. BindingFlags.Public |
  46. BindingFlags.NonPublic)
  47. .Where(m =>
  48. string.Equals("Main", m.Name, StringComparison.OrdinalIgnoreCase)))
  49. {
  50. if (method.ReturnType == typeof(void)
  51. || method.ReturnType == typeof(int)
  52. || method.ReturnType == typeof(Task)
  53. || method.ReturnType == typeof(Task<int>))
  54. {
  55. candidates.Add(method);
  56. }
  57. }
  58. }
  59. }

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

  1. // 用于打包指定程序。
  2. SaveDb(@"E:\Project\LiteDB-Application\LiteDB.Service\bin\Release\net7.0\publish");
  3. // 打开db
  4. var db = new LiteDatabase("Launch.db");
  5. // 打开表。
  6. var files = db.GetCollection<FileAssembly>("files");
  7. // 接管未找到的程序集处理
  8. AppDomain.CurrentDomain.AssemblyResolve += (sender, eventArgs) =>
  9. {
  10. try
  11. {
  12. var name = eventArgs.Name.Split(",")[0];
  13. if (!name.EndsWith(".dll"))
  14. {
  15. name += ".dll";
  16. }
  17. var file = files.FindOne(x => x.Name == name);
  18. return file != null ? Assembly.Load(file.Bytes) : default;
  19. }
  20. catch (Exception)
  21. {
  22. return default;
  23. }
  24. };
  25. // 启动程序。
  26. StartServer("LiteDB.Service", new string[] { });
  27. Console.ReadKey();
  28. void StartServer(string assemblyName, string[] args)
  29. {
  30. var value = files!.FindOne(x => x.Name == assemblyName + ".dll");
  31. var assembly = Assembly.Load(value!.Bytes);
  32. var entryPoint = EntryPointDiscoverer.FindStaticEntryMethod(assembly);
  33. try
  34. {
  35. var parameters = entryPoint.GetParameters();
  36. if (parameters.Length != 0)
  37. {
  38. var parameterValues = parameters.Select(p =>
  39. p.ParameterType.IsValueType ? Activator.CreateInstance(p.ParameterType) : null)
  40. .ToArray();
  41. entryPoint.Invoke(null, parameterValues);
  42. }
  43. else
  44. {
  45. entryPoint.Invoke(null, null);
  46. }
  47. }
  48. catch (Exception e)
  49. {
  50. }
  51. }
  52. // 扫描指定目录下所有文件和子目录,保存到LiteDB数据库中。
  53. void SaveDb(string path)
  54. {
  55. var files = ScanDirectory(path);
  56. using var db = new LiteDatabase("Launch.db");
  57. var col = db.GetCollection<FileAssembly>("files");
  58. col.InsertBulk(files);
  59. }
  60. // 实现一个方法,扫描指定目录下所有文件和子目录,返回一个集合。
  61. List<FileAssembly> ScanDirectory(string path)
  62. {
  63. var files = new List<FileAssembly>();
  64. var dir = new DirectoryInfo(path);
  65. var fileInfos = dir.GetFiles("*", SearchOption.AllDirectories);
  66. foreach (var fileInfo in fileInfos)
  67. {
  68. var file = new FileAssembly
  69. {
  70. Name = fileInfo.Name,
  71. Bytes = File.ReadAllBytes(fileInfo.FullName)
  72. };
  73. files.Add(file);
  74. }
  75. return files;
  76. }
  77. class FileAssembly
  78. {
  79. /// <summary>
  80. /// 文件名
  81. /// </summary>
  82. public string Name { get; set; }
  83. /// <summary>
  84. /// 文件的内容
  85. /// </summary>
  86. public byte[] Bytes { get; set; }
  87. }

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

  1. <Project Sdk="Microsoft.NET.Sdk.Web">
  2. <PropertyGroup>
  3. <OutputType>Exe</OutputType>
  4. <TargetFramework>net7.0</TargetFramework>
  5. <ImplicitUsings>enable</ImplicitUsings>
  6. <Nullable>enable</Nullable>
  7. </PropertyGroup>
  8. <ItemGroup>
  9. <PackageReference Include="LiteDB" Version="5.0.17" />
  10. </ItemGroup>
  11. </Project>

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

然后启动项目;

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

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

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

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

结尾

来自token的分享

qq技术交流群:737776595

原文链接:https://www.cnblogs.com/hejiale010426/p/17631103.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号