老文章档案 · 2003 年

关于硬盘序列号的探讨!

破解教程 · 技术资料 · 2003-09-19 · 作者:看雪 人气: · 出处:赢政天下整理收藏)

大家好:

近来在CFIDO和E-mail中一直有朋友询问关于如何能在Windows下用VB来

获取硬盘序列号的问题, 因为在VB的for Windows中版本中没有了端口存取

函数, 所以就写了一个HDIDE16.DLL的东东, 放在主页上免费发放, 并且

HDIDE32版本的即将出台, 孰知却遭到 XXX 肆意践踏, 理由如下:

---- CUT ----

WX> 好久一来, 一直未能发现有用VB来获取硬盘序列号的东东,

WX> 以致于VB的程序 不能得到很好的保护, 所以昨天做了个HDIDE16.DLL,

RT> 太烦了吧!

RT> 不是我想给你泼冷水,你的WINAPI知识有点欠乏!

RT> 取计算机硬盘序列号及卷名的函数是:

RT> 这个老早我就用了.

RT> 加密方法很多种,也不一定用硬盘序列号.

RT> 可惜不能说. :)))

--- CUT ---

对此, 我表示强烈的抗议, 并且为避免由此引起的误导, 特将基本的常识区

分如下, 附有完整的对比源程序:

关于盘序列号有两种:

硬盘序列号: 英文名 Hard Disk Serial Number, 该号是出厂时生产厂家为

区别产品而设置的, 是唯一的, 是只读的, 利用硬盘序列号的

加密往往是利用其唯一和只读的特性, 大多是针对有序列号的

IDE HDD而言, 对于没有序列号或SCSI HDD硬盘则无能为力,

这也是利用它进行加密的局限性.

卷的序列号: 英文名 Volume Serial Number, 该号既可指软磁盘要得, 如:

A:盘和B:盘的, 又可以指硬盘的逻辑盘, 如: C:, D:...的,

是高级格式化时随机产生的, 是可以修改的, 所以利用其进行

加密, 其唯一性还可, 而其可修改性对于安全而言就大打折扣

了.

那么如何获得它们呢? 这要视不同的平台而论, 核心实现方法如下:

DOS平台 Windows 3.X Windows 9.X

硬盘序列号: 端口I/O 端口I/O Ring0级I/O

卷的序列号: 中断调用 WINAPI WINAPI

为方便大家验证, 特贴如下两程序用TC或BC编译后运行在DOS下即可:

/* 程序1: 获得IDE硬盘C的序列号 */

#include <stdio.h>

#include <stdlib.h>

#include <dos.h>

#include <conio.h>

#include <string.h>

char *getascii (unsigned int in_data [], int off_start, int off_end);

void main (void)

{

unsigned int dd [256]; /* DiskData */

unsigned int dd_off; /* DiskData offset */

while (inp (0x1F7) != 0x50) /* Wait for controller not busy */

;

outp (0x1F6, 0xA0); /* Get first/second drive */

outp (0x1F7, 0xEC); /* Get drive info data */

while (inp (0x1F7) != 0x58) /* Wait for data ready */

;

for (dd_off = 0; dd_off != 256; dd_off++) /* Read "sector" */

dd [dd_off] = inpw (0x1F0);

printf ("The Serial Number Hard Disk [C] is %s", getascii (dd, 10, 19));

}

char *getascii (unsigned int in_data [], int off_start, int off_end)

{

static char ret_val [255];

int loop, loop1;

for (loop = off_start, loop1 = 0; loop <= off_end; loop++)

{

ret_val [loop1++] = (char) (in_data [loop] / 256); /* Get High byte */

ret_val [loop1++] = (char) (in_data [loop] % 256); /* Get Low byte */

}

ret_val [loop1] = ""; /* Make sure it ends in a NULL character */

return (ret_val);

}

/* 程序2: 获得逻辑盘C的序列号 */

#include <stdio.h>

#include <stdlib.h>

#include <ctype.h>

#include <dos.h>

void main(void)

{

char serial_no[10];

union REGS r;

struct SREGS s;

unsigned sno1, sno2;

r.x.ax = 0x6900;

r.h.bl = 3; /* A:=1, B:=2, C:=3 etc. */

segread(&s);

intdosx(&r, &r, &s);

if (r.x.cflag)

*serial_no = "";

else

{

sno2 = *((unsigned far *)MK_FP(s.ds, r.x.dx+2));

sno1 = *((unsigned far *)MK_FP(s.ds, r.x.dx+4));

sprintf(serial_no, "%04X-%04X

", sno1, sno2);

}

printf("The Serial Number of Login Disk [C] is %s", serial_no );

}

在Windows 3.X中:

硬盘序列号: 使用端口I/O即可, 将以上程序稍加修改并用VC或BC做成DLL

即可在VB中调用, 本人就是这样做的.

卷的序列号: 用那位朋友所说的WINAPI函数GetVolumeInformation即可.

在Windows 9.X中:

硬盘序列号: 必须使用VxD技术, 即便不写VxD文件, 要获得Ring0级的访问权

才能获得, 否则程序工作在Ring3级会死在以下语句处:

while (inp (0x1F7) != 0x50) /* Wait for controller not busy */

详细技术请访问http://dingkai.sdxf.com

卷的序列号: 用那位朋友所说的WINAPI函数GetVolumeInformation即可.

我欢迎每一位热情, 诚挚的朋友! 拒绝狂妄.

让我们携起手来, 从小做起, 共通推动民族软件发展!

(出处:赢政天下整理收藏)

相关文章:

相关软件:

→ 特别推荐

→ 热点TOP10

我为人人《《==》》人人为我

关于我们 |

帮助(?)

| 广告服务 |

版权声明 |

商业合作 |

发展历程 |

加盟我们 |

联系我们

Copyright © 1999-2003

winzheng.com All Rights Reserved.

繁体版:由华琦数码技术提供

Powered

by:MeSky.Net

2003-2004 年,宽带刚刚普及,下载站的文章区是许多人学电脑的第一课堂。
🕰 → 🤖 从那时到现在

当年一篇教程能让一台电脑焕然一新;今天的效率工具换成了 AI。 想知道当下最可靠的 AI 模型怎么选?看 赢政指数——我们用了 28 年的选软件严谨,现在用来评测大模型。

档案性质声明:本页为赢政天下(1998-2011)老文章的历史档案复原, 内容反映当年发表时的原貌——包括当年的技术表述、软件版本与观点,部分方法在今天已不适用或不合规,仅作互联网历史记录与研究用途, 不提供任何形式的下载。原始数据经由公共网络存档(Internet Archive)复原。发现问题请联系我们
← 返回老文章档案 · 软件史档案馆 · 赢政天下站史