Skip to content

Commit

Permalink
Initial code commit
Browse files Browse the repository at this point in the history
  • Loading branch information
bbepis committed Jul 31, 2021
1 parent 0bdcee4 commit 9889004
Show file tree
Hide file tree
Showing 8 changed files with 697 additions and 0 deletions.
25 changes: 25 additions & 0 deletions NStrip.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30011.22
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NStrip", "NStrip\NStrip.csproj", "{CE5BFF3E-2350-46AE-A54E-0631D89565F4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CE5BFF3E-2350-46AE-A54E-0631D89565F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CE5BFF3E-2350-46AE-A54E-0631D89565F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CE5BFF3E-2350-46AE-A54E-0631D89565F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CE5BFF3E-2350-46AE-A54E-0631D89565F4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {505788DE-B387-43E7-90DB-98E6903B88EE}
EndGlobalSection
EndGlobal
6 changes: 6 additions & 0 deletions NStrip/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>
96 changes: 96 additions & 0 deletions NStrip/AssemblyStripper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
using System.Collections.Generic;
using Mono.Cecil;
using Mono.Cecil.Cil;

namespace NStrip
{
public static class AssemblyStripper
{
static IEnumerable<TypeDefinition> GetAllTypeDefinitions(AssemblyDefinition assembly)
{
var typeQueue = new Queue<TypeDefinition>(assembly.MainModule.Types);

while (typeQueue.Count > 0)
{
var type = typeQueue.Dequeue();

yield return type;

foreach (var nestedType in type.NestedTypes)
typeQueue.Enqueue(nestedType);
}
}

static void ClearMethodBodies(TypeReference voidTypeReference, ICollection<MethodDefinition> methods)
{
foreach (MethodDefinition method in methods)
{
if (!method.HasBody)
continue;

MethodBody body = new MethodBody(method);
var il = body.GetILProcessor();

// There's multiple ways we could handle this:
// - Only provide a ret. Smallest size, however if .NET tries to load this assembly during runtime it might fail.
// - Providing a value and ret (what we currently do). Slightly more space, however .NET should be fine loading it.
// - Null body, i.e. mark everything as extern. Should theoretically work when loaded into .NET and be the smallest size,
// but the size of assembly remains the same. Might be a bug within Mono.Cecil.

if (method.ReturnType.IsPrimitive)
{
il.Emit(OpCodes.Ldc_I4_0);
}
else if (method.ReturnType != voidTypeReference)
{
il.Emit(OpCodes.Ldnull);
}

il.Emit(OpCodes.Ret);

method.Body = body;

method.AggressiveInlining = false;
method.NoInlining = true;
}
}

public static void StripAssembly(AssemblyDefinition assembly)
{
if (!assembly.MainModule.TryGetTypeReference("System.Void", out var voidTypeReference))
{
voidTypeReference = assembly.MainModule.ImportReference(typeof(void));
}

foreach (TypeDefinition type in GetAllTypeDefinitions(assembly))
{
if (type.IsEnum || type.IsInterface)
continue;

ClearMethodBodies(voidTypeReference, type.Methods);
}

assembly.MainModule.Resources.Clear();
}

public static void MakePublic(AssemblyDefinition assembly, IList<string> typeNameBlacklist)
{
foreach (var type in GetAllTypeDefinitions(assembly))
{
if (typeNameBlacklist.Contains(type.Name))
continue;

if (type.IsNested)
type.IsNestedPublic = true;
else
type.IsPublic = true;

foreach (var method in type.Methods)
method.IsPublic = true;

foreach (var field in type.Fields)
field.IsPublic = true;
}
}
}
}
Loading

0 comments on commit 9889004

Please sign in to comment.