Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
takeshixx committed Apr 28, 2018
1 parent f38ed4a commit 91657ca
Show file tree
Hide file tree
Showing 6 changed files with 208 additions and 2 deletions.
97 changes: 97 additions & 0 deletions CosturaPlugin/ContextMenuCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Linq;
using System.Windows.Forms;
using ICSharpCode.ILSpy;
using ICSharpCode.ILSpy.TreeNodes;
using Mono.Cecil;
using Mono.Collections.Generic;


namespace CosturaPlugin
{
[ExportContextMenuEntryAttribute(Header = "_Load Embedded Resources", Icon = "Load.png")]
public class SaveAssembly : IContextMenuEntry
{
public bool IsVisible(TextViewContext context)
{
return context.SelectedTreeNodes != null && context.SelectedTreeNodes.All(n => n is AssemblyTreeNode);
}

public bool IsEnabled(TextViewContext context)
{
return context.SelectedTreeNodes != null && context.SelectedTreeNodes.Length == 1;
}

public void Execute(TextViewContext context)
{
if (context.SelectedTreeNodes == null)
return;
AssemblyTreeNode node = (AssemblyTreeNode)context.SelectedTreeNodes[0];
AssemblyDefinition asm = node.LoadedAssembly.GetAssemblyDefinitionOrNull();
ModuleDefinition module = asm.MainModule;
string assemblyPath = Path.GetDirectoryName(node.LoadedAssembly.FileName);
Collection<Resource> compressed_resources = new Collection<Resource>();
foreach (var resource in module.Resources) {
if (resource.Name.StartsWith("costura.") && resource.Name.EndsWith(".dll.compressed")) {
compressed_resources.Add(resource);

}
}
foreach (var resource in compressed_resources) {
string fileName = assemblyPath + "/" + resource.Name.Substring(8, resource.Name.LastIndexOf(".compressed") - 8);
if (File.Exists(fileName)) {
// Assembly has already been decompressed and saved in the local path, just load it.
MainWindow.Instance.CurrentAssemblyList.OpenAssembly(fileName);
} else {
EmbeddedResource er = resource as EmbeddedResource;
MemoryStream memoryStream = DecompressEmbeddedAssembly(er.GetResourceStream());
WriteAssemblyToFile(memoryStream, fileName);
OpenAssemblyFromStream(memoryStream, fileName);
}
}
}

private static void PrintDebugWindow(string message)
{
string caption = "CosturaPlugin Debug Output";
MessageBoxButtons buttons = MessageBoxButtons.OK;
MessageBox.Show(message, caption, buttons);
}

private static void OpenAssemblyFromStream(Stream stream, string fileName)
{
stream.Position = 0L;
MainWindow.Instance.CurrentAssemblyList.OpenAssembly(fileName, stream);
}

private static MemoryStream DecompressEmbeddedAssembly(Stream embeded_resource)
{
Assembly executingAssembly = Assembly.GetExecutingAssembly();
DeflateStream source = new DeflateStream(embeded_resource, CompressionMode.Decompress);
MemoryStream memoryStream = new MemoryStream();
CopyTo(source, memoryStream);
memoryStream.Position = 0L;
return memoryStream;
}

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

private static void WriteAssemblyToFile(MemoryStream memoryStream, string fileName)
{
memoryStream.Position = 0L;
using (FileStream output = new FileStream(fileName, FileMode.Create)) {
memoryStream.CopyTo(output);
}
}

}
}
55 changes: 55 additions & 0 deletions CosturaPlugin/CosturaPlugin.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net461</TargetFramework>
<AssemblyName>Costura.Plugin</AssemblyName>

<GenerateAssemblyInfo>False</GenerateAssemblyInfo>

<EnableDefaultItems>False</EnableDefaultItems>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<DebugType>pdbonly</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>

<PropertyGroup>
<!-- Workaround for lack of XAML support in the new project system -->
<LanguageTargets>$(MSBuildExtensionsPath)\$(VisualStudioVersion)\Bin\Microsoft.CSharp.targets</LanguageTargets>
</PropertyGroup>

<ItemGroup>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Windows.Forms">
<HintPath>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\System.Windows.Forms.dll</HintPath>
</Reference>
<Reference Include="System.Xaml" />
<Reference Include="WindowsBase" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\ICSharpCode.Decompiler\ICSharpCode.Decompiler.csproj" />
<ProjectReference Include="..\ILSpy\ILSpy.csproj" />
<ProjectReference Include="..\SharpTreeView\ICSharpCode.TreeView.csproj" />
</ItemGroup>

<ItemGroup>
<Compile Include="ContextMenuCommand.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>

<ItemGroup>
<Resource Include="Load.png" />
</ItemGroup>

</Project>
Binary file added CosturaPlugin/Load.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions CosturaPlugin/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#region Using directives

using System.Reflection;
using System.Runtime.InteropServices;

#endregion

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("CosturaPlugin")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CosturaPlugin")]
[assembly: AssemblyCopyright("Copyright 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// This sets the default COM visibility of types in the assembly to invisible.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
[assembly: ComVisible(false)]

// The assembly version has following format :
//
// Major.Minor.Build.Revision
//
// You can specify all the values or you can use the default the Revision and
// Build Numbers by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
9 changes: 9 additions & 0 deletions CosturaPlugin/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"profiles": {
"CosturaPlugin": {
"commandName": "Executable",
"executablePath": "$(OutDir)ILSpy.exe",
"commandLineArgs": "/separate"
}
}
}
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,17 @@
# ILSpy-CosturaPlugin
A plugin for ILSpy that loads references that have been embedded as resources with Costura.
# Costura Plugin for ILSpy

[Costura](https://github.com/Fody/Costura) is an add-in for [Fody](https://github.com/Fody/Fody/) which allows to embedd references in binaries as resources. This means that e.g. all the DLL files that are required by a binary are added as compressed resources in the new binary. They are loaded with some compiled-in trampolin code by Costura. This plugin adds decompression and loading support for such embedded references to ILSpy to make decompilation of binaries compiled with Costura easier.

## Installation

A pre-built DLL is available in the [release section](https://github.com/takeshixx/ILSpy-CosturaPlugin/releases). Just copy it to the same directory where the `ILSpy.exe` resides and run `ILSpy.exe`.

## Building

Clone the ILSpy repository:

```
git clone https://github.com/icsharpcode/ILSpy.git
```

Copy the `CosturaPlugin` folder to the ILSpy directory. Then open `ILSpy.sln` in Visual Studio and add `CosturaPlugin/CosturaPlugin.csproj` as existing project. Then just build the `CosturaPlugin` project.

0 comments on commit 91657ca

Please # to comment.