Отчет Л2
.docxСанкт-Петербургский политехнический университет Петра Великого
Институт компьютерных наук и технологий
Высшая школа интеллектуальных систем и суперкомпьютерных технологий
ЛАБОРАТОРНАЯ РАБОТА №2
«Защита программ от несанкционированной эксплуатации
за счёт привязки к носителю информации»
по дисциплине «Информационная безопасность»
Выполнил
студент гр. 3530903/80001 А. В. Шильникова
Руководитель А. В. Сергеев
«___» __________ 2021 г.
Санкт-Петербург
2021
Цель работы: получить навыки по установке защиты на разрабатываемые программы за счёт привязки к носителю информации (устройству внешней памяти).
1. Назначение программного продукта.
Программный продукт выводит основную информацию о накопителях.
2. Описание способа скрытия информации о серийном номере.
Серийный номер хранится в двух файлах разных расширений (dll, log). Один файл хранится в корневой папке, второй в папке bin. Файлы имеют бессмысленные названия. Серийный номер зашифрован.
3. Какие методы защиты от взлома использовались.
Серийный номер хранится в двух файлах в зашифрованном виде.
В коде присутствуют ложные функции расшифровки и проверки.
Названия переменных и функций либо случайны, либо имеют иное значение.
Результаты проверок не хранятся в переменных.
Пути к файлам указаны в кодировке Base64.
4. Какие алгоритмы шифрования использовались.
Серийный номер зашифрован с помощью сдвига по коду символа на 33 (цифры становятся заглавными буквами).
5. Код программы с комментариями.
Основная программа:
using System; using System.Collections.Generic; using System.IO; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; namespace Lab2_InfoBez { public partial class Form1 : Form { [DllImport("Kernel32.dll", SetLastError = true)] static extern bool GetVolumeInformation(string vol, StringBuilder name, int nameSize, out uint serialNum, out uint maxNameLen, out uint flags, StringBuilder fileSysName, int fileSysNameSize); [DllImport("Kernel32.dll", SetLastError = true)] static extern bool GetDiskFreeSpace(string lpRootPathName, out int lpSectorsPerCluster, out int lpBytesPerSector, out int lpNumberOfFreeClusters, out int lpTotalNumberOfClusters); static List<Volume> VolumeList = new(); static string[] vars = { "YmluXFxwZnRycy5kbGw=", "cGxvamsubG9n" }; static string r = Path.GetPathRoot(Environment.CurrentDirectory); static bool fileSys, serialNum = true; private uint fileSystem; //функция для чтения из файлов с серийным номером private static string Change(string to) { string res = ""; using (StreamReader sr = new StreamReader(to)) res += sr.ReadToEnd(); return res; } //функция для расшифровки путей к файлам с серийным номером private static string GetClusters(string s) { byte[] d = Convert.FromBase64String(s); return Encoding.UTF8.GetString(d); } //ложная функция для расшифровки серийного номера private static string GetSer() { string serNum = ""; string ser1 = Change(GetClusters(vars[1])); string ser2 = Change(GetClusters(vars[0])); serNum = ser1 + ser2; string result = ""; for (int i = 0; i < serNum.Length; i++) result += Convert.ToChar(Math.Abs(Convert.ToInt32(serNum[i]) - 33)); return result; } //ложная функция проверки серийного номера private static bool ChSerial(string s) { string result = ""; uint serialNumber, maxNameLen, flags; int sectorsPerCluster, bytesPerSector, numberOfFreeClusters, totalNumberOfClusters; string rootPath = r; StringBuilder a = new StringBuilder(), name = new StringBuilder(); GetVolumeInformation(rootPath, name, 100, out serialNumber, out maxNameLen, out flags, a, 100); GetDiskFreeSpace(rootPath, out sectorsPerCluster, out bytesPerSector, out numberOfFreeClusters, out totalNumberOfClusters); var serialN = serialNumber.ToString(); for (int i = 0; i < s.Length; i++) result += Convert.ToChar(Math.Abs(Convert.ToInt32(s[i]) - 30)); return serialN != result; } public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { uint maxNameLen2, flags2; string serial; StringBuilder a2 = new StringBuilder(), name2 = new StringBuilder(); GetVolumeInformation(r, name2, 100, out fileSystem, out maxNameLen2, out flags2, a2, 100); r = ByteNum(); if (r == fileSystem.ToString() && ChSerial(GetSer())) { DriveInfo[] allDrives = DriveInfo.GetDrives(); foreach (DriveInfo d in allDrives) { if (d.DriveType.ToString() != "CDRom") { comboBox1.Items.Add(d.Name); uint serialNumber, maxNameLen, flags; int sectorsPerCluster, bytesPerSector, numberOfFreeClusters, totalNumberOfClusters; string rootPath = d.Name; StringBuilder a = new StringBuilder(), name = new StringBuilder(); GetVolumeInformation(rootPath, name, 100, out serialNumber, out maxNameLen, out flags, a, 100); GetDiskFreeSpace(rootPath, out sectorsPerCluster, out bytesPerSector, out numberOfFreeClusters, out totalNumberOfClusters); var serialN = serialNumber.ToString(); var clusters = sectorsPerCluster.ToString(); var bytesPerSec = bytesPerSector.ToString(); VolumeList.Add(new Volume(d.Name, d.VolumeLabel, serialN, d.DriveFormat, clusters, bytesPerSec)); } } } else { comboBox1.Enabled = false; textBox1.Visible = true; } } //функция для расшифровки серийного номера private static string ByteNum() { string byteNum = ""; string n1 = Change(GetClusters(vars[0])); string n2 = Change(GetClusters(vars[1])); byteNum = n1 + n2; string result = ""; for (int i = 0; i < byteNum.Length; i++) result += Convert.ToChar(Math.Abs(Convert.ToInt32(byteNum[i]) - 33)); return result; } private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { string name = comboBox1.SelectedItem.ToString(); foreach (var v in VolumeList) { if (v.Name == name) { label1.Text = "Метка тома:" + v.Metka; label2.Text = "Серийный номер:" + v.SerialNum; label3.Text = "Имя файловой системы:" + v.FileSys; label4.Text = "Количество секторов в кластере:" + v.SectorPerClus; label5.Text = "Количество байт в секторе:" + v.BytePerSector; } } } } }
Программа установщика:
using System; using System.IO; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; namespace Laba2_Installer { public partial class Form1 : Form { private string finalPath; public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { FolderBrowserDialog folderBrowserDialog1 = new FolderBrowserDialog(); if (folderBrowserDialog1.ShowDialog() == DialogResult.OK) { textBox1.Text = folderBrowserDialog1.SelectedPath; } } [DllImport("Kernel32.dll", SetLastError = true)] extern static bool GetVolumeInformation(string vol, StringBuilder name, int nameSize, out uint serialNum, out uint maxNameLen, out uint flags, StringBuilder fileSysName, int fileSysNameSize); private static void AddFiles(string path) { File.Copy("Programm.exe", path + "\\Programm.exe"); Directory.CreateDirectory(path + "\\bin"); uint serialNum, maxNameLen, flags; string rootPath = path.Substring(0, path.IndexOf(":\\") + 2); StringBuilder a = new StringBuilder(), name = new StringBuilder(); GetVolumeInformation(rootPath, name, 100, out serialNum, out maxNameLen, out flags, a, 100); string serial = serialNum.ToString(); string result = ""; for (int i = 0; i < serial.Length; i++) result += Convert.ToChar(Math.Abs(Convert.ToInt32(serial[i]) + 33)); using (StreamWriter sw = new StreamWriter(path + "\\bin\\pftrs.dll", false, Encoding.UTF8)) sw.Write(result.Substring(0, 5)); using (StreamWriter sw = new StreamWriter(path + "\\plojk.log", false, Encoding.UTF8)) sw.Write(result.Substring(5, serial.Length - 5)); } private void button2_Click(object sender, EventArgs e) { finalPath = textBox1.Text; AddFiles(finalPath); Close(); } } }
6. Выводы и рекомендации по дальнейшему усовершенствованию методов защиты программного продукта.
В результате лабораторной работы была создана программа с защитой от нелицензионного использования путём привязки к накопителю.
Для усовершенствования программного продукта можно использовать более сложные алгоритмы шифрования, использовать несколько алгоритмов хранения контрольных данных, увеличить число файлов, в которых кодируется серийный номер диска, хранить код проверки и расшифрования в скрытых отдельных файлах.
7. Список литературы и ссылок на статьи.
https://docs.microsoft.com/ru-ru/dotnet/api/system.io.driveinfo?view=net-6.0
https://www.pinvoke.net/default.aspx/kernel32.getvolumeinformation
https://www.pinvoke.net/default.aspx/kernel32.getdiskfreespace