Skip to content

Instantly share code, notes, and snippets.

@hypeartist
Created February 8, 2022 20:24
Show Gist options
  • Save hypeartist/5b3913f8fb4bc7d145265ce18c511f53 to your computer and use it in GitHub Desktop.
Save hypeartist/5b3913f8fb4bc7d145265ce18c511f53 to your computer and use it in GitHub Desktop.
diff --git a/src/PowerUp.Core/Decompilation/JITExtensions.cs b/src/PowerUp.Core/Decompilation/JITExtensions.cs
index 88b3397..0f18362 100644
--- a/src/PowerUp.Core/Decompilation/JITExtensions.cs
+++ b/src/PowerUp.Core/Decompilation/JITExtensions.cs
@@ -5,23 +5,18 @@ using System.Runtime.CompilerServices;
using System.Text;
using PowerUp.Core.Console;
using System.Linq;
+using System.Runtime.InteropServices;
using PowerUp.Core.Decompilation.Attributes;
namespace PowerUp.Core.Decompilation
{
public static class JitExtensions
{
- public static TypeLayout ToLayout(this Type typeInfo, bool @private = false, object[] parameters = null)
+ public static TypeLayout ToLayout(this Type typeInfo)
{
var decompiler = new JitCodeDecompiler();
- var flags = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
- if (@private)
- {
- flags |= BindingFlags.NonPublic;
- }
-
- if (typeInfo.IsInterface)
+ if (typeInfo.IsInterface || typeInfo.IsAbstract)
{
return new TypeLayout()
{
@@ -31,112 +26,13 @@ namespace PowerUp.Core.Decompilation
};
}
- if (parameters == null)
- parameters = TryGetConstructorParameters(typeInfo);
-
- //
- // Get the layout:
- // To be able to create the object we need to call it's constructor.
- // The constructor parameters can be passed from the caller, or set by an Contructor Attribute
- // or guessed with some accuracy.
- //
- if (HasDefaultConstructorOrIsStruct(typeInfo) || parameters != null)
- {
- var obj = Activator.CreateInstance(typeInfo, parameters);
- var typeMemLayout = decompiler.GetTypeLayoutFromHeap(typeInfo, obj);
-
- return typeMemLayout;
- }
- else
- {
- return new TypeLayout()
- {
- Name = typeInfo.Name,
- IsValid = false,
- Message = @"Type Layout requires a default constructor"
- };
- }
- }
-
- private static object[] TryGetConstructorParameters(Type typeInfo)
- {
- object[] values = null;
-
- //
- // Try and get constructor params from an attribute if present.
- // If it's not present there should be a way to guess them with good
- // accuracy; here's how we're going to do it:
- //
- // - ValueTypes can be just instantiated
- // - ReferenceTypes can be null
- //
- var attrs = typeInfo.GetCustomAttributes();
- foreach (var attr in attrs)
- {
- var type = attr.GetType();
- if (type.Name == "ConstructorAttribute")
- {
- var props = type.GetProperties();
- var parameters = props.First(x => x.Name == "Parameters");
- values = (object[])parameters.GetValue(attr);
- break;
- }
- }
- //
- // Guess values
- //
- if (values == null)
- {
- var constructor = typeInfo.GetConstructors().FirstOrDefault();
- //
- // There is a possibility that there will be no constructors
- // a struct is a good example of this.
- //
- if (constructor != null)
- {
- var parameters = constructor.GetParameters();
- values = new object[parameters.Length];
-
- int idx = 0;
- foreach (var param in parameters)
- {
- if (param.ParameterType.IsValueType)
- {
- values[idx] = Activator.CreateInstance(param.ParameterType);
- }
- else
- {
- values[idx] = null;
- }
+ var obj = RuntimeHelpers.GetUninitializedObject(typeInfo);
+ var typeMemLayout = decompiler.GetTypeLayoutFromHeap(typeInfo, obj);
- idx++;
- }
- }
-
- }
- return values;
- }
-
-
- private static bool HasDefaultConstructorOrIsStruct(Type type)
- {
- //
- // Value Types are somewhat interesting since they don't
- // have any default constructors in the metadata but
- // they can still be instantiated using one.
- //
- if (type.IsValueType) return true;
-
- var constructors = type.GetConstructors();
- foreach (var c in constructors)
- {
- if (c.GetParameters().Length == 0)
- return true;
- }
- return false;
+ return typeMemLayout;
}
- public static DecompiledMethod[] ToAsm(this Type typeInfo, ILMethodMap[] sourceCodeMap = null, bool @private = false)
+ public static DecompiledMethod[] ToAsm(this Type typeInfo, ILMethodMap[] sourceCodeMap = null, bool @private = false)
{
if (typeInfo.IsEnum)
return Array.Empty<DecompiledMethod>();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment