Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Хочу привязаться к железу


Автор: Rapalex 29.9.2006, 16:49
Давайте все поделимся друг с другом мыслями как можно привязаться к железу и кто как это делает.

Но мой вопросс: как получить серийный номер винта (а не раздела который меняется приформатировании), или проца или оперативы?

Автор: sOckets 29.9.2006, 17:42
http://www.internals.com/ | http://www.internals.com/utilities/winnt/ntdriverlist/NtDriverList.zip
NtDriverList is a user-mode console application which takes advantage of the undocumented NtQuerySystemInformation API to obtain a list of loaded drivers under Windows NT. Source code is included !

Исходники на С++ , там WinAPI , думаю не трудно будет на дельфи переделать.

Автор: Kefir 29.9.2006, 18:18
http://rsdn.ru/forum/message.aspx?mid=905667&only=1.

Автор: mr.DUDA 30.9.2006, 11:35
Цитата(Kefir @  29.9.2006,  18:18 Найти цитируемый пост)
Тут можно посмотреть как это можно реализовать средствами .NET.

Отличие VolumeSerialNumber от серийника винта состоит в том, что первый назначается при форматировании раздела, и может совпадать на разных винтах. Второй - уникален для каждого винта, и получить его можно только с пом. утилиты аналогичной diskid32 (ссылку дал sOckets).

Автор: Kefir 30.9.2006, 12:01
mr.DUDA, я просто дал ссылку на пример получения инфы о железе smile

Автор: mr.DUDA 30.9.2006, 18:43
Цитата(Kefir @  30.9.2006,  12:01 Найти цитируемый пост)
mr.DUDA, я просто дал ссылку на пример получения инфы о железе

Ok, а я просто заметил что, к сожалению, не всё решается штатными средствами (System.Management) smile

З.Ы. подобную задачу пытаюсь решить в проекте, над которым работаю сейчас

Автор: Rapalex 11.10.2006, 16:34
Так скажите как хоть какойнибудь номер железа получить при помощи средст .NET

Автор: mr.DUDA 11.10.2006, 16:57
Можно из реестра поднять, из раздела с инфой по драйверам.

Автор: Rapalex 11.10.2006, 16:59
Цитата(mr.DUDA @  11.10.2006,  16:57 Найти цитируемый пост)
из раздела с инфой по драйверам

Это как и где? 

Автор: mr.DUDA 11.10.2006, 17:27
Да хоть тот же HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses

Автор: Rapalex 12.10.2006, 10:36
Ключ реестра это не очень хорошо, подменить можно, да и где же тут платформенная назависимость .нет???

А другого способа что нет?

Добавлено @ 10:37 
Да и если всю системму завиртуалить и на другую тачку перенести думаю защита и слетает!

Добавлено @ 10:39 
Или необходимый рег файл перед стартом проги запускать, это не затруднительно но думаю прогу обманит!

Автор: mr.DUDA 12.10.2006, 11:08
Rapalex, что-то я сомневаюсь в работоспособности виндовоза с "поковырянными" этими разделами. Если их только назад не возвращать сразу после старта проги.

Автор: Rapalex 12.10.2006, 11:14
Я проверять не буду но что же мешает назад всё вернуть, а что мы спотрим RegMon раскажет,

Но а главное Что будет если свиртулить всю системму, и при переходе на линукс?

Добавлено @ 11:25 
Цитата

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses


Зашол я по этому ключю и ничего не понятно! Как это можно вообще с чемто сопоставить!!!

Автор: Rapalex 12.10.2006, 12:36
Есть ещё какие-нибудь варианты?

Автор: ivashkanet 12.10.2006, 13:05
Rapalex, спроси у Гугла как можно защитить свою прогу от взлома, он тебе даст кучу статей, несколько из них будут очень обширные и с примерами. 
Возможно они быдут на ВыньАПИ и системных dll, но ничего страшного. 
Ведь платформенная независимость .Net --- это МИФ (если не миф, то потенциальная возможность, которая так и останется нереализованной, ИМХО)

Автор: Rapalex 12.10.2006, 15:00
Цитата(ivashkanet @  12.10.2006,  13:05 Найти цитируемый пост)
платформенная независимость .Net --- это МИФ

Я слышал что платформа mono реализовала переход на UNIX.

Автор: ivashkanet 12.10.2006, 15:04
Цитата(Rapalex @  12.10.2006,  15:00 Найти цитируемый пост)
Я слышал что платформа mono реализовала переход на UNIX.

Да, но только первый .Net, да и то не весь smile и кривовато. Поищи инфу на форуме по этой теме.
Самый главный аргумент --- MS это не надо, а если этим будут заниматься сторонние компании, то они все равно будут отставать от MS  smile  smile 

Автор: mr.DUDA 12.10.2006, 16:50
Модератор: Давайте вернёмся к теме обсуждения.

Автор: Rapalex 10.2.2007, 16:33
Kefir, по поводу этой ссылки http://rsdn.ru/forum/message.aspx?mid=905667&only=1 скажу - ЛАЖА, я железо не менял, систему переставлял (на висту 64) и результаты изменились, такчто я бы не рекомендовал это как идентификацию железа.

sOckets, по поводу NtDriverList это я не смог собрать в студии, и както мне это не очень понравилось, да и не знаю как оно с вистой будет дружить или нет.

Больше ссылок в топике небыло, я возврощаюсть после "длительного" отдыха и опять поднимаю вопросс. Хоть ктото свою мелкую но весьма полезную прогу привязывал (или покрайней мере хотел).

ХЕЛП!!!

Автор: Xao 30.12.2007, 23:47
да, мне тоже интересно, кто-нибудь решил эту проблему?

mr.DUDA, а как у тебя с проектом, ты как делал?

 smile 

 smile 

Автор: mr.DUDA 31.12.2007, 17:33
Привязали к идентификатору HDD, используя driveId (скомпилированную в отдельную dll, вызов функций через [DllImport]).

Автор: Xao 2.1.2008, 17:39
mr.DUDA, 
а ты не мог бы выложить пример или эту длл?
если да, тогда опиши плз какие параметры должны быть в функции

Автор: Любитель 2.1.2008, 23:32
http://www.winsim.com/diskid32/diskid32.html - утилита (с исходниками на C) для получения инфы о винтах (в том числе и серйника).

Выдрать нужный код, думаю, проблем не составит. А вот способ взаимодействия с ним - вопрос спорный. Просто дллка + DllImport - уж слишком легко тупо подменить. В итоге вся привязка по сути отваливается. Наиболее, на мой взгляд, удачно было бы завязать то, что касается защиты в чистый анмэнеджед (за икслючением обращения непосредственно к дотнетовским вещам), но на C++/CLI. Полученную сборочку затем слинковать с самим приложением (ilmerge). В итоге этот код выдрать будет относительно проблемно (ну, всё в итоге прогать через оббфускатор - это уж само собой...)

Автор: Kefir 3.1.2008, 10:50
Когда то криво написал фигнюшку.
Код

        private string GetHDSerial()
        {
            ManagementObject disk = new ManagementObject("Win32_LogicalDisk.DeviceID=\"C:\"");
            PropertyData diskPropertyA = disk.Properties["VolumeSerialNumber"];
            return diskPropertyA.Value.ToString();
        }

        private string GetCPUId()
        {
            string cpuInfo = string.Empty;
            string temp = string.Empty;
            ManagementClass mc = new ManagementClass("Win32_Processor");
            ManagementObjectCollection moc = mc.GetInstances();
            foreach (ManagementObject mo in moc)
            {
                if (cpuInfo == string.Empty)
                {
                    cpuInfo = mo.Properties["ProcessorId"].Value.ToString();
                }
            }
            return cpuInfo;
        }

        private string GetMac()
        {
            ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
            ManagementObjectCollection moc = mc.GetInstances();
            foreach (ManagementObject mo in moc)
            {
                if ((bool)mo["IPEnabled"] == true)
                    return mo["MacAddress"].ToString();
            }
            return "";
        }

Автор: Любитель 3.1.2008, 13:18
1. Сетевухи может не быть. MAC адресса соответственно тоже.

2. ProcessorId - не есть уникальный код. С CPUID заморочка, что уникальный серийник ИМХО только у интела получить можно, и то не на всех процах.

3. Ты получаешь серйник раздела, а не самого винта. Получение серийник раздела винта - не столь тривиально (через WMI не возможно). В сорсах утилы, приведённой мною выше работает (там нэтив) через DeviceIoControl и \\.\Scsi

Автор: Kefir 3.1.2008, 13:50
Дада, само собой, прошу обратить внимание на мою фразу:
Цитата(Kefir @  3.1.2008,  10:50 Найти цитируемый пост)
Когда то криво написал фигнюшку.


Автор: mr.DUDA 3.1.2008, 14:40
Цитата(Любитель @  3.1.2008,  12:18 Найти цитируемый пост)
3. Ты получаешь серйник раздела, а не самого винта.

+1
Там походу вообще дата/время создания раздела в серийник пишется AFAIK. Например если компания закупила 10 веников с отформатированными разделами, тогда будет 10 одинаковых серийников.

Насчёт подмены длл - всё не так просто. Можно завязаться на содержимое длл: перед вызовом ф-ции через DllImport читать файл DLL, вычислять контрольную сумму и сравнивать с прописанной в коде проги. Если не совпадает, значит хакер Вася написал свою длл-ку. Говорим "привет Вася!" и завершаем работу.

Автор: Любитель 3.1.2008, 18:29
mr.DUDA, в какой-то мере, конечно да, но (!) в любом случае мэнеджед код (в нормальном виде - фишки CLR Secure, скажем, делают по сути ненормальный менеджед smile ) исследовать в разы проще. Впрочем, это уже явно не
Цитата(Любитель @  2.1.2008,  23:32 Найти цитируемый пост)
легко тупо подменить


Протос анменеджед из-под C++/CLI (т. е. внедрённый непосредственно в дотнетовский бинариник) исследовать достаточно муторно.

Автор: Xao 10.1.2008, 04:04
Народ, я пробовал выдрать то, что мне нужно отсюда 
http://www.winsim.com/diskid32/diskid32.html
открыл проект в с++
хотел его собрать, так он стока ошибок выдает  smile 
на C# еще можно было бы что-нить понять

Код

Error    1    error C2011: '_IDEREGS' : 'struct' type redefinition    c:\...\projects\diskid\diskid32.cpp    81    diskid32
Error    2    error C2011: '_SENDCMDINPARAMS' : 'struct' type redefinition    c:\...\projects\diskid\diskid32.cpp    96    diskid32
Error    3    error C2011: '_DRIVERSTATUS' : 'struct' type redefinition    c:\...\projects\diskid\diskid32.cpp    114    diskid32
Error    4    error C2011: '_SENDCMDOUTPARAMS' : 'struct' type redefinition    c:\...\projects\diskid\diskid32.cpp    125    diskid32
Error    5    error C2079: 'scip' uses undefined struct '_SENDCMDINPARAMS'    c:\...\projects\diskid\diskid32.cpp    242    diskid32
Error    6    error C2664: 'DoIDENTIFY' : cannot convert parameter 2 from 'int *' to 'PSENDCMDINPARAMS'    c:\...\projects\diskid\diskid32.cpp    259    diskid32
Error    7    error C2027: use of undefined type '_SENDCMDOUTPARAMS'    c:\...\projects\diskid\diskid32.cpp    264    diskid32
Error    8    error C2227: left of '->bBuffer' must point to class/struct/union/generic type    c:\...\projects\diskid\diskid32.cpp    264    diskid32

и т.д и там их куча


вот например первая ошибка, что значит структура переопределена
Код

   //  IDE registers
typedef struct _IDEREGS
{
   BYTE bFeaturesReg;       // Used for specifying SMART "commands".
   BYTE bSectorCountReg;    // IDE sector count register
   BYTE bSectorNumberReg;   // IDE sector number register
   BYTE bCylLowReg;         // IDE low order cylinder value
   BYTE bCylHighReg;        // IDE high order cylinder value
   BYTE bDriveHeadReg;      // IDE drive/head register
   BYTE bCommandReg;        // Actual IDE command.
   BYTE bReserved;          // reserved for future use.  Must be zero.
} IDEREGS, *PIDEREGS, *LPIDEREGS;


HELP!!!

Автор: Xao 10.1.2008, 04:47
с этой ошибкой разобрался, а вот такая ошибка:

Код

Error    2    error C2664: 'CreateFileW' : cannot convert parameter 1 from 'char [256]' to 'LPCWSTR'    c:\...\projects\diskid2\diskid2\diskid32.cpp    545    diskid2


Код

      char driveName [256];

      sprintf (driveName, "\\\\.\\PhysicalDrive%d", drive);

         //  Windows NT, Windows 2000, Windows XP - admin rights not required
      hPhysicalDriveIOCTL = CreateFile (driveName, 0,
                               FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                               OPEN_EXISTING, 0, NULL);


в sprintf надо передавать char
а в CreateFile LPWSTR
пишет, что не может конвертировать

Автор: mr.DUDA 10.1.2008, 11:46
Xao, вместо char использовать wchar_t, перед строковыми константами ставить букву L. Остальные вопросы - в раздел С++.

Автор: Xao 10.1.2008, 18:59
mr.DUDA, 
ты говорил, что решил проблему привязки

не мог бы ты скинуть ту длл плз и если можно, то пример получения серийного номера?

У меня не получается сделать dll с этих исходников :(
http://www.winsim.com/diskid32/diskid32.html

я вот тут нашел, но тут только с правами админа
http://www.sql.ru/forum/actualthread.aspx?bid=4&tid=346957&hl=
там код примера на ВБ

Код

Option Explicit
Private Declare Function IsWinNT Lib "DiskID.dll" () As Long
Private Declare Function ReadPhysicalDrive9X Lib "DiskID.dll" (driveID As Long, buffer As Long, bufLen As Long) As Long
Private Declare Function ReadPhysicalDriveInNT Lib "DiskID.dll" (driveID As Long, buffer As Long, bufLen As Long) As Long

Private Type DRIVER_INFO_OK
    ModalNumber(39) As Byte
    SerialNumber(19) As Byte
    ControlNum(7) As Byte
    DriveType As Long
    Cylinders As Long
    Heads As Long
    Sectors As Long
End Type

Private Sub Command1_Click()
    Dim x As DRIVER_INFO_OK
    Dim i As Long
    If IsWinNT = 1 Then
        i = ReadPhysicalDriveInNT(ByVal 0, ByVal VarPtr(x), ByVal 256)
    Else
        i = ReadPhysicalDrive9X(ByVal 0, ByVal VarPtr(x), ByVal 256)
    End If
    Dim s As String
    s = StrConv(x.ModalNumber, vbUnicode)
    s = Left(s, InStr(1, s, Chr(0)) - 1)
    Debug.Print "ModalNumber: " + s
    s = StrConv(x.SerialNumber, vbUnicode)
    s = Left(s, InStr(1, s, Chr(0)) - 1)
    Debug.Print "SerialNumber: " + s
End Sub


а вот сама dll:
http://www.sql.ru/forum/actualfile.aspx?id=3231663

помогите перевести этот код на С# плз!!!

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

Код

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace testdiskid32
{
    public partial class Form1 : Form
    {
        struct DRIVER_INFO_OK
        {
            byte[] ModalNumber;
            byte[] SerialNumber;
            byte[] ControlNum;
            long DriveType;
            long Cylinders;
            long Heads;
            long Sectors;
        }

        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            long buffer;
            this.label1.Text = ExportDiskID32.IsWinNT().ToString();
            this.label2.Text = ExportDiskID32.ReadPhysicalDriveInNT(0, buffer, 256).ToString();
        }
    }

    public class ExportDiskID32
    {
        [DllImport("DiskID.dll", EntryPoint = "IsWinNT")]
        public static extern long IsWinNT();
        [DllImport("DiskID.dll", EntryPoint = "ReadPhysicalDrive9X")]
        public static extern long ReadPhysicalDrive9X(long driveID, long buffer, long bufLen);
        [DllImport("DiskID.dll", EntryPoint = "ReadPhysicalDriveInNT")]
        public static extern long ReadPhysicalDriveInNT(long driveID, long buffer, long bufLen);
    }
}


Автор: mr.DUDA 10.1.2008, 23:38
Сорри, сейчас этого кода у меня нет (остался на предыдущей работе)... :(

Автор: Xao 12.1.2008, 14:41
mr.DUDA, 
жаль(

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

хотел еще спросить существуют ли проги, которые бы смогли изменить Drive Model Number (disk32.exe), или Product ID, жесткого диска 

Автор: mr.DUDA 12.1.2008, 16:36
Цитата(Xao @  12.1.2008,  13:41 Найти цитируемый пост)
пример использования этой длл

Всё сводится к получению серийника HDD, я просто взял стандартный идущий пример вместе с diskId и завернул его в экспортируемую функцию из DLL.

Автор: Xao 13.1.2008, 01:40
а как по поводу:

Цитата(Xao @  12.1.2008,  14:41 Найти цитируемый пост)
хотел еще спросить существуют ли проги, которые бы смогли изменить Drive Model Number (disk32.exe), или Product ID, жесткого диска 


???

Автор: VisualProgrammerNET 13.1.2008, 21:10
ммм... можно ли программно изменить вшитый аппаратно productId? ИМХО, нельзя. И ваще, цель подобной программы что-то не особо понятна...

Автор: Любитель 14.1.2008, 13:01
Цитата(Xao @  10.1.2008,  04:47 Найти цитируемый пост)

в sprintf надо передавать char
а в CreateFile LPWSTR
пишет, что не может конвертировать

Утила немного крива написана smile Перводи всё на юникод (wsprintf, etc.).

Цитата(Xao @  10.1.2008,  18:59 Найти цитируемый пост)
я тут начал делать, но не понял что надо сделать со вторым параметром в функции

По ходу у тебя пример для VB6. Он сильно отличается от дотнетовского (конкретно судить не могу - ибо не знаю smile )

Код

unsafe struct DRIVER_INFO_OK
{
            fixed byte ModalNumber[39];
            fixed byte SerialNumber[19];
            fixed byte ControlNum[7];
            long DriveType;
            long Cylinders;
            long Heads;
            long Sectors;
}

//...

        [DllImport("DiskID.dll", EntryPoint = "ReadPhysicalDriveInNT")]
        public static extern unsafe long ReadPhysicalDriveInNT(long driveID, DRIVER_INFO_OK* buffer, long bufLen);


То есть с приведённой длл-кой (судя по сигнатурам, по крайней мере) - юзать ансейф. И передавать адрес структуры соответствующей. Вообще, по-моему эта длл-ка основана на тех же исходниках (все дороги ведут туда...) - проще "подправить" анменеджед функцию, чтобы она приняла удобный для тебя вид (чтобы всё тупо промарашллить можно было).

Плюс к тому заметь - в тех сорсах три функции. Не знаю, что там в 9x, но в нт-шках:
1. Одна работает лишь с админскими правами
2. Вторая не работает с саташными винтами :(

Нормально рабочая (в моём понимании - т. е. без админских прав и с любыми винтами) - та, которая юзает \\.\Scsi

Автор: AGENTxXx 3.4.2010, 20:41
Надеюсь кому-нибудь пригодится в будующем (т.к. вопрос вроде бы как не решен тут). Код проги которая выдает необходимую информацию:
Код

using System;
using System.Management;
using System.Management.Instrumentation;

namespace Win32_ComputerSystem
{
    class Class1
    {
        [STAThread]
        static void Main(string[] args)
        {

            // сначала нам необходимо создать объект - запрос, в котором собственно и необходимо указать, что и откуда мы хотим получить
            ObjectQuery DiskQuery = new System.Management.ObjectQuery("select SerialNumber, Name, Description, InterfaceType from Win32_DiskDrive");
            // "Искатель" информации, приближенный аналог DataSet
            ManagementObjectSearcher DiskSearcher = new ManagementObjectSearcher(DiskQuery);
            ManagementObjectCollection DiskCollection = DiskSearcher.Get();
            foreach (ManagementObject DiskInfo in DiskCollection)
            {
                Console.WriteLine("Серийный номер жесткого диска: " + DiskInfo["SerialNumber"].ToString());
                Console.WriteLine("Имя жесткого диска: " + DiskInfo["Name"].ToString());
                Console.WriteLine("Описание жесткого диска: " + DiskInfo["Description"].ToString());
                Console.WriteLine("Интерфейс жесткого диска: " + DiskInfo["InterfaceType"].ToString());
            }
        }
    }
}


Добавлено через 1 минуту и 49 секунд
И да.. вот ссылочка где можно взять необходимые переменные для запроса (ну или использовать другой запрос): 
http://msdn.microsoft.com/en-us/library/aa394084(v=VS.85).aspx

Автор: SKrivosein 4.4.2010, 10:47
AGENTxXx у меня твой код неработает, выбрасывает ManagementException - неправильный запрос.
Пытаюсь найти в MSND причину. Я  эту тему неочень, но интересно...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)