Skip to content

Commit aac5831

Browse files
authored
Unstrip Exception Handlers (#157)
* Unstrip Exception Handlers * Handle ExceptionType more strictly
1 parent 2f73813 commit aac5831

File tree

1 file changed

+81
-2
lines changed

1 file changed

+81
-2
lines changed

Il2CppInterop.Generator/Utils/UnstripTranslator.cs

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using AsmResolver.DotNet.Collections;
55
using AsmResolver.DotNet.Signatures;
66
using AsmResolver.PE.DotNet.Cil;
7+
using AsmResolver.PE.DotNet.Metadata.Tables;
78
using Il2CppInterop.Generator.Contexts;
89
using Il2CppInterop.Generator.Extensions;
910
using Il2CppInterop.Generator.Passes;
@@ -341,13 +342,91 @@ public static bool TranslateMethod(MethodDefinition original, MethodDefinition t
341342
newLabel.Instruction = instructionMap[oldLabel.Instruction!];
342343
}
343344

345+
// Copy exception handlers
346+
foreach (var exceptionHandler in original.CilMethodBody.ExceptionHandlers)
347+
{
348+
var newExceptionHandler = new CilExceptionHandler
349+
{
350+
HandlerType = exceptionHandler.HandlerType
351+
};
352+
353+
switch (exceptionHandler.TryStart)
354+
{
355+
case null:
356+
break;
357+
case CilInstructionLabel { Instruction: not null } tryStart:
358+
newExceptionHandler.TryStart = new CilInstructionLabel(instructionMap[tryStart.Instruction]);
359+
break;
360+
default:
361+
return false;
362+
}
363+
364+
switch (exceptionHandler.TryEnd)
365+
{
366+
case null:
367+
break;
368+
case CilInstructionLabel { Instruction: not null } tryEnd:
369+
newExceptionHandler.TryEnd = new CilInstructionLabel(instructionMap[tryEnd.Instruction]);
370+
break;
371+
default:
372+
return false;
373+
}
374+
375+
switch (exceptionHandler.HandlerStart)
376+
{
377+
case null:
378+
break;
379+
case CilInstructionLabel { Instruction: not null } handlerStart:
380+
newExceptionHandler.HandlerStart = new CilInstructionLabel(instructionMap[handlerStart.Instruction]);
381+
break;
382+
default:
383+
return false;
384+
}
385+
386+
switch (exceptionHandler.HandlerEnd)
387+
{
388+
case null:
389+
break;
390+
case CilInstructionLabel { Instruction: not null } handlerEnd:
391+
newExceptionHandler.HandlerEnd = new CilInstructionLabel(instructionMap[handlerEnd.Instruction]);
392+
break;
393+
default:
394+
return false;
395+
}
396+
397+
switch (exceptionHandler.FilterStart)
398+
{
399+
case null:
400+
break;
401+
case CilInstructionLabel { Instruction: not null } filterStart:
402+
newExceptionHandler.FilterStart = new CilInstructionLabel(instructionMap[filterStart.Instruction]);
403+
break;
404+
default:
405+
return false;
406+
}
407+
408+
switch (exceptionHandler.ExceptionType?.ToTypeSignature())
409+
{
410+
case null:
411+
break;
412+
case CorLibTypeSignature { ElementType: ElementType.Object }:
413+
newExceptionHandler.ExceptionType = imports.Module.CorLibTypeFactory.Object.ToTypeDefOrRef();
414+
break;
415+
default:
416+
// In the future, we will throw exact exceptions, but we don't right now,
417+
// so attempting to catch a specific exception type will always fail.
418+
return false;
419+
}
420+
421+
target.CilMethodBody.ExceptionHandlers.Add(newExceptionHandler);
422+
}
423+
344424
return true;
345425
}
346426

347427
public static void ReplaceBodyWithException(MethodDefinition newMethod, RuntimeAssemblyReferences imports)
348428
{
349-
newMethod.CilMethodBody!.LocalVariables.Clear();
350-
newMethod.CilMethodBody.Instructions.Clear();
429+
newMethod.CilMethodBody = new(newMethod);
351430
var processor = newMethod.CilMethodBody.Instructions;
352431

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

0 commit comments

Comments
 (0)