下面将介绍如何通过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 用于寻找执行方法。

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的文件的内容的时候进行解密。

结尾

来自token的分享

qq技术交流群:737776595

c# 如何将程序加密隐藏?的更多相关文章

  1. Android程序的隐藏与退出

    转自Android程序的隐藏与退出 Android的程序无需刻意的去退出,当你一按下手机的back键的时候,系统会默认调用程序栈中最上层Activity的Destroy()方法来销毁当前Activit ...

  2. 为你的Python程序加密

      在实际的工作中,有时候我们需要部署自己的Python应用,但这时候我们并不希望别人能够看到自己的Python源程序.因此,我们需要为自己的源代码进行加密,Python已经为我们提供了这样一套工作机 ...

  3. 如何给python程序加密

    在实际的工作中,有时候我们需要部署自己的Python应用,但这时候我们并不希望别人能够看到自己的Python源程序.因此,我们需要为自己的源代码进行加密,Python已经为我们提供了这样一套工作机制. ...

  4. .net 程序加密

    .net 程序加密,一般是对生成的exe文件或者dll直接进行加壳,配合加密锁或者许可进行授权控制,既能保证安全性,又控制软件的使用. 加壳工具的选择 一般要考虑几点,第一是加壳的安全性,不能被轻易脱 ...

  5. 小程序后台隐藏后 socket 无法重新连接

    小程序后台隐藏后 socket 无法重新连接 连接时 fail 回调函数的事件参数:connectSocket:fail:jsapi has no permission,event=createSoc ...

  6. 并发刺客(False Sharing)——并发程序的隐藏杀手

    并发刺客(False Sharing)--并发程序的隐藏杀手 前言 前段时间在各种社交平台"雪糕刺客"这个词比较火,简单的来说就是雪糕的价格非常高!其实在并发程序当中也有一个刺客, ...

  7. ASP程序加密/解密方法大揭密

      如今,用ASP技术构建的网站随处可见.由于ASP脚本是在服务器上解释执行的(无法编译),因此你辛苦开发出来的ASP代码,很容易被人拷去任意修改,如何保护ASP源代码呢?这是每个ASP站长都会遇到的 ...

  8. 微信小程序加密解密 C# 以及 填充无效,无法被移除错误的解决方案 Padding is invalid and cannot be removed

    解密加密源码 using System; using System.Security.Cryptography; using System.Text; namespace Wechat { publi ...

  9. 免费的java代码混淆,程序加密

    java代码可以反编译,特别是放在客户端的程序很用被剽窃,盗用.保护程序一般都有以下几个方法: 1.将class文件加密,这个是最安全的,但也费事儿,因为要重写classloader来解密class文 ...

  10. Android如何做到应用程序图标隐藏,由第三方程序启动

    在你App的AndroidManifest.xml中,将启动页做如下修改 <intent-filter> <action android:name="android.int ...

随机推荐

  1. 2022-08-19:以下go语言代码输出什么?A:equal;B:not equal;C:不确定。 package main import ( “fmt“ “reflect“ )

    2022-08-19:以下go语言代码输出什么?A:equal:B:not equal:C:不确定. package main import ( "fmt" "refle ...

  2. 2022-07-23:给定N件物品,每个物品有重量(w[i])、有价值(v[i]), 只能最多选两件商品,重量不超过bag,返回价值最大能是多少? N <= 10^5, w[i] <= 10^5, v

    2022-07-23:给定N件物品,每个物品有重量(w[i]).有价值(v[i]), 只能最多选两件商品,重量不超过bag,返回价值最大能是多少? N <= 10^5, w[i] <= 1 ...

  3. ES6迭代器(Iterator)和生成器(Generator)

    平时我们迭代数据用得最多的应该就是for循环了 来看个简单的例子 var colors = ["red", "green", "blue"] ...

  4. GPUImage框架使用

    GPUImage框架简介 GPUImage框架是一个基于OpenGL ES 2.0的iOS图像和视频处理框架.它充分利用GPU并行计算能力可以实时处理图像和视频,可以让开发者轻松地实现各种滤镜效果. ...

  5. 一篇文章带你详细了解axios的封装

    axios 封装 对请求的封装在实际项目中是十分必要的,它可以让我们统一处理 http 请求.比如做一些拦截,处理一些错误等.本篇文章将详细介绍如何封装 axios 请求,具体实现的功能如下 基本配置 ...

  6. 基于 Linux 集群环境上 GPFS 的问题诊断

    作者:谷珊,帅炜,陈志阳来源:IBM Developer GPFS 的概述 GPFS 是 IBM 公司提供的一个共享文件系统,它允许所有的集群节点可以并行访问整个文件系统.GPFS 允许客户共享文件, ...

  7. 【LeetCode专题#基本计算器】基本计算器I,图解中序表达式转逆波兰表达式,太难了

    基本计算器 https://leetcode.cn/problems/basic-calculator/?envType=list&envId=cKNEfNsF 给你一个字符串表达式 s ,请 ...

  8. 【PAT】1001 害死人不偿命的(3n+1)猜想(动态更新)

    卡拉兹(Callatz)猜想: 对任何一个正整数 n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把 ( 砍掉一半.这样一直反复砍下去,最后一定在某一步得到 n=1.卡拉兹在 1950 年的世界 ...

  9. 2023-06-19:讲一讲Redis分布式锁的实现?

    2023-06-19:讲一讲Redis分布式锁的实现? 答案2023-06-19: Redis分布式锁最简单的实现 要实现分布式锁,确实需要使用具备互斥性的Redis操作.其中一种常用的方式是使用SE ...

  10. pta第三阶段题目集

    (1)前言 pta第三阶段作业中,主要包含了如下的主要内容: 1.全程贯穿了课程设计的程序,每一次都是上一次的迭代和修改,难度较大,中间涉及到先是类与类之间的多态和继承关系,后面的修改中,转变为了组合 ...