internal static IEnumerable <XrefInstance> XrefScanImpl(Decoder decoder, bool skipClassCheck = false) { while (true) { decoder.Decode(out var instruction); if (decoder.LastError == DecoderError.NoMoreBytes) { yield break; } if (instruction.FlowControl == FlowControl.Return) { yield break; } if (instruction.Mnemonic == Mnemonic.Int || instruction.Mnemonic == Mnemonic.Int1) { yield break; } if (instruction.Mnemonic == Mnemonic.Call || instruction.Mnemonic == Mnemonic.Jmp) { var targetAddress = ExtractTargetAddress(instruction); if (targetAddress != 0) { yield return(new XrefInstance(XrefType.Method, (IntPtr)targetAddress, (IntPtr)instruction.IP)); } continue; } if (instruction.FlowControl == FlowControl.UnconditionalBranch) { continue; } if (IsMoveMnemonic(instruction.Mnemonic)) { XrefInstance?result = null; try { if (instruction.Op1Kind == OpKind.Memory && instruction.IsIPRelativeMemoryOperand) { var movTarget = (IntPtr)instruction.IPRelativeMemoryAddress; if (instruction.MemorySize != MemorySize.UInt64) { continue; } if (skipClassCheck || XrefGlobalClassFilter(movTarget)) { result = new XrefInstance(XrefType.Global, movTarget, (IntPtr)instruction.IP); } } } catch (Exception ex) { LogSupport.Error(ex.ToString()); } if (result != null) { yield return(result.Value); } } } }
internal static IEnumerable <XrefInstance> XrefScanImpl(Decoder decoder) { while (true) { decoder.Decode(out var instruction); if (decoder.InvalidNoMoreBytes) { yield break; } if (instruction.FlowControl == FlowControl.Return) { yield break; } if (instruction.Mnemonic == Mnemonic.Int || instruction.Mnemonic == Mnemonic.Int1) { yield break; } if (instruction.Mnemonic == Mnemonic.Call || instruction.Mnemonic == Mnemonic.Jmp) { var targetAddress = ExtractTargetAddress(instruction); if (targetAddress != 0) { yield return(new XrefInstance(XrefType.Method, (IntPtr)targetAddress)); } continue; } if (instruction.FlowControl == FlowControl.UnconditionalBranch) { continue; } if (instruction.Mnemonic == Mnemonic.Mov) { XrefInstance?result = null; try { if (instruction.Op1Kind == OpKind.Memory && instruction.IsIPRelativeMemoryOperand) { var movTarget = (IntPtr)instruction.IPRelativeMemoryAddress; if (instruction.MemorySize != MemorySize.UInt64) { continue; } var valueAtMov = (IntPtr)Marshal.ReadInt64(movTarget); if (valueAtMov != IntPtr.Zero) { var targetClass = (IntPtr)Marshal.ReadInt64(valueAtMov); if (targetClass == Il2CppClassPointerStore <string> .NativeClassPtr || targetClass == Il2CppClassPointerStore <Type> .NativeClassPtr) { result = new XrefInstance(XrefType.Global, movTarget); } } } } catch (Exception ex) { LogSupport.Error(ex.ToString()); } if (result != null) { yield return(result.Value); } } } }