多年前用8086汇编写的《给硬盘加启动密码》

02年刚学汇编语言时写的一个小程序,并投稿至《计算机爱好者》杂志,结果被退稿(好没面子),一直没有机会展现在世人面前,今天抖胆发出来,实现自己多年的夙愿,各位看官见笑了!

我们知道硬盘的0磁头0柱面1扇区为硬盘的主引导扇区,它又分为主引导记录(MBR) 和分区表(DPT)一共512字节。其中前446字节为主引导记录,接着是分区表,起始地址为第1BEH字节,占16×4=64字节(主分区和扩展分区最多有四个,每个分区记录占16个字节),剩下的二个字节是结束标志,恒定为55H、AAH。分区表是记录硬盘的分区情况,如标记活动分区的地址、各分区的起始扇区、结束扇区、分区的大小等。通过修改分区表我们最可以实现安装多操作系统及多重启动。主引导记录其实就是一段程序,它的作用是在硬盘启动时检测分区表的完整性及引导活动分区的操作系统。如果我们用自己的程序代替主引导记录,那么我们就可以在硬盘启动时为所欲为了,例如加上一个启动密码。    

现在我们来分析一下硬盘的启动流程,假定BIOS设定为从硬盘启动:    

开机时BIOS程序先检测分区表的有效性,如果分区表有问题,比如没有结束标志,则按照BIOS设定启动的驱动器顺序依次去引导。否则把主引导扇区加载到内存的0:7C00H 处,并跳到0:7C00H去运行主引导程序。    

 在硬盘的0磁头0柱面除了第1个扇区(主引导扇区)外,其它的扇区基本上是无用的,我们所要做的事情就是先找到一个全为0的空扇区,可以用KV300的F6功能或NORTON D- ISKEDIT等磁盘工具去查找 ,然后把主引导扇区搬到这个扇区,再把自己的程序连同原分区表一起加载到0磁头0柱面1扇区。读写扇区的工作可以调用BIOS的13号中断的2、3子功能来完成。    

接下来替代主引导记录的程序则可以按如下步骤编写:    

 (1) 初始化堆栈和各寄存器    

(2)把主程序搬移到0:61BH处,为以后要加载的主引导扇区腾出空间    

(3)跳到0:61BH处继续运行    

(4)显示密码框及输入、判断密码,如密码正确则跳到(5),否则重复(4)    

(5)把备份的主引导扇区读到0:7C00H处    

(6)跳到0:7C00H处运行    

下面就把以上的步骤结合起来,写一个完整的程序,源程序用汇编语言编写,并连接成COM程序,在使用前请先备份分区表,否则若出现什么问题那可就多多得罪了。

cseg	    segment

    assume  cs:cseg,ds:cseg,es:cseg,ss:cseg

    org     100h

main	proc	near

    jmp     start

sector	    db	200h dup(0);存放扇区数据,长度为512字节

n	    dw	8	   ;n为空扇区的扇区号,可以用磁盘工具找到

start:

    mov     ax,201h	

    lea     bx,sector

    mov     cx,1

    mov     dx,80h

    int     13h		;读主引导扇区数据

    mov     ax,301h	

    mov     cx,n

    int     13h		;备份主引导扇区的数据到空扇区



    lea     si,my_code	

    lea     di,sector   

    mov     cx,1beh

    cld

    rep     movsb	;把密码程序的前1BEH字节移到sector,

			;对原来的分区表不作更改

    mov     ax,301h     

    inc     cx

    int     13h		;把sector中的数据写到硬盘的主引导扇区

    int     20h         ;程序结束

    org     600h        ;把下面的程序EA定义到600H处,这样所有变量

			;和标号在内存中的相对位址也就确定了

main		endp    

;---------------------------------------------------

my_code proc	near

    xor     ax,ax       

    mov     ss,ax

    mov     sp,7c00h    ;堆栈设在0:7C00H处

    sti

    push    ax          ;ES=DS=AX=0

    pop     es	

    push    ax

    pop     ds

    cld

    mov     si,7c1bh    ;把password_start以下的程序搬到0:61BH处

			;因为在引导时下面程序的EA为7C1BH,

			;所以这里填上立即数

    mov     di,61bh     

    push    ax          

    push    di

    mov     cx,1e5h

    rep     movsb

    retf		;跳到password_start去执行

password_start:

    lea     di,buffer	;清除键盘缓冲区,di为缓冲区指针,buffer在后面定义

    push    di

    xor     al,al

    mov     cx,8

    rep     stosb

    pop     di



    mov     ax,600h	

    mov     bx,7000h

    mov     cx,0b1ch

    mov     dx,0d34h

    int     10h		;把sector中的数据写到硬盘的主引导扇区



    mov     ah,13h	

    xchg    bh,bl

    mov     cx,0fh

    mov     dx,0c1dh

    lea     bp,string

    int     10h		;把sector中的数据写到硬盘的主引导扇区



    mov     ah,2	

    xor     bh,bh

    add     dx,0fh

    int     10h		;设置光标位置



in_key:

    xor     ah,ah	;键盘输入

    int     16h

    cmp     ah,1ch

    jz	    check	;回车则跳去检查密码

    cmp     di,offset buffer+8 

    jz	    in_key      ;密码最多8位,如缓冲区满则不再接受字符

    stosb		;把输入字符的ASCII码存入缓冲,di+1

    mov     ax,0e2ah	;在光标置显示"*",光标右移

    int     10h

    jmp     in_key      ;继续等待键盘输入直至按回车

check:

    lea     si,buffer   ;SI指向键盘缓冲区首地址

    xor     bx,bx	;BX清零

    mov     cx,8	;循环次数为8次

add_loop:

    lodsb               ;把(SI)装入AL,并SI+1

    mul     cl		;AX=AL*CL

    add     bx,ax	;BX=BX+AX

    loop    add_loop	;循环直到CX=0

    xor     bx,password

    jnz     password_start;如密码错误则重新输入

    mov     ah,2	

    xor     bx,bx

    mov     dx,1700h	

    int     10h		;设置光标位置到屏幕的24行1列	

    mov     ax,201h	

    lea     bx,7c00h

    mov     cx,8	

    mov     dx,80h

    int     13h		;把备份的主引导扇区加载到0:7C00H处

			;这里的CX与上面的n对应,但必须填入立即数

    jmp     bx		;跳到0:7C00H

my_code 	endp

;--------------------------------------------------

buffer	    db	8 dup(0);键盘缓冲区,密码最多为8位

password    dw	738h	;密码的值,即密码为12345678

string	    db	'Enter password:';提示字符

    org     7beh	;把下面指令的EA设置为7BEH,使这段程序填满1BEH字节

    nop

cseg	    ends

    end     main
这个程序功能比较简单,只能在引导时启用口令,对磁盘的文件则没有加密的效果,且没有更改密码的功能。小弟只在这里提出一条思路,各位朋友可以发挥想象力,写出更好的程序.此程序的初始密码为12345678,如果想修改密码则可以按以下公式进行计算:password=N1*8+N2*7+N3*6+……N8*1。其中N1为第一个字符的ASCII码,N2为第二个字符的ASCII码,以此类推,如果密码不足8位则只计算前面几位即可,然后把相加的结果存入源程序的password区再进行汇编连接并运行。使用时还要注意一点:这个程序只能使用一次,如果运行第二次开机时会出现死循环,除非在运行第二次前已经恢复了主引导扇区的数据。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值