關於硬碟序列號的探討!
http://www.ddvip.net/jmjm/crackjq/43.htm 近來在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
#include
#include
#include
#include 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
#include
#include
#include 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, "X-X
", 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即可. 我歡迎每一位熱情, 誠摯的朋友! 拒絕狂妄. 讓我們攜起手來, 從小做起, 共通推動民族軟體發展!