private IDebugBreakpoint2 CreateBreakpointForPattern(byte[] progModuleMemory, string searchPattern, string name)
        {
            (byte[] searchPatternBytes, byte[] searchPatternWildcardBytes) = ParseSearchPattern(searchPattern);

            IntPtr codeAddress;

            fixed(
                void *progModuleMemoryPtr = progModuleMemory,
                searchPatternPtr          = searchPatternBytes,
                wildcardPtr = searchPatternWildcardBytes
                )
            {
                ulong codeOffset =
                    IndexOfUnchecked(
                        progModuleMemoryPtr,
                        (ulong)progModuleMemory.LongLength,
                        searchPatternPtr,
                        (ulong)searchPatternBytes.LongLength,
                        wildcardPtr
                        );

                Control.OutputWide(
                    DEBUG_OUTPUT.NORMAL,
                    $"{name} offset: 0x{codeOffset:X8}\r\n"
                    );
                if (codeOffset == ulong.MaxValue)
                {
                    Control.OutputWide(DEBUG_OUTPUT.ERROR, "Dumping prog.dll memory to prog.dll.memory");
                    File.WriteAllBytes("prog.dll.memory", progModuleMemory);
                    throw new Exception($"Pattern '{searchPattern}' not found for function {name}!");
                }

                codeAddress = new IntPtr((long)(codeOffset + (ulong)GameProgModule.BaseAddress));
            }

            Control.OutputWide(
                DEBUG_OUTPUT.NORMAL,
                $"{name} address: {codeAddress.FormatAsHex()}\n"
                );

            Control.AddBreakpoint2(DEBUG_BREAKPOINT_TYPE.CODE, uint.MaxValue, out IDebugBreakpoint2 breakpoint);
            breakpoint.SetOffset((ulong)codeAddress);
            breakpoint.SetFlags(DEBUG_BREAKPOINT_FLAG.ENABLED);
            //breakpoint.SetCommandWide(".echo Entered " + name);

            return(breakpoint);
        }