---
title: "Смена серийного номера тома"
description: "В статье “WinAPI: Определение типа носителя и его серийного номера” я показывал простой пример как р..."
author: "huzrus"
published: "2013-02-03T09:33:07+00:00"
modified: "2013-02-03T09:33:07+00:00"
locale: "ru"
canonical_url: "https://yvision.kz/post/smena-seriynogo-nomera-toma-318274"
markdown_url: "https://yvision.kz/post/smena-seriynogo-nomera-toma-318274/markdown"
site_name: "Yvision.kz"
---

# Смена серийного номера тома

> В статье “WinAPI: Определение типа носителя и его серийного номера” я показывал простой пример как р...

В статье “WinAPI: Определение типа носителя и его серийного номера” я показывал простой пример как реализовать защиту программ путем привязки к железу. Но все бы хорошо, да только бывают моменты когда просто необходимо “отвязаться” от железки. С такой проблемой столкнулся sansan. Собственно, благодаря ему и была написана эта статья.Ну а теперь от слов к делу. Вся информация для корректной работы накопителя хранится в его загрузочной области. Нас будет интересовать используемая файловая система, от которой зависит расположения нужных байт относительно начала загрузочной области. Поэтому основная наша задача это определить тип файловой системы, и сместившись на нужный адрес переписать значение серийного номера. Всё просто ;). Изучим таблицу.Таблица:Поле/ФС FAT FAT32 NTFSМетка тома 0×2B 0×47 ?Файловая система 0×36 0×52 0×3Серийный номер 0×27 0×43 0×48В приведенной таблице показаны основные файловые системы и соответствующие для них смещения. Оперируя этой информацией мы и будем реализовывать нашу программу. На необходимо реализовать следующие функции:• DiskOpen - открыть диск• DiskClose - закрыть диск• ReadSector - прочитать сектор• WriteSector - записать секторРеализовывать нашу программу мы будем С++ под семейство Windows NT. В частности, в среде разработки С++ Builder 6. Нам понадобиться глобальная переменная, в которой будем хранить указатель на используемый диск:HANDLE hD;Начнем c описания функции DiskOpen():bool DiskOpen(char *vol){char szDrive[10];sprintf(szDrive, ".%c:", vol[0]);hD = CreateFile(szDrive,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);return hD != INVALID_HANDLE_VALUE;}Данной функции в качестве параметра передаётся буква диска, которому нужно сменить серийный номер. С помощью API-функции CreateFile(), мы получаем указатель на диск (подробней о CreateFile можно прочитать в статье “WinAPI: Работа с файлами (основные функции)“). В случае успеха возвращает “истину”, иначе - “ложь”.Далее опишем функцию DiskClose():void DiskClose(){if (hD != INVALID_HANDLE_VALUE)CloseHandle(hD);}Эта функция достаточно простая, она освобождает используемый указатель на диск.Следующая функция ReadSector():bool ReadSector (DWORD sector, char *Buffer, int sectorSize){DWORD read = 0;if (SetFilePointer(hD, sector, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)return false;if (!ReadFile(hD, Buffer, sectorSize, &read, NULL))return false;return true;}Эта функция уже посложней. Исользует 3 параметра:• первый - указатель на диск.• второй - буфер, куда будут записаны данные, считанные из загрузочной области.• третий - размер загрузочной области, а следовательно и буфера.Функция переводит указатель смещения в файле на нужную позицию с помощью API-функции SetFilePointer(), а потом с помощью ReadFile() считывает в буфер данные из загрузочной области (подробней о ReadFile() можно прочитать в статье “WinAPI: Работа с файлами (основные функции)“). В случае успеха возвращает “истину”, иначе - “ложь”.И последняя функция WriteSector():bool WriteSector(DWORD sector, char *Buffer, int sectorSize){DWORD wrote = 0;if (SetFilePointer(hD, sector, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)return false;if (!WriteFile(hD, Buffer, sectorSize, &wrote, NULL))return false;return true;}Эта функция аналогична предыдущей. Только вместо API-функции ReadFile() используется WriteFile() (подробней о WriteFile() можно прочитать в статье “WinAPI: Работа с файлами (основные функции)“). В случае успеха возвращает “истину”, иначе - “ложь”.Ну что, базовые функции мы реализовали, пора приступить и к завершающей стадии. Скинем на форму 1 кнопку, 1 поле ввода (сюда будем вводить новый серийный номер), и 1 ComboBox (определим выбор основных букв дисков). И для кнопки опишем следующий код:void __fastcall TForm1::Button1Click(TObject *Sender){//проверяем не пусты ли необходимые поляif ((ComboBox1->Text !="") && (Edit1->Text !="")){DWORD newSerial = StrToInt(Edit1->Text);const max_pbsi = 3;//определяем структуру для сигнатуры загрузочной областиstruct partial_boot_sector_info{LPSTR Fs; // название файловой системыDWORD FsOffs; // смещение системного имени в загрузочной областиDWORD SerialOffs; // смещение серийного номера в загрузочной области};//описываем часто используемые сигнатурыpartial_boot_sector_info pbsi[max_pbsi] ={{"FAT32", 0x52, 0x43},{"FAT", 0x36, 0x27},{"NTFS", 0x03, 0x48}};//инициализируем необходимые переменныеTCHAR Drive[12]={0};char Sector[512];DWORD i;sprintf(Drive, "%s:", ComboBox1->Text);//открываем дискif (!DiskOpen(Drive)){//если ошибка оповещаем пользователя и выходим из процелурыApplication->MessageBoxA("Невозможно открыть диск!","Ошибка");return;}// читаем загрузочную областьif (!ReadSector(0, Sector,512)){Application->MessageBoxA("Невозможно считать данные","Ошибка");return;}// посик сигнатуры загрузочной областиfor (i=0;i= max_pbsi){Application->MessageBoxA("Невозможно сменить номер для этой файловой системы!","Ошибка");return;}// меняем номер*(PDWORD)(Sector+pbsi[i].SerialOffs) = newSerial;// записываем в загрузочную областьif (!WriteSector(0, Sector,512)){Application->MessageBoxA("Невозможно записать на диск!","Ошибка");return;}DiskClose();Application->MessageBoxA("Серийный номер успешно изменен! Необходимо перезагрзить компьютер.","Внимание");}elseApplication->MessageBoxA("Не указан диск или серийный номер!","Внимание");}Если Вы меняете серийный номер тома флешки, то компьютер перезагружать не обязательно, достаточно отключить и заново подключить флешку. В других случаях результат буде виден только после перезагрузки. На этом всё, замечания и вопросы можете высказать на форуме. Спасибо за внимание! ;)Рабочий пример скачать (http://depositfiles.com/files/3vg3psz21).Рекомендуемые статьи для прочтения:WinAPI: Работа с файлами (основные функции).WinAPI: Определение типа носителя и его серийного номера.

**[Обучение взлому и программированию](http://itblogs.org/)**

---

Source: [https://yvision.kz/post/smena-seriynogo-nomera-toma-318274](https://yvision.kz/post/smena-seriynogo-nomera-toma-318274)