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);
                    }
                }
            }
        }
示例#2
0
        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);
                    }
                }
            }
        }