Skip to content

Commit

Permalink
A small amount of work on actions, I'm not at a place I can do a lot …
Browse files Browse the repository at this point in the history
…of work rn
  • Loading branch information
Sam Byass committed Sep 7, 2020
1 parent 5346ab6 commit b630789
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 36 deletions.
23 changes: 19 additions & 4 deletions Cpp2IL/Analysis/Actions/GlobalMethodRefToConstantAction.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
using Cpp2IL.Analysis.ResultModels;
using System;
using System.Linq;
using Cpp2IL.Analysis.ResultModels;
using LibCpp2IL;
using LibCpp2IL.Metadata;
using Mono.Cecil;
using SharpDisasm;
using SharpDisasm.Udis86;

namespace Cpp2IL.Analysis.Actions
{
public class GlobalMethodRefToConstantAction : BaseAction
{
public GlobalIdentifier GlobalRead;
public MethodDefinition ResolvedMethod;
public Il2CppMethodDefinition? MethodData;
public MethodDefinition? ResolvedMethod;
public ConstantDefinition ConstantWritten;

public GlobalMethodRefToConstantAction(MethodAnalysis context, Instruction instruction) : base(context, instruction)
{
var globalAddress = context.MethodStart + LibCpp2ILUtils.GetOffsetFromMemoryAccess(instruction, instruction.Operands[1]);
MethodData = LibCpp2IlMain.GetMethodDefinitionByGlobalAddress(globalAddress);
var (type, genericParams) = Utils.TryLookupTypeDefByName(MethodData!.DeclaringType.FullName);
ResolvedMethod = type.Methods.FirstOrDefault(m => m.Name == MethodData.Name);

if (ResolvedMethod == null) return;

var destReg = instruction.Operands[0].Type == ud_type.UD_OP_REG ? Utils.GetRegisterName(instruction.Operands[0]) : null;
var name = ResolvedMethod.Name;

ConstantWritten = context.MakeConstant(typeof(MethodDefinition), ResolvedMethod, name, destReg);
}

public override Mono.Cecil.Cil.Instruction[] ToILInstructions()
Expand All @@ -27,7 +42,7 @@ public override string ToPsuedoCode()

public override string ToTextSummary()
{
throw new System.NotImplementedException();
return $"Loads the type definition for managed method {ResolvedMethod!.FullName} as a constant \"{ConstantWritten.Name}\"";
}
}
}
14 changes: 11 additions & 3 deletions Cpp2IL/Analysis/Actions/GlobalStringRefToConstantAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,25 @@
using LibCpp2IL;
using Mono.Cecil;
using SharpDisasm;
using SharpDisasm.Udis86;

namespace Cpp2IL.Analysis.Actions
{
public class GlobalStringRefToConstantAction : BaseAction
{
public GlobalIdentifier GlobalRead;
public string ResolvedString;
public string? ResolvedString;
public ConstantDefinition ConstantWritten;

public GlobalStringRefToConstantAction(MethodAnalysis context, Instruction instruction) : base(context, instruction)
{
var globalAddress = context.MethodStart + LibCpp2ILUtils.GetOffsetFromMemoryAccess(instruction, instruction.Operands[1]);
ResolvedString = LibCpp2IlMain.GetLiteralByAddress(globalAddress);

if (ResolvedString == null) return;

var destReg = instruction.Operands[0].Type == ud_type.UD_OP_REG ? Utils.GetRegisterName(instruction.Operands[0]) : null;

ConstantWritten = context.MakeConstant(typeof(string), ResolvedString, null, destReg);
}

public override Mono.Cecil.Cil.Instruction[] ToILInstructions()
Expand All @@ -27,7 +35,7 @@ public override string ToPsuedoCode()

public override string ToTextSummary()
{
throw new System.NotImplementedException();
return $"Loads the string literal \"{ResolvedString}\" as a constant \"{ConstantWritten.Name}\"";
}
}
}
6 changes: 3 additions & 3 deletions Cpp2IL/Analysis/Actions/GlobalTypeRefToConstantAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ public class GlobalTypeRefToConstantAction : BaseAction
public GlobalTypeRefToConstantAction(MethodAnalysis context, Instruction instruction) : base(context, instruction)
{
var globalAddress = context.MethodStart + LibCpp2ILUtils.GetOffsetFromMemoryAccess(instruction, instruction.Operands[1]);
GlobalRead = SharedState.GlobalsByOffset[globalAddress];
var (type, genericParams) = Utils.TryLookupTypeDefByName(GlobalRead.Name);
var typeData = LibCpp2IlMain.GetTypeGlobalByAddress(globalAddress);
var (type, genericParams) = Utils.TryLookupTypeDefByName(typeData!.ToString());
ResolvedType = type;

if (ResolvedType == null) return;
Expand All @@ -40,7 +40,7 @@ public override string ToPsuedoCode()

public override string ToTextSummary()
{
return $"Loads the type definition for managed type {ResolvedType?.FullName} as a constant \"{ConstantWritten.Name}\"";
return $"Loads the type definition for managed type {ResolvedType.FullName} as a constant \"{ConstantWritten.Name}\"";
}
}
}
15 changes: 14 additions & 1 deletion LibCpp2IL/GlobalIdentifier.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
namespace LibCpp2IL
using LibCpp2IL.Metadata;
using LibCpp2IL.Reflection;

namespace LibCpp2IL
{
public struct GlobalIdentifier
{
Expand All @@ -12,6 +15,16 @@ public override string ToString()
return $"LibCpp2IL Global Identifier (Name = {Name}, Offset = 0x{Offset:X}, Type = {IdentifierType})";
}

public Il2CppFieldDefinition? ReferencedField => IdentifierType != Type.FIELDREF ? null
: Value is Il2CppFieldDefinition def ? def : null;

public Il2CppTypeReflectionData? ReferencedType => IdentifierType != Type.TYPEREF ? null
: Value is Il2CppTypeReflectionData data ? data : null;

public Il2CppMethodDefinition? ReferencedMethod => IdentifierType != Type.METHODREF ? null
: Value is Il2CppGlobalGenericMethodRef genericMethodRef ? genericMethodRef.baseMethod //TODO Can we get a specific generic variant?
: Value is Il2CppMethodDefinition definition ? definition : null;

public enum Type
{
TYPEREF,
Expand Down
28 changes: 3 additions & 25 deletions LibCpp2IL/LibCpp2IlMain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,7 @@ public class LibCpp2IlSettings
var typeGlobal = LibCpp2IlGlobalMapper.TypeRefs.FirstOrDefault(lit => lit.Offset == address);
if (typeGlobal.Offset != address) return null;

if (typeGlobal.Value is Il2CppTypeReflectionData reflectionData)
{
return reflectionData;
}

return null;
return typeGlobal.ReferencedType;
}

public static Il2CppFieldDefinition? GetFieldGlobalByAddress(ulong address)
Expand All @@ -46,12 +41,7 @@ public class LibCpp2IlSettings
var typeGlobal = LibCpp2IlGlobalMapper.FieldRefs.FirstOrDefault(lit => lit.Offset == address);
if (typeGlobal.Offset != address) return null;

if (typeGlobal.Value is Il2CppFieldDefinition fieldDefinition)
{
return fieldDefinition;
}

return null;
return typeGlobal.ReferencedField;
}

public static GlobalIdentifier? GetMethodGlobalByAddress(ulong address)
Expand All @@ -70,19 +60,7 @@ public class LibCpp2IlSettings

if (global.Value.Offset != address) return null;

if (global.Value.Value is Il2CppGlobalGenericMethodRef genericMethodRef)
{
//TODO: This isn't quite right, there should be a way to get the specific generic reference here for specific method pointers.
return genericMethodRef.baseMethod;
}

if (global.Value.Value is Il2CppMethodDefinition methodDefinition)
{
return methodDefinition;
}

//Nasty fallback but we shouldn't ever get here.
return TheMetadata!.methodDefs.FirstOrDefault(type => type.GlobalKey == global.Value.Name);
return global.Value.ReferencedMethod;
}

/// <summary>
Expand Down

0 comments on commit b630789

Please sign in to comment.