0

我想保护我的应用程序。所以我读取了硬盘序列号并进行了比较。该应用程序在管理员用户模式下效果良好,但在标准用户模式下效果不佳。

我用 C# 编写了我的应用程序。但是为了读取硬盘序列号,我使用了我在 Delphi 中编写的 dll 文件。

hDevice := CreateFile( '\\.\PhysicalDrive0:', GENERIC_READ or GENERIC_WRITE ,
        FILE_SHARE_READ or FILE_SHARE_WRITE , nil, OPEN_EXISTING, 0, 0 );

我尝试使用 NET,所以我使用了 WMI 类Win32_DiskDrive,但这种方法在标准用户模式下也有不好的结果。

private string getserial()
{
    string SerialNumber = "";
    string dataForSerial = string.Empty;
    ManagementObjectSearcher Finder = new ManagementObjectSearcher("Select * from Win32_OperatingSystem");
    string Name = "";

    foreach (ManagementObject OS in Finder.Get()) Name = OS["Name"].ToString();

    // Name = "Microsoft Windows XP Professional|C:\WINDOWS|\Device\Harddisk0\Partition1" 

    int ind = Name.IndexOf("Harddisk") + 8;
    int HardIndex = Convert.ToInt16(Name.Substring(ind, 1));
    Finder = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive WHERE Index=" + HardIndex);
    foreach (ManagementObject HardDisks in Finder.Get())
        foreach (ManagementObject HardDisk in HardDisks.GetRelated("Win32_PhysicalMedia"))
            SerialNumber = HardDisk["SerialNumber"].ToString();

    // SerialNumber = dataForSerial;

    return SerialNumber;
} 

在标准用户模式下:

  1. 如果是 Delphi dll,它会抛出拒绝访问错误
  2. 在 WMI 的情况下,标准用户与管理员用户的输出不同。

注意:此问题(NO.2)仅在 Windows 7 中。

4

2 回答 2

1

请看这个链接。结果因 Windows 版本、代码是否以管理员身份运行以及是否使用Win32_PhysicalMedia类或Win32_DiskDrive类而异。看起来很不可靠,您可能必须编写自己的抽象层来自己处理它,如这些论坛帖子中所述。

我自己尝试了一下,发现我得到了两个不同的序列号,具体取决于 admin 与 normal 和Win32_PhysicalMediavs Win32_DiskDrive

VB38bb50ab-0de50c12

42563833626230356261302d6564303531632032

请注意,第二个字符串实际上是第一个字符串的一个hex-encodedbyte-reversed版本!

于 2019-06-26T10:31:29.587 回答
1

CreateFile调用访问物理磁盘时请使用以下代码。它无需管理员权限即可工作,并允许读取驱动器的属性:

hDisk := CreateFile ('\\.\PHYSICALDRIVE0', 0, FILE_SHARE_WRITE, NIL, OPEN_EXISTING,
                     FILE_ATTRIBUTE_NORMAL or FILE_FLAG_NO_BUFFERING, 0);

另请注意,作为第一个参数传递给 CreateFile 的驱动器名称末尾不包含冒号“:”。

于 2019-06-09T19:12:57.067 回答