【问题标题】:How to decompress a Fody.Costura packed assembly如何解压缩 Fody.Costura 打包程序集
【发布时间】:2020-01-04 01:05:47
【问题描述】:

我的一个朋友向我提出了解压装有 Fody.Costura 的程序集的挑战。该程序集具有作为资源嵌入的 dll 依赖项。我尝试使用 dotPeek 提取此 .zip 资源并在此处使用此代码解压缩它

public static void Decompress(string path)
{
    using (var stream = File.OpenRead(path))
    using (var compressStream = new DeflateStream(stream, CompressionMode.Decompress))
    {
        compressStream.Seek(0, SeekOrigin.Begin);
        var fs = File.Create(path + ".decompressed");
        compressStream.CopyTo(fs);
        fs.Close();
    }
}

这在提取 .zip 时有效,但结果非常无用

有没有合适的办法解压这个打包好的dll?

【问题讨论】:

  • .text 文件可能包含代码但不可读,它是一个二进制文件
  • 您是否希望在其中找到源代码?解压后,还需要反编译代码。
  • 没想到会在里面找到源代码。我的问题针对的是反编译代码本身的过程。
  • 你试过用你最喜欢的解压工具手动解压吗?
  • 是的,没有用(至少在 7-Zip 中)

标签: c# embedded-resource fody fody-costura


【解决方案1】:

这是我的简单 C# 控制台应用程序代码(框架 4),我通过在编译的 (ConsoleApp1) 可执行文件上“拖放”(Costura 压缩)文件来使用它。

using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text.RegularExpressions;

namespace ConsoleApp1
{
  class Program
  {
    static void CopyTo(Stream source, Stream destination) {
      int count;
      var array = new byte[81920];
      while ((count = source.Read(array, 0, array.Length)) != 0) {
        destination.Write(array, 0, count);
      }
    }

    static Stream LoadStream(string fullname) {
      FileStream stream = default(FileStream);
      if (fullname.EndsWith(".zip")) {
        using (stream = new FileStream(fullname, FileMode.Open)) {
          using (var compressStream = new DeflateStream(stream, CompressionMode.Decompress)) {
            var memStream = new MemoryStream();
            CopyTo(compressStream, memStream);
            memStream.Position = 0;
            return memStream;
          }
        }
      }
      return stream;
    }

    static void Main(string[] args) {
      Stream stream; Stream file;
      string RefilePath = @"^.+[^\\]+\\"; string fullname; string newFile;
      for (int i = 0; i < args.Count(); i++) {
        fullname = args[i];
        newFile = Regex.Replace(fullname, "\\.zip$", string.Empty);
        Console.Write("{0} -> {1}\r\n",
          Regex.Replace(fullname, RefilePath, string.Empty),
          Regex.Replace(newFile, RefilePath, string.Empty));
        try
        {
          stream = LoadStream(fullname);
          using (file = File.Create(newFile)) {
            CopyTo(stream, file);
          }
        }
        catch (Exception ex) {
          Console.Write("{0}", ex.ToString());
        }
      }
    }
  }
}

基于Cameron MacFarland Answer

【讨论】:

    【解决方案2】:

    Costura 用来解压这些资源的代码在这里。

    https://github.com/Fody/Costura/blob/master/src/Costura.Template/Common.cs

    static void CopyTo(Stream source, Stream destination)
    {
        var array = new byte[81920];
        int count;
        while ((count = source.Read(array, 0, array.Length)) != 0)
        {
            destination.Write(array, 0, count);
        }
    }
    
    static Stream LoadStream(string fullname)
    {
        var executingAssembly = Assembly.GetExecutingAssembly();
    
        if (fullname.EndsWith(".zip"))
        {
            using (var stream = executingAssembly.GetManifestResourceStream(fullname))
            using (var compressStream = new DeflateStream(stream, CompressionMode.Decompress))
            {
                var memStream = new MemoryStream();
                CopyTo(compressStream, memStream);
                memStream.Position = 0;
                return memStream;
            }
        }
    
        return executingAssembly.GetManifestResourceStream(fullname);
    }
    

    【讨论】:

    • 关于源的一个小问题:为什么要使用自己的 CopyTo 方法?这是一种特定的方式还是这段代码是在它被实现到标准库之前的代码?
    • Costura 支持 .net 2,是的,它没有本地 CopyTo 方法。
    • 明确地说,这段代码被复制到正在修改的程序集中,因此它与 .net 2 兼容。
    【解决方案3】:

    要解压这些资源,有this 项目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-23
      • 2022-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多