了解代码混淆的应该对Obfuscar不陌生
他是一个开源的.net混淆工具
源码信息
https://github.com/obfuscar/obfuscar
本次以贴代码客服源码为例,介绍如何使用Obfuscar混淆你的源码!
引入nuget包
在PasteTalk.HttpApi.Host引入包
<PackageReference Include="Obfuscar" Version="2.2.38">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
修改项目文件,信息如下
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<SatelliteResourceLanguages>null</SatelliteResourceLanguages>
<ServerGarbageCollection>false</ServerGarbageCollection>
<ConcurrentGarbageCollection>true</ConcurrentGarbageCollection>
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
<RootNamespace>PasteTalk.HttpApi.Host</RootNamespace>
<PreserveCompilationReferences>true</PreserveCompilationReferences>
<UserSecretsId>63aefe29-6779-492b-b195-a0b2432ab3b4</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerfileContext>..\..</DockerfileContext>
<DocumentationFile>..\PasteTalk.HttpApi.Host\PasteTalk.HttpApi.Host.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Compile Remove="logs\**" />
<Content Remove="logs\**" />
<EmbeddedResource Remove="logs\**" />
<None Remove="logs\**" />
</ItemGroup>
<ItemGroup>
<Content Remove="font\roles.json" />
</ItemGroup>
<ItemGroup>
<None Include="font\roles.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.10">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Obfuscar" Version="2.2.38">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Volo.Abp.Autofac" Version="8.3.2" />
<PackageReference Include="Volo.Abp.Swashbuckle" Version="8.3.2" />
<PackageReference Include="System.IO.FileSystem.Primitives" Version="4.3.0" />
<PackageReference Include="System.Runtime.Handles" Version="4.3.0" />
<PackageReference Include="System.Runtime.InteropServices" Version="4.3.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PasteTalk.Application\PasteTalk.Application.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="Dockerfile">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="font\font.ttf">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="obfuscar.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command=""$(Obfuscar)" obfuscar.xml
copy .\bin\Obfuscar\PasteTalk.Handler.dll .\bin\Release\net8.0\PasteTalk.Handler.dll" />
</Target>
</Project>
看上面,有涉及一个文件obfuscar.xml
obfuscar.xml
如何混淆,要看配置文件,内容如下
<?xml version='1.0'?>
<Obfuscator>
<!-- 输入的工作路径,采用如约定的 Windows 下的路径表示法,Obfuscar如以下表示当前工作路径 -->
<!-- 推荐使用当前工作路径,因为 DLL 的混淆过程,需要找到 DLL 的所有依赖。刚好当前工作路径下,基本都能满足条件 -->
<Var name="InPath" value=".\bin\Release\net8.0" />
<!-- 混淆之后的输出路径,如下面代码,设置为当前工作路径下的 Obfuscar 文件夹 -->
<!-- 混淆完成之后的新 DLL 将会存放在此文件夹里 -->
<Var name="OutPath" value=".\bin\Obfuscar" />
<!-- 以下的都是细节的配置,配置如何进行混淆 -->
<!-- 使用 KeepPublicApi 配置是否保持公开的 API 不进行混淆签名,如公开的类型公开的方法等等,就不进行混淆签名了 -->
<!-- 语法的写法就是 name 表示某个开关,而 value 表示值 -->
<!-- 对于大部分的库来说,设置公开的 API 不进行混淆是符合预期的 -->
<Var name="KeepPublicApi" value="true" />
<!-- 设置 HidePrivateApi 为 true 表示,对于私有的 API 进行隐藏,隐藏也就是混淆的意思 -->
<!-- 可以通过后续的配置,设置混淆的方式,例如使用 ABC 字符替换,或者使用不可见的 Unicode 代替 -->
<Var name="HidePrivateApi" value="true" />
<!-- 设置 HideStrings 为 true 可以设置是否将使用的字符串进行二次编码 -->
<!-- 由于进行二次编码,将会稍微伤一点点性能,二次编码需要在运行的时候,调用 Encoding 进行转换为字符串 -->
<Var name="HideStrings" value="false" />
<!-- 设置 UseUnicodeNames 为 true 表示使用不可见的 Unicode 字符代替原有的命名,通过此配置,可以让反编译看到的类和命名空间和成员等内容都是不可见的字符 -->
<Var name="UseUnicodeNames" value="true" />
<!-- 是否复用命名,设置为 true 的时候,将会复用命名,如在不同的类型里面,对字段进行混淆,那么不同的类型的字段可以是重名的 -->
<!-- 设置为 false 的时候,全局将不会有重复的命名 -->
<Var name="ReuseNames" value="true" />
<!-- 配置是否需要重命名字段,默认配置了 HidePrivateApi 为 true 将都会打开重命名字段,因此这个配置的存在只是用来配置为 false 表示不要重命名字段 -->
<Var name="RenameFields" value="false" />
<!-- 是否需要重新生成调试信息,生成 PDB 符号文件 -->
<Var name="RegenerateDebugInfo" value="true" />
<Module file="$(InPath)\PasteTalk.Handler.dll" >
<SkipNamespace name="Volo.Abp.*" />
<SkipNamespace name="Microsoft.*" />
<SkipNamespace name="System.*" />
<SkipType name="*AnonymousType*" skipProperties="true" skipMethods="true" skipFields="true" skipEvents="true" skipStringHiding="true" />
</Module>
<AssemblySearchPath path="D:\nugetpackage\microsoft.aspnetcore.signalr.core\1.1.0\lib\netstandard2.0\"/>
<!-- 需要进行混淆的程序集,可以传入很多个,如传入一排排 -->
<!-- <Module file="$(InPath)\Lib1.dll" /> -->
<!-- <Module file="$(InPath)\Lib2.dll" /> -->
<!-- 程序集的引用加载路径,对于 dotnet 6 应用,特别是 WPF 或 WinForms 项目,是需要特别指定引用加载路径的 -->
<!-- 这里有一个小的需要敲黑板的知识点,应该让 Microsoft.WindowsDesktop.App 放在 Microsoft.NETCore.App 之前 -->
<!-- 对于部分项目,如果没有找到如下顺序,将会在混淆过程中,将某些程序集解析为旧版本,从而失败 -->
<!--<AssemblySearchPath path="C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\6.0.1\" />-->
<!--<AssemblySearchPath path="C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.1\" />-->
</Obfuscator>
上面的配置信息注释非常全了,如果要加密多个dll按照上面的Module再加就行
至于加密的配置,一定要测试,测试,测试!
因为有些配置加密后,可能不能使用了!
上面的有一些路径是我电脑的,所以要基于你的实际情况做修改!
上面中的路径 “.\bin\Release\net8.0”是从发布那获得的
文件obfuscar.xml文件存放在如下
生成测试
以上配置后,我们生成试试
20:12:02:844 重新生成开始于 20:12...
20:12:05:281 已还原 D:\GiteeProject\PasteTalk\PasteTalk\PasteTalk.Domain\PasteTalk.Domain.csproj (用时 1.92 秒)。
20:12:05:281 已还原 D:\GiteeProject\PasteTalk\PasteTalk\PasteTalk.EntityFrameworkCore\PasteTalk.EntityFrameworkCore.csproj (用时 1.95 秒)。
20:12:05:281 已还原 D:\GiteeProject\PasteTalk\PasteTalk\PasteTalk.Application.Contracts\PasteTalk.Application.Contracts.csproj (用时 1.96 秒)。
20:12:05:343 已还原 D:\GiteeProject\PasteTalk\PasteTalk\PasteTalk.Handler\PasteTalk.Handler.csproj (用时 2 秒)。
20:12:05:343 已还原 D:\GiteeProject\PasteTalk\PasteTalk\PasteTalk.Application\PasteTalk.Application.csproj (用时 2.02 秒)。
20:12:05:416 1>------ 已启动全部重新生成: 项目: PasteTalk.Domain, 配置: Release Any CPU ------
20:12:05:418 已还原 D:\GiteeProject\PasteTalk\PasteTalk\PasteTalk.HttpApi.Host\PasteTalk.HttpApi.Host.csproj (用时 2.09 秒)。
20:12:09:164 1>PasteTalk.Domain -> D:\GiteeProject\PasteTalk\PasteTalk\PasteTalk.Domain\bin\Release\net8.0\PasteTalk.Domain.dll
20:12:09:184 2>------ 已启动全部重新生成: 项目: PasteTalk.EntityFrameworkCore, 配置: Release Any CPU ------
20:12:09:185 3>------ 已启动全部重新生成: 项目: PasteTalk.Application.Contracts, 配置: Release Any CPU ------
20:12:10:343 2>PasteTalk.EntityFrameworkCore -> D:\GiteeProject\PasteTalk\PasteTalk\PasteTalk.EntityFrameworkCore\bin\Release\net8.0\PasteTalk.EntityFrameworkCore.dll
20:12:11:234 3>PasteTalk.Application.Contracts -> D:\GiteeProject\PasteTalk\PasteTalk\PasteTalk.Application.Contracts\bin\Release\net8.0\PasteTalk.Application.Contracts.dll
20:12:11:246 4>------ 已启动全部重新生成: 项目: PasteTalk.Handler, 配置: Release Any CPU ------
20:12:12:062 4>PasteTalk.Handler -> D:\GiteeProject\PasteTalk\PasteTalk\PasteTalk.Handler\bin\Release\net8.0\PasteTalk.Handler.dll
20:12:12:076 5>------ 已启动全部重新生成: 项目: PasteTalk.Application, 配置: Release Any CPU ------
20:12:13:050 5>PasteTalk.Application -> D:\GiteeProject\PasteTalk\PasteTalk\PasteTalk.Application\bin\Release\net8.0\PasteTalk.Application.dll
20:12:13:055 6>------ 已启动全部重新生成: 项目: PasteTalk.HttpApi.Host, 配置: Release Any CPU ------
20:12:15:257 6>PasteTalk.HttpApi.Host -> D:\GiteeProject\PasteTalk\PasteTalk\PasteTalk.HttpApi.Host\bin\Release\net8.0\PasteTalk.HttpApi.Host.dll
20:12:15:609 6>Note that Rollbar API is enabled by default to collect crashes. If you want to opt out, please run with -s switch
20:12:16:327 6>Loading project obfuscar.xml...Processing assembly: PasteTalk.Handler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
20:12:16:716 6>Loading assemblies...Extra framework folders: Done.
20:12:16:780 6>Hiding strings...
20:12:16:869 6>Renaming: fields...Parameters...Properties...Events...Methods...Types...Done.
20:12:17:079 6>Saving assemblies...Done.
20:12:17:140 6>Writing log file...Done.
20:12:17:140 6>Completed, 1.13 secs.
20:12:17:261 6>已复制 1 个文件。
20:12:17:276 ========== “全部重新生成”: 6 成功,0 失败,0已跳过 ==========
20:12:17:276 ========== 重新生成 于 20:12 完成,耗时 14.469 秒 ==========
可以看到已经执行成功了,不过生成的文件存放于
<Var name="OutPath" value=".\bin\Obfuscar" />
所以在发布的时候还得执行一个动作,就是复制到发布的文件夹
这个就得看PasteSpiderFile的配置!
PasteSpiderFile配置
打开PasteSpiderFile找到对应的项目,点击配置
所以我们使用到的是PasteSpiderFile的前置命令!
这个前置命令的意思是 在执行“对比差异”前执行的命令
注意多个命令之间使用;隔开
多个命令之间没有上下文的关联,所以路径全部要写全路径!
这样在改动代码后,只要点击1位置的发布,等待2位置提示发布成功,然后就可以点击3执行一键发布了
等一会,服务器就会升级为新的版本(这个可以查看对应的钉钉、企业微信、飞书的WebHook通知!)