Перейти к содержанию

C# ошибка "Индекс находился вне границы массива"


Рекомендуемые сообщения

Всем привет
При создании тренера столкнулся с такой проблемой как: "Индекс находился вне границ массива."
Данная ошибка появляется при поиске адреса при помощи структуры.
Помогите пожалуйста
Код приведу ниже
Кто сталкивался с такой проблемой, подскажите как решить ее.
Бывает срабатывает и адрес находит, и все работает как надо
А бывает так, что когда игра только запускается и я нажимаю "активировать" то ошибка не вылетает
Но если нажать "активировать" в главном меню(когда игра запустилась полностью), то вылетает ошибка которую я указал выше

активировать - запускает FindSignature()

Спойлер

public static int FindSignature()
        {
            int[] signature = { 0xCD, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xF4, 0x3F, 0x01, 0x00, 0x00, 0x00, 0xA0, 0xB7, 0x1F, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x40 };
            


            long MaxAddress = 0x7fffffff;
            long address = 0;
            MEMORY_BASIC_INFORMATION m;
            
            var handle = OpenProcess(0x001F0FFF, false, GetProcessID());
            m.BaseAddress = IntPtr.Zero;
            m.RegionSize = IntPtr.Zero;
            byte[] buffer;

            while (address <= MaxAddress)
            {
                VirtualQueryEx(handle, (IntPtr)address, out m, (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION)));
                buffer = new byte[(uint)m.RegionSize];
                int dammy = 0;
                ReadProcessMemory(handle, m.BaseAddress, buffer, (int)m.RegionSize, out dammy);
                if (address == (long)m.BaseAddress + (long)m.RegionSize)
                    break;
                int count = 0;
                address = (long)m.BaseAddress + (long)m.RegionSize;
                if (buffer.Length > signature.Length)
                {
                    for (int i = 0; i < buffer.Length; i++)
                    {
                        if (buffer[i] == signature[0])
                        {
                            for (int q = 0; q < signature.Length; q++ )
                            {
                                if (buffer[i + q ] == signature[q] && signature[q] != -1)
                                //&& signature[q] != 0 добавить в скобку выше если что-то не так
                                {
                                    count++;
                                    if (count == signature.Length)
                                    {
                                       
                                        Func func = new Func();
                                        var result = i + (int)m.BaseAddress;
                                        func.vamaddr += result;
                                        Func.addr = result;
                                        string some = result.ToString();
                                        MessageBox.Show(result.ToString());
                                        return i + (int)m.BaseAddress;
                                    }
                                }
                                else
                                {
                                    count = 0;
                                }
                            }
                        }
                    }
                }
            }

            CloseHandle(handle);
            return -1;
        }

 

 

Ссылка на комментарий
Поделиться на другие сайты

Эта ошибка означает, что ты выходишь за границы массива где-то, как бы логично это не звучало. 
Пройдись с отладчиком по этой функции и узнаешь, где проблема. 

Ссылка на комментарий
Поделиться на другие сайты

1 час назад, KRYPTOPUNK сказал:

Эта ошибка означает, что ты выходишь за границы массива где-то, как бы логично это не звучало. 
Пройдись с отладчиком по этой функции и узнаешь, где проблема. 

а как это понимать? за границы массива ?
как тогда объяснить то, что если я перезагружу ПК, то все будет ок
 

Ссылка на комментарий
Поделиться на другие сайты

5 часов назад, Tristam123 сказал:

Помогите пожалуйста

Ты хочешь чему-то научиться или тебе просто нужно решение? Если первый вариант, то прокомментируй каждую строчку, что ты делаешь в своём коде.

Ссылка на комментарий
Поделиться на другие сайты

7 часов назад, Tristam123 сказал:

а как это понимать? за границы массива ?

Так и понимать. Если у тебя в массиве 3 элемента, а ты попробуешь взять из него 4-й, ты получишь как раз эту самую ошибку.

Ссылка на комментарий
Поделиться на другие сайты

10 часов назад, Xipho сказал:

Так и понимать. Если у тебя в массиве 3 элемента, а ты попробуешь взять из него 4-й, ты получишь как раз эту самую ошибку.

Теперь понял, спасибо.

просто как-то странно получается, бывает работает, а бывает не работает. С чем этом связано, ума не приложу 

 

15 часов назад, JustHack сказал:

Ты хочешь чему-то научиться или тебе просто нужно решение? Если первый вариант, то прокомментируй каждую строчку, что ты делаешь в своём коде.

Я понимаю как работает код и что он делает. Просто не могу побороть эту ошибку уже больше полугода. Вот и обратился за помощью 

Ссылка на комментарий
Поделиться на другие сайты

2 часа назад, Tristam123 сказал:

С чем этом связано, ума не приложу

Пошаговая отладка поможет понять, где конкретно ты за пределы массива вываливаешься.

 

2 часа назад, Tristam123 сказал:

Я понимаю как работает код и что он делает. Просто не могу побороть эту ошибку уже больше полугода.

Первое предложение не вяжется со вторым. Будь добр, процитируй свой же код, но только расставь комментарии возле каждой строки с пояснениями, что в ней делается. Возможно, в процессе ты сам увидишь ошибку. Если нет, попробуем вместе порассуждать.

Ссылка на комментарий
Поделиться на другие сайты

5 часов назад, Xipho сказал:

процитируй свой же код, но только расставь комментарии возле каждой строки с пояснениями

Спойлер

public static int FindSignature()
        {
            int[] signature = { 0xCD, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xF4, 0x3F, 0x01, 0x00, 0x00, 0x00, 0xA0, 0xB7, 0x1F, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x40 }; // наша сигнатура которую мы ищем(и  ищем адрес это сигнатуры)
            


            long MaxAddress = 0x7fffffff; // максимальный адрес где может лежать сигнатура
            long address = 0; 
            MEMORY_BASIC_INFORMATION m;
            
            var handle = OpenProcess(0x001F0FFF, false, GetProcessID()); // открываем хэндл
            m.BaseAddress = IntPtr.Zero;
            m.RegionSize = IntPtr.Zero;
            byte[] buffer; // объявление массива 

            while (address <= MaxAddress) // начинаем цикл
            {
                VirtualQueryEx(handle, (IntPtr)address, out m, (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION))); // скан региона памяти
                buffer = new byte[(uint)m.RegionSize];
                int dammy = 0;
                ReadProcessMemory(handle, m.BaseAddress, buffer, (int)m.RegionSize, out dammy); // чтение памяти
                if (address == (long)m.BaseAddress + (long)m.RegionSize)
                    break;
                int count = 0;
                address = (long)m.BaseAddress + (long)m.RegionSize;
                if (buffer.Length > signature.Length) // проверяем условие длина буфера больше длины сигнатуры
                {
                    for (int i = 0; i < buffer.Length; i++) // для i++ пока < длины буфера
                    {
                        if (buffer[i] == signature[0]) // буфер равен сигнатуре 
                        {
                            for (int q = 0; q < signature.Length; q++ ) // для q++ пока < длины сигнатуры
                            {
                                if (buffer[i + q ] == signature[q] && signature[q] != -1) // если буфер i + q равен сигнатуре[q] и сиганутра не равно -1
                                {
                                    count++;
                                    if (count == signature.Length) // если условие выполняется
                                    {
                                       
                                        Func func = new Func();
                                        var result = i + (int)m.BaseAddress; // выводим адрес сигнатуры
                                        func.vamaddr += result;
                                        Func.addr = result;
                                        string some = result.ToString();
                                        MessageBox.Show(result.ToString());
                                        return i + (int)m.BaseAddress;
                                    }
                                }
                                else // не нашли сигнатуру
                                {
                                    count = 0; // выводим 0
                                }
                            }
                        }
                    }
                }
            }

            CloseHandle(handle); // закрываем хэндл
            return -1; // в инном случае возвращаем -1
        }

 

 

Ссылка на комментарий
Поделиться на другие сайты

8 часов назад, Tristam123 сказал:

MaxAddress = 0x7fffffff; // максимальный адрес где может лежать сигнатура

Это максимальный адрес юзерспейса, а твой адрес никак не будет находиться вне диапазона

00010000-7FFEFFFF

 

Ссылка на комментарий
Поделиться на другие сайты

2 часа назад, Xipho сказал:

Отлично, а теперь подскажи, пожалуйста, в какой строчке возникает указанное тобой исключение?

if (buffer[i + q ] == signature[q] && signature[q] != -1)

 

1 час назад, JustHack сказал:

Это максимальный адрес юзерспейса, а твой адрес никак не будет находиться вне диапазона



 

Я и не сказал, что он будет лежать вне этого диапазона

Ссылка на комментарий
Поделиться на другие сайты

1 минуту назад, Xipho сказал:

Или больше буфера. Тебе осталось выяснить в пошаговой отладке, почему так происходит.

Понял, спасибо

а как объяснить то, что бывает перезапустишь компьютер, игру или сам «чит» и все работает как надо?

Ссылка на комментарий
Поделиться на другие сайты

1 минуту назад, Tristam123 сказал:

а как объяснить то, что бывает перезапустишь компьютер, игру или сам «чит» и все работает как надо?

Вот как раз в пошаговой отладке и поймешь )) 

Ссылка на комментарий
Поделиться на другие сайты

13 часов назад, Xipho сказал:

Вот как раз в пошаговой отладке и поймешь )) 

Во время отладки понял
что если q = 22
i = 124376 то все работает
но если i > этого значение(что я привел выше), вылетает эта ошибка(которую я в теме указал)
Только вот я не понимаю, откуда там цифры такие берутся...

Ссылка на комментарий
Поделиться на другие сайты

6 часов назад, Tristam123 сказал:

Только вот я не понимаю, откуда там цифры такие берутся...

Вот ты нам и скажи, откуда они такие там берутся )) Понимаешь, какая штука - я мог бы тебе сразу подсказать, но тогда это не отложится в твоей памяти, и не будет понимания. А я хочу, чтобы ты научился анализировать код, и тогда к тебе придет понимание. 

Ссылка на комментарий
Поделиться на другие сайты

Гость Сашкоу
В 28.04.2021 в 21:13, Tristam123 сказал:

long MaxAddress = 0x7fffffff;

Первая ошибка - в цикле ты используешь адрес, он должен быть на 8 байт меньше. Если коротко, то у тебя цикл выходит за границы массива, то есть при последующих итерациях получается Length.newArray > Length.oldArray.

В 28.04.2021 в 21:13, Tristam123 сказал:

for (int i = 0; i < buffer.Length; i++)

Вторая ошибка - надо "<=", так как индексация начинается с нуля, при "<" последний символ массива не будет учитываться.

 

Извиняюсь, давно не кодил, возможно, ошибаюсь.

Ссылка на комментарий
Поделиться на другие сайты

19 часов назад, Сашкоу сказал:

быть на 8 байт меньше

Это я поправил давно уже 

 

19 часов назад, Сашкоу сказал:

Вторая ошибка - надо "<=", так как индексация начинается с нуля

И это тоже поправил

после этого ошибка так и осталась

спасибо, что ответи

Думаю дальше

Ссылка на комментарий
Поделиться на другие сайты

21 час назад, Сашкоу сказал:

надо "<=", так как индексация начинается с нуля, при "<" последний символ массива не будет учитываться

Неверно. Если массив длиной в 4 элемента, что будет, когда ты попробуешь взять элемент с индексом, равным длине этого массива?

 

21 час назад, Сашкоу сказал:

в цикле ты используешь адрес, он должен быть на 8 байт меньше

И снова неверно. Ошибка не потому, что меньше на 8 байт, а потому, что последний проверяемый элемент должен быть равен длине буфера за вычетом размера сигнатуры. Чтобы при последовательной проверке не получить этот самый вылет. Именно это я и хотел, чтобы понял топикстартер. А ты его еще и в заблуждение вгоняешь.

 

Скомпенсировал необдуманный плюс от Гарика, поставив минус.

Ссылка на комментарий
Поделиться на другие сайты

2 часа назад, Xipho сказал:

необдуманный плюс от Гарика

я ставлю плюсы не за правильность, а за активность и участие,
плюс/минус ИМХО - нравится/не нравится
мне понравилось.
Тем более 

 

23 часа назад, Сашкоу сказал:

Извиняюсь, давно не кодил, возможно, ошибаюсь.

и более опытные конечно поправят.

  • Спасибо 1
Ссылка на комментарий
Поделиться на другие сайты

5 часов назад, Garik66 сказал:

я ставлю плюсы не за правильность, а за активность и участие

За активность и участие нужно ставить "Понравилось". Это не даст плюс в репутацию (незаслуженно), но даст автору понять, что его пост кому-то понравился.

Ссылка на комментарий
Поделиться на другие сайты

В 02.05.2021 в 09:46, Xipho сказал:

И снова неверно. Ошибка не потому, что меньше на 8 байт, а потому, что последний проверяемый элемент должен быть равен длине буфера за вычетом размера сигнатуры. Чтобы при последовательной проверке не получить этот самый вылет. Именно это я и хотел, чтобы понял топикстартер. А ты его еще и в заблуждение вгоняешь.

Все проблему решил
Всем спасибо за помощь
Решение было таково: "последний проверяемый элемент должен быть равен длине буфера за вычетом размера сигнатуры"
Как и сказал Xipho.
Спасибо еще раз.

Ссылка на комментарий
Поделиться на другие сайты

  • Xipho закрыл тема
Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.