Skip to content

Commit

Permalink
Unstrip Exception Handlers (#157)
Browse files Browse the repository at this point in the history
* Unstrip Exception Handlers

* Handle ExceptionType more strictly
  • Loading branch information
ds5678 authored Sep 15, 2024
1 parent 2f73813 commit aac5831
Showing 1 changed file with 81 additions and 2 deletions.
83 changes: 81 additions & 2 deletions Il2CppInterop.Generator/Utils/UnstripTranslator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using AsmResolver.DotNet.Collections;
using AsmResolver.DotNet.Signatures;
using AsmResolver.PE.DotNet.Cil;
using AsmResolver.PE.DotNet.Metadata.Tables;
using Il2CppInterop.Generator.Contexts;
using Il2CppInterop.Generator.Extensions;
using Il2CppInterop.Generator.Passes;
Expand Down Expand Up @@ -341,13 +342,91 @@ public static bool TranslateMethod(MethodDefinition original, MethodDefinition t
newLabel.Instruction = instructionMap[oldLabel.Instruction!];
}

// Copy exception handlers
foreach (var exceptionHandler in original.CilMethodBody.ExceptionHandlers)
{
var newExceptionHandler = new CilExceptionHandler
{
HandlerType = exceptionHandler.HandlerType
};

switch (exceptionHandler.TryStart)
{
case null:
break;
case CilInstructionLabel { Instruction: not null } tryStart:
newExceptionHandler.TryStart = new CilInstructionLabel(instructionMap[tryStart.Instruction]);
break;
default:
return false;
}

switch (exceptionHandler.TryEnd)
{
case null:
break;
case CilInstructionLabel { Instruction: not null } tryEnd:
newExceptionHandler.TryEnd = new CilInstructionLabel(instructionMap[tryEnd.Instruction]);
break;
default:
return false;
}

switch (exceptionHandler.HandlerStart)
{
case null:
break;
case CilInstructionLabel { Instruction: not null } handlerStart:
newExceptionHandler.HandlerStart = new CilInstructionLabel(instructionMap[handlerStart.Instruction]);
break;
default:
return false;
}

switch (exceptionHandler.HandlerEnd)
{
case null:
break;
case CilInstructionLabel { Instruction: not null } handlerEnd:
newExceptionHandler.HandlerEnd = new CilInstructionLabel(instructionMap[handlerEnd.Instruction]);
break;
default:
return false;
}

switch (exceptionHandler.FilterStart)
{
case null:
break;
case CilInstructionLabel { Instruction: not null } filterStart:
newExceptionHandler.FilterStart = new CilInstructionLabel(instructionMap[filterStart.Instruction]);
break;
default:
return false;
}

switch (exceptionHandler.ExceptionType?.ToTypeSignature())
{
case null:
break;
case CorLibTypeSignature { ElementType: ElementType.Object }:
newExceptionHandler.ExceptionType = imports.Module.CorLibTypeFactory.Object.ToTypeDefOrRef();
break;
default:
// In the future, we will throw exact exceptions, but we don't right now,
// so attempting to catch a specific exception type will always fail.
return false;
}

target.CilMethodBody.ExceptionHandlers.Add(newExceptionHandler);
}

return true;
}

public static void ReplaceBodyWithException(MethodDefinition newMethod, RuntimeAssemblyReferences imports)
{
newMethod.CilMethodBody!.LocalVariables.Clear();
newMethod.CilMethodBody.Instructions.Clear();
newMethod.CilMethodBody = new(newMethod);
var processor = newMethod.CilMethodBody.Instructions;

processor.Add(OpCodes.Ldstr, "Method unstripping failed");
Expand Down

0 comments on commit aac5831

Please sign in to comment.