简体   繁体   English

在 msbuild 将二进制文件打包到单个文件之前如何访问二进制文件

[英]How to access binary before msbuild packs it to single file

I'm using ConfuserEx to obfuscate my app, but it requires whole .dll binary file.我正在使用 ConfuserEx 来混淆我的应用程序,但它需要整个.dll二进制文件。
So, is there a way to obfuscate it using cli and then pack it to single file, or那么,有没有办法使用 cli 对其进行混淆,然后将其打包到单个文件中,或者
access binary before compressing it to single file, so i can obfuscate it在将其压缩为单个文件之前访问二进制文件,因此我可以对其进行混淆

I tried to do exclude main binary by ExcludeFromSingleFile , but it didn't work我试图通过ExcludeFromSingleFile排除主要二进制文件,但它没有用

My .crproj file我的.crproj文件

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <OutputType>exe</OutputType>
        <AssemblyName>jay-$(RuntimeIdentifier)</AssemblyName>
        <PublishSingleFile>true</PublishSingleFile>
        <IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
        <IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
        <TargetFramework>net5.0</TargetFramework>
    </PropertyGroup>

    <ItemGroup>
        <Content Update="$(AssemblyName).dll">
            <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
            <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
        </Content>
    </ItemGroup>

    <ItemGroup>
      <PackageReference Include="CloudFlareUtilities" Version="1.3.0" />
      <PackageReference Include="Colorful.Console" Version="1.2.15" />
      <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
      <PackageReference Include="YamlDotNet" Version="9.1.4" />
    </ItemGroup>

</Project>

You need to add it as a post-build event, for example:您需要将其添加为构建后事件,例如:

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <OutputType>exe</OutputType>
        <AssemblyName>jay-$(RuntimeIdentifier)</AssemblyName>
        <PublishSingleFile>true</PublishSingleFile>
        <IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
        <IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
        <TargetFramework>net5.0</TargetFramework>
    </PropertyGroup>

    <!-- runs: TheAppToPassItTo.exe "<path to dll>" -->
    <Target Name="PostBuild" AfterTargets="PostBuildEvent">
      <Exec Command="TheAppToPassItTo.exe &quot;$(TargetPath)&quot;" />
    </Target>

    <ItemGroup>
      <PackageReference Include="CloudFlareUtilities" Version="1.3.0" />
      <PackageReference Include="Colorful.Console" Version="1.2.15" />
      <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
      <PackageReference Include="YamlDotNet" Version="9.1.4" />
    </ItemGroup>

</Project>

Edited To Add编辑添加

So, it turns out that the new "single file" executable option doesn't build it's executable from the bin directory, but from the obj directory.因此,事实证明,新的“单个文件”可执行选项不是从bin目录构建它的可执行文件,而是从obj目录构建它的可执行文件。 This has to be a simple oversight from the .NET team.这必须是 .NET 团队的简单疏忽。 There are many times where you'd want to modify your executable code before packing it up.很多时候,您希望在打包之前修改可执行代码。 What you are asking for is not unreasonable.你所要求的并不是不合理的。

We can accomplish this by implementing a kludge until this gets rectified.我们可以通过实施一个 kludge 来实现这一点,直到它得到纠正。 We will still use the "post-build" job, but we are going to do some string replacement to build the correct path to the executable you want to modify.我们仍将使用“构建后”作业,但我们将进行一些字符串替换来构建您要修改的可执行文件的正确路径。

This is the new script:这是新脚本:

@ECHO off
SET tp=$(TargetPath)
SET tp=%tp:\bin\=\obj\% 
ECHO Target file to modify: %tp%
YourObfuscatorEngine.exe "%tp%"

This will get the target path, in my case it is:这将获得目标路径,在我的情况下是:

D:\Repositories\Source\ConsoleApp2\ConsoleApp2\bin\Release\netcoreapp3.1\win-x64\ConsoleApp2.dll

Then we do a string replace.然后我们进行字符串替换。 We replace \bin\ with \obj\ .我们将\bin\替换为\obj\ The path will then be:路径将是:

D:\Repositories\Source\ConsoleApp2\ConsoleApp2\obj\Release\netcoreapp3.1\win-x64\ConsoleApp2.dll

Now when you call your obfuscator engine, it will modify the correct file.现在,当您调用混淆器引擎时,它将修改正确的文件。

Please keep in mind that if you turn on the PublishReadyToRun option, your path will change to:请记住,如果您打开PublishReadyToRun选项,您的路径将更改为:

D:\Repositories\Source\ConsoleApp2\ConsoleApp2\obj\Release\netcoreapp3.1\win-x64\R2R\ConsoleApp2.dll

Which will make this a tad more complicated.这会使这有点复杂。 So just keep that in mind if you decide you want to do this.因此,如果您决定要这样做,请记住这一点。

At the end of the day, your post-build script will look like this:最终,您的构建后脚本将如下所示:

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <OutputType>exe</OutputType>
        <AssemblyName>jay-$(RuntimeIdentifier)</AssemblyName>
        <PublishSingleFile>true</PublishSingleFile>
        <IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
        <IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
        <TargetFramework>net5.0</TargetFramework>
    </PropertyGroup>

  <Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <Exec Command="@ECHO off&#xD;&#xA;SET tp=$(TargetPath)&#xD;&#xA;SET tp=%25tp:\bin\=\obj\%25 &#xD;&#xA;ECHO Target file to modify: %25tp%25&#xD;&#xA;YourObfuscatorEngine.exe &quot;%25tp%25&quot;" />
  </Target>

    <ItemGroup>
      <PackageReference Include="CloudFlareUtilities" Version="1.3.0" />
      <PackageReference Include="Colorful.Console" Version="1.2.15" />
      <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
      <PackageReference Include="YamlDotNet" Version="9.1.4" />
    </ItemGroup>

</Project>

if you only need to modify the file on publish, I suggest hooking into the publish pipeline:如果您只需要在发布时修改文件,我建议您连接到发布管道:

<Target Name="ObfuscateAssembly" BeforeTargets="PrepareForPublish">
  <Exec Command="some.exe %(IntermediateAssembly.FullPath)" />
</Target>

In case a larger process is needed, eg for this sample all dependencies need to be present for the obfuscator to work on all assemblies, an extended method of hooking into the build process would be after ComputeResolvedFilesToPublishList where the SDK figures out what files are needed to publish.如果需要更大的进程,例如对于这个示例,所有依赖项都需要存在,混淆器才能处理所有程序集,挂钩到构建过程的扩展方法将在ComputeResolvedFilesToPublishList之后,其中 SDK 确定需要哪些文件发布。

Here's the full example where the obfuscator works on all the assemblies in a directory:这是混淆器在目录中的所有程序集上工作的完整示例:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
    <PublishReadyToRun>True</PublishReadyToRun>
    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
    <SelfContained>False</SelfContained>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
  </ItemGroup>

  <Target Name="CalculateObfuscationInputs" DependsOnTargets="_ComputeAssembliesToPostprocessOnPublish">
    <PropertyGroup>
      <ObfuscationDir>$(IntermediateOutputPath)obfuscation\</ObfuscationDir>
    </PropertyGroup>
    <ItemGroup>
      <AssembliesToObfuscate Include="@(ResolvedFileToPublish->WithMetadataValue('PostprocessAssembly', 'true'))" />
      <AssembliesToObfuscateTemporaryLocation Include="@(AssembliesToObfuscate->'$(ObfuscationDir)%(Filename)%(Extension)')" />
      <_PdbsToObfuscateInput Include="@(AssembliesToObfuscate->'%(RelativeDir)%(Filename).pdb')" />
      <PdbsToObfuscate Include="@(_PdbsToObfuscateInput)" RelativePath="%(_PdbsToObfuscateInput.Identity)" Condition="Exists(%(_PdbsToObfuscateInput.Identity))" />
      <PdbsToObfuscateTemporaryLocation Include="@(PdbsToObfuscate->'$(ObfuscationDir)%(Filename)%(Extension)')" />
    </ItemGroup>
    <MakeDir Directories="$(ObfuscationDir)" />
  </Target>

  <Target Name="PrepareForObfuscation" Inputs="@(AssembliesToObfuscate);@(PdbsToObfuscate)" Outputs="@(AssembliesToObfuscateTemporaryLocation);@(PdbsToObfuscateTemporaryLocation)">
    <Copy SourceFiles="@(AssembliesToObfuscate);@(PdbsToObfuscate)" DestinationFiles="@(AssembliesToObfuscateTemporaryLocation);@(PdbsToObfuscateTemporaryLocation)" SkipUnchangedFiles="True" />
  </Target>

  <Target Name="ObfuscateAssembly" AfterTargets="ComputeResolvedFilesToPublishList" DependsOnTargets="CalculateObfuscationInputs;PrepareForObfuscation">
    <Exec Command="some-obfuscator.exe $(ObfuscationDir)" />
    <ItemGroup>
      <ResolvedFileToPublish Remove="@(AssembliesToObfuscate);@(PdbsToObfuscate)" />
      <ResolvedFileToPublish Include="@(AssembliesToObfuscateTemporaryLocation);@(PdbsToObfuscateTemporaryLocation)" />
    </ItemGroup>
  </Target>

</Project>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM