Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Il2CppInterop.Common/XrefScans/XrefScanUtilFinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public static IntPtr FindLastRcxReadAddressBeforeCallTo(IntPtr codeStart, IntPtr
if (instruction.Op0Kind == OpKind.Register && instruction.Op0Register == Register.ECX &&
instruction.Op1Kind == OpKind.Memory && instruction.IsIPRelativeMemoryOperand)
{
var movTarget = (IntPtr)instruction.IPRelativeMemoryAddress;
var movTarget = new IntPtr(unchecked((long)instruction.IPRelativeMemoryAddress));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this fix the problem?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly. Why does this not throw too?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It converts the ulong to a long with unchecked wrapping, then creates a new IntPtr

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/checked-and-unchecked

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only ways I see that not throwing is either:

  • The ulong value is less than or equal to int.MaxValue.
  • The ulong value is greater than ulong.MaxValue + int.MinValue.

Is it guaranteed to be in these ranges?

Copy link
Author

@Dustin21335 Dustin21335 Jul 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yea your right I apologize. I believe this would work without throwing

IntPtr movTarget;

if (Environment.Is64BitProcess) movTarget = address <= long.MaxValue ? new IntPtr((long)address) : new IntPtr(unchecked((long)address)); 
else movTarget = address <= int.MaxValue ? new IntPtr((int)address) : new IntPtr(unchecked((int)address));

if (instruction.MemorySize != MemorySize.UInt32 && instruction.MemorySize != MemorySize.Int32)
continue;

Expand Down Expand Up @@ -72,7 +72,7 @@ public static IntPtr FindByteWriteTargetRightAfterCallTo(IntPtr codeStart, IntPt
if (instruction.Mnemonic == Mnemonic.Mov && seenCall)
if (instruction.Op0Kind == OpKind.Memory && (instruction.MemorySize == MemorySize.Int8 ||
instruction.MemorySize == MemorySize.UInt8))
return (IntPtr)instruction.IPRelativeMemoryAddress;
return new IntPtr(unchecked((long)instruction.IPRelativeMemoryAddress));
}
}

Expand Down
Loading