Как распаковать упакованную сборку Fody.Costura

Мой друг дал мне задание распаковать сборку, заполненную Fody.Costura. Сборка имеет зависимость dll, встроенную в качестве ресурса. Я попытался извлечь этот .zip-ресурс с помощью dotPeek и распаковать его с помощью этого кода здесь.

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?


person Christian Klemm    schedule 15.05.2017    source источник
comment
Файл .text может содержать код, но он не читается, это двоичный файл.   -  person Christian Klemm    schedule 15.05.2017
comment
Вы ожидали найти там исходный код? После распаковки вам все равно нужно будет декомпилировать код.   -  person C.Evenhuis    schedule 15.05.2017
comment
Я не ожидал найти там исходный код. Мой вопрос направлен на процесс декомпиляции самого кода.   -  person Christian Klemm    schedule 15.05.2017
comment
Пробовали ли вы вручную разархивировать его с помощью вашего любимого инструмента для распаковки?   -  person C.Evenhuis    schedule 15.05.2017
comment
Да, не работает (по крайней мере с 7-Zip)   -  person Christian Klemm    schedule 15.05.2017
comment
Не работает - сообщение об ошибке? Требуется пароль? деформированный вывод? 7-Zip сломался? Мы не видим того, что видите вы :)   -  person C.Evenhuis    schedule 15.05.2017
comment
Извините, пишет, что это не архив   -  person Christian Klemm    schedule 15.05.2017
comment
В этом вопросе у них работает бит извлечения: stackoverflow.com/questions/39368405/   -  person C.Evenhuis    schedule 15.05.2017
comment
Спасибо, я попробую это позже.   -  person Christian Klemm    schedule 15.05.2017
comment
Ваш код в порядке. Сборка должна иметь имя и заканчиваться на .dll вместо .dll.zip.decompressed. Я не уверен, что вы ожидаете.   -  person Cameron MacFarland    schedule 15.05.2017
comment
@CameronMacFarland вау, ты прав! Я ожидал, что ссылка - это zip, который нужно распаковать.   -  person Christian Klemm    schedule 15.05.2017
comment
Что ж, вы будете отчасти правы. Мне нужно было как-то назвать сжатый ресурс, поэтому я использовал zip, но на самом деле это не zip, и я никогда не ожидал, что люди захотят извлекать ресурсы сами.   -  person Cameron MacFarland    schedule 15.05.2017
comment
Ааа, я вижу, ты один из разработчиков Костуры. Ну, иногда у вас нет другого выхода (кто-нибудь передаст вам бинарник неизвестной сборки, который был упакован с Costura, и вы должны его просмотреть).   -  person Christian Klemm    schedule 15.05.2017


Ответы (3)


Код, который 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);
}
person Cameron MacFarland    schedule 15.05.2017
comment
Небольшой вопрос по поводу источника: зачем собственный метод CopyTo? Имеет ли это особый способ или этот код был создан еще до того, как он был реализован в стандартных библиотеках? - person Christian Klemm; 15.05.2017
comment
Costura поддерживает .net 2, в котором нет собственного метода CopyTo. - person Cameron MacFarland; 15.05.2017
comment
Чтобы было ясно, этот код копируется в изменяемую сборку, поэтому он совместим с .net 2. - person Cameron MacFarland; 15.05.2017

Это мой простой код консольного приложения C# (Framework 4), который я использую, просто «перетаскивая» (Costura Compressed) файлы поверх скомпилированного (ConsoleApp1) исполняемого файла.

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());
        }
      }
    }
  }
}

На основе ответа Кэмерона МакФарланда

person 20AMax    schedule 03.01.2020

Для распаковки этих ресурсов есть этот проект.

person Fábio Augusto Pandolfo    schedule 03.10.2019