2

A friend of mine gave me the challenge to decompress an assembly that was packed with Fody.Costura. The assembly has a dll dependency that was embedded as a resource. I tried to extract this .zip resource with dotPeek and decompress it with this code here

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

This works when it comes to extracting the .zip but the result is quite unuseful enter image description here

Is there a suitable solution to decompress this packed dll?

Christian Klemm
  • 1,180
  • 3
  • 20
  • 43

3 Answers3

2

This is my simple C# Console App code (Framework 4), which I`m using simply by "drag and drop" (Costura Compressed) files over compiled (ConsoleApp1) executable.

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

Based On Cameron MacFarland Answer

20AMax
  • 161
  • 3
  • 6
1

The code that Costura uses to decompress those resources is here.

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);
}
Cameron MacFarland
  • 65,569
  • 20
  • 98
  • 130
1

To decompress those resources there is this project to.