📄 restitutor.asm
字号:
;本版本应经测试通过
;############################################################################################################
; 这是一个在保护模式的Windows NT/2000/XP下恢复被RWMBR.exe改写的硬盘MBR程序
; 请最好在“命令提示符”下运行,图形方式也能运行。
;############################################################################################################
;
.386
.model flat, stdcall
option casemap :none
;
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
SECTOR_BYTES equ 512
.data?
dwRW dd ? ; 保存ReadFile函数实际读出的字节数
; 之后保存WriteFile函数实际写入的字节数
hFile dd ? ; 文件句柄
szBuffer1 db SECTOR_BYTES dup(?) ; 数据缓冲:将存放我写的MBR
szBuffer2 db SECTOR_BYTES dup(?) ; 数据缓冲:将存放原来的MBR
.const
szFileName db '\\.\PHYSICALDRIVE0',0 ; 打开第一个物理硬盘(PhysicalDrive0)
szCaption1 db '囧 Restitutor',0
szCaption2 db '^_^ Restitutor',0
szMessage db '本程序将恢复第一硬盘的主引导记录 ',0
szOkmessage db ' 恭 喜 你!',0Dh,0Dh
db '原硬盘主引导记录已经恢复!',0
szErrMessage1 db '你的权限不够,请以管理员身份运行本程序 ',0
szErrMessage2 db '遗憾,读原主引导扇区失败! ',0
szErrMessage3 db '抱歉,写主引导记录失败! ',0
szErrMessage db '你已经运行过本程序,不能再次运行',0Dh,0Dh
db ' 或者是你的MBR未曾被改变过!',0
.data
; 这是我写的新MBR,将被程序转储到szBuffer1起始的缓冲区中
szMyMBR db 0FAh,033h,0C0h,08Eh,0D0h,0BCh,000h,07Ch,0FBh,050h,007h,050h,01Fh,0FCh,0BEh,01Ch
db 07Ch,0BFh,01Ch,006h,050h,057h,0B9h,000h,002h,0F3h,0A4h,0CBh,033h,0C0h,050h,050h
db 050h,0B8h,001h,000h,050h,033h,0C0h,050h,0B8h,000h,07Ch,050h,0B8h,001h,000h,050h
db 0B8h,010h,000h,050h,08Bh,0F4h,0B8h,000h,042h,0B2h,080h,0CDh,013h,00Fh,082h,08Bh
db 000h,0EBh,041h,090h,054h,068h,065h,020h,04Dh,052h,042h,020h,068h,061h,076h,065h
db 020h,062h,065h,065h,06Eh,020h,072h,065h,070h,06Ch,061h,063h,065h,064h,021h,020h
db 049h,06Eh,070h,075h,074h,020h,037h,020h,063h,068h,061h,072h,020h,070h,061h,073h
db 073h,077h,06Fh,072h,064h,03Ah,0B5h,0A8h,0B7h,0B2h,0B7h,0B3h,0BFh,000h,000h,000h
db 000h,000h,000h,000h,0BCh,000h,07Ch,0B8h,000h,0B8h,08Eh,0C0h,00Eh,01Fh,0BEh,044h
db 006h,033h,0FFh,0B4h,0BCh,0B9h,032h,000h,0ACh,0ABh,0E2h,0FCh,01Eh,007h,0B9h,007h
db 000h,0BFh,07Dh,006h,051h,057h,0B4h,000h,0CDh,016h,00Ah,0C0h,074h,0F8h,05Fh,034h
db 086h,0AAh,059h,0E2h,0EFh,0BEh,076h,006h,0BFh,07Dh,006h,0B9h,007h,000h,0F3h,0A6h
db 075h,00Ah,090h,090h,033h,0C0h,050h,0BFh,000h,07Ch,057h,0CBh,0B8h,000h,0B8h,08Eh
db 0D8h,033h,0DBh,0B8h,045h,0FCh,089h,007h,0EBh,0FEh
szIDAddr EQU $-szMyMBR
db 055h,0AAh,0AAh,055h
szMyMBRLen EQU $-szMyMBR ; 下面是构造的硬盘前两个物理扇区内容
;
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
start:
; 提示信息
invoke MessageBox,NULL,offset szMessage,offset szCaption2,MB_OK or MB_ICONINFORMATION
; —————————————————————————核心—————————————————————————————
; 打开第一个物理硬盘
invoke CreateFile,offset szFileName, \
GENERIC_READ or GENERIC_WRITE, \ ; ★
FILE_SHARE_READ or FILE_SHARE_WRITE, \
NULL, \
OPEN_EXISTING, \
NULL, \
NULL ; 打开文件(第一个物理硬盘)
.if eax == INVALID_HANDLE_VALUE
invoke MessageBox,NULL,offset szErrMessage1,offset szCaption1,MB_OK or MB_ICONSTOP
jmp _exit ; 打开错误,则显示提示后退出
.endif
mov hFile,eax
; 读硬盘第一、第二物理扇区
invoke ReadFile,hFile, \
offset szBuffer1, \
SECTOR_BYTES*2, \
offset dwRW, \
NULL ; 读硬盘主引导扇区
.if eax == NULL
invoke CloseHandle,hFile ; 关闭句柄
invoke MessageBox,NULL,offset szErrMessage2,offset szCaption1,MB_OK or MB_ICONSTOP
jmp _exit ; 失败则显示提示后退出
.elseif dwRW !=SECTOR_BYTES*2
invoke CloseHandle,hFile ; 关闭句柄
invoke MessageBox,NULL,offset szErrMessage2,offset szCaption1,MB_OK or MB_ICONSTOP
jmp _exit ; 失败则显示提示后退出
.endif
mov dwRW,0
; ★test
; 判定是否已经运行过本程序
lea ebx,szBuffer1
add ebx,szIDAddr
mov eax,[ebx]
.if eax != 055AAAA55h
invoke CloseHandle,hFile ; 关闭句柄
invoke MessageBox,NULL,offset szErrMessage,offset szCaption1,MB_OK or MB_ICONSTOP
jmp _exit
.endif
; 复制到szBuffer2到szBuffer1——把原主引导扇区复制到szBuffer1
cld
lea edi,szBuffer1
lea esi,szBuffer2
mov ecx,SECTOR_BYTES
rep movsb
;
;编程提示:要先调整指针
invoke SetFilePointer,hFile,0,NULL,FILE_BEGIN ; 移动文件指针到物理第1扇区第零字节
; 写硬盘第一、第二物理扇区
invoke WriteFile,hFile, \
offset szBuffer1, \
SECTOR_BYTES*2, \
offset dwRW, \
NULL ; 写硬盘主引导扇区
.if eax == NULL
invoke CloseHandle,hFile ; 关闭句柄
invoke MessageBox,NULL,offset szErrMessage3,offset szCaption1,MB_OK or MB_ICONSTOP
jmp _exit ; 失败则显示提示后退出
.elseif dwRW !=SECTOR_BYTES*2
invoke CloseHandle,hFile ; 关闭句柄
invoke MessageBox,NULL,offset szErrMessage3,offset szCaption1,MB_OK or MB_ICONSTOP
jmp _exit ; 失败则显示提示后退出
.endif
invoke CloseHandle,hFile ; 关闭句柄
; 为成功欢呼
invoke MessageBox,NULL,offset szOkmessage,offset szCaption2,MB_OK or MB_ICONINFORMATION
;
_exit: invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
;############################################################################################################
使用 nmake 或下列命令进行编译和链接:
ml /c /coff /FlRestitutor Restitutor.asm ;(编译生成清单,不要清单的话:ml /c /coff Restitutor.asm)
Link /subsystem:windows Restitutor.obj RMBR.res
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -