Last active
June 9, 2026 06:52
-
-
Save sgtvcamera/b3e2f16e3b7c4c0c679b303b780afb7b to your computer and use it in GitHub Desktop.
Тест взлома памяти на с++
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #define _CRT_SECURE_NO_WARNINGS // Отключаем предупреждения безопасности Windows | |
| #include <iostream> | |
| #include <cstring> | |
| #include <clocale> // Подключаем библиотеку для работы с локалью | |
| struct MemoryTest { | |
| char name[4]; // Выделили ровно 4 байта под имя (например: 'T', 'o', 'm', '\0') | |
| int secret_code; // Сразу за именем в памяти лежит секретный код (число) | |
| }; | |
| int main() { | |
| setlocale(LC_ALL, "Russian"); | |
| MemoryTest test; | |
| // 1. Задаем начальные значения | |
| test.secret_code = 7777; | |
| // Копируем безопасное короткое имя "Tom" (3 буквы + нуль-терминатор = 4 байта) | |
| strcpy(test.name, "Tom"); | |
| std::cout << "--- ДО ПЕРЕПОЛНЕНИЯ ---" << std::endl; | |
| std::cout << "Имя: " << test.name << std::endl; | |
| std::cout << "Секретный код: " << test.secret_code << std::endl; | |
| std::cout << "-----------------------" << std::endl << std::endl; | |
| // 2. А теперь творим хаос. Записываем имя, которое явно больше 4 байт. | |
| // Функция strcpy не знает границ и пойдет писать дальше по адресам памяти! | |
| strcpy(test.name, "SuperCat"); | |
| std::cout << "--- ПОСЛЕ ПЕРЕПОЛНЕНИЯ ---" << std::endl; | |
| std::cout << "Имя: " << test.name << std::endl; | |
| std::cout << "Секретный код: " << test.secret_code << " (ОЙ! Код испорчен!)" << std::endl; | |
| std::cout << "--------------------------" << std::endl; | |
| return 0; | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Может ли строка залезть на ячейку памяти другой переменной?
Да, может, и это одна из самых классических, опасных и коварных ошибок в C++, которая называется переполнением буфера (Buffer Overflow).
В языках вроде Java, C# или Python за памятью строго следит виртуальная машина. Если ты попытаешься записать в строку больше символов, чем под неё выделено, программа просто выкинет безопасную ошибку.
Но C++ — это язык максимальной свободы и прямого доступа к железу. Компилятор C++ свято верит, что программист — взрослый человек и точно знает, что делает. Он не проверяет границы массивов и строк во время работы программы ради максимальной скорости.
Как это происходит под капотом (Наглядный пример)
Давай вернемся к нашему коту с картинки и немного упростим схему для наглядности. Допустим, мы выделили под имя кота фиксированный массив из 4 ячеек (байт), а сразу же за ним в памяти компилятор положил переменную веса weight.
В памяти они легли ровно друг за другом:
[ Ячейка 1 ] [ Ячейка 2 ] [ Ячейка 3 ] [ Ячейка 4 ] | [ Ячейка 5 ] [ Ячейка 6 ] ...
(имя) (имя) (имя) (имя) | (переменная weight)
Ты записываешь туда имя "Том". Оно занимает 3 байта + 1 байт на невидимый маркер конца строки \0. Всё поместилось идеально.
Но вдруг ты решаешь переименовать кота в "Константин".
Программа послушно берет адрес первой ячейки и начинает поочередно записывать буквы: К, о, н, с... На четвертой ячейке выделенное
место под имя заканчивается.
Что делает C++? Он не останавливается. Он просто идет дальше по физическим адресам памяти и пишет букву т в 5-ю ячейку, букву
а — в 6-ю и так далее.
Результат катастрофы:
Буквы "тантин" физически затерли те байты, где хранилось число веса weight.
Теперь, если ты попытаешься узнать вес кота, вместо условных 5.5 кг программа выдаст абсолютно случайное,
гигантское или бредовое число, потому что двоичный код букв испортил двоичный код числа.
Чем это грозит?
В зависимости от того, куда именно «залезет» строка, последствия могут быть трех уровней:
Глюки и порча данных (как в примере выше): Программа продолжает работать, но переменные вокруг начинают жить своей безумной жизнью.
Искать такие баги — сущий ад.
Аварийное завершение (Segmentation Fault): Если строка залезет слишком далеко и попытается переписать память, которая принадлежит
операционной системе или другой программе, ОС жестко пристрелит твой процесс. Для сисадмина это выглядит как внезапный вылет программы
с кодом ошибки 139 в Linux.
Дыра в безопасности (Хакерский взлом): Именно через этот механизм совершается огромная часть хакерских атак. Хакер специально подает на
вход программе строку безумной длины. Эта строка затирает переменные, добирается до системных команд процессора и подменяет адрес
возврата функции на адрес вируса. Программа начинает выполнять код хакера.
Далее - маленькая программка, которая демонстрирует этот процесс