原文:
http://bbs.fishc.com/thread-18255-1-1.html
http://bbs.fishc.com/thread-18256-1-1.html
-----------------------------------------------------------------------------------------------------------
知识普及:
硬盘的引导扇区位于 0 磁道 0 磁头 1 扇区位置,该扇区存放着系统的引导程序和硬盘的分区表等重要信息。另外小甲鱼八卦一下,该扇区常常是病毒的重点攻击目标!
实现要求:读取硬盘引导扇区并保存为boot.ini文件
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
实现原理:
上节课小甲鱼不是说会告诉大家如何在用户模式下直接访问硬盘么?嗯,而且承诺绝对简单通俗。好吧,事实上,硬盘内核驱动程序将硬盘作为一个文件,文件名为:"\\.\\physicaldrive0"
我们可以利用这个鲜为人知的文件名,通过 CreateFile, ReadFile, WriteFile 和 DeviceIoControl API 来进行访问硬盘。
代码及详细注释:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; by 小甲鱼, http://www.fishc.com
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 功能:读取硬盘引导扇区并保存于boot.ini文件中
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat,stdcall
option casemap:none
include windows.inc
include comdlg32.inc
include user32.inc
include kernel32.inc
includelib comdlg32.lib
includelib user32.lib
includelib kernel32.lib
.data
szFileName db '\\.\\physicaldrive0', 0 ; 硬盘设备名
.data?
szBuffer db 512 dup (?)
@hFile dd ?
@dwBytesRead dd ?
@szLogFile db MAX_PATH dup (?)
.const
szNewFile db 'boot.ini', 0
szErrOpenFile db '无法打开硬盘文件!', 0
szErrCreateFile db '无法创建boot.ini文件!', 0
szSuccess db '成功读取硬盘引导区并写入boot.ini文件!', 0
szCaption db '鱼C工作室', 0
.code
start:
invoke CreateFile, ; 打开或创建文件
addr szFileName, ; 文件的名字
GENERIC_READ, ; 允许读访问
FILE_SHARE_READ, ; 允许对文件进行共享访问
0, ; 指向一个SECURITY_ATTRIBUTES结构的指针
OPEN_EXISTING, ; 文件必须存在
FILE_ATTRIBUTE_NORMAL, ; 默认属性
0
.if eax == INVALID_HANDLE_VALUE ; 打开文件错误
invoke MessageBox,
NULL,
addr szErrOpenFile,
addr szCaption,
MB_OK
jmp exit
.endif
mov @hFile, eax ; 返回文件句柄,这时候硬盘被看成是一个文件的哦~
invoke ReadFile, ; 从文件中读取数据
@hFile, ; 文件句柄
addr szBuffer, ; 用于保存读入数据的缓冲区
sizeof szBuffer, ; 需要读入的字符数
addr @dwBytesRead, ; 实际读入的字节数
0
invoke CloseHandle, @hFile ; 小甲鱼温馨提醒:记得文件打开后要擦屁股->关闭文件,否则造成内存泄漏
invoke lstrcpy, ; 拷贝字符串
addr @szLogFile,
addr szNewFile
invoke CreateFile, ; 创建boot.ini文件
addr @szLogFile,
GENERIC_WRITE,
FILE_SHARE_READ,
0,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0
.if eax != INVALID_HANDLE_VALUE
mov @hFile, eax
invoke WriteFile, ; 将数据写入boot.ini文件
@hFile,
addr szBuffer,
sizeof szBuffer,
addr @dwBytesRead,
0
invoke CloseHandle, @hFile ; 擦屁股
invoke wsprintf, ; 这个事实上常用的函数,如果有问题的鱼油可以在论坛搜索下,有篇文章中小甲鱼已经做好了详细的解释给大家。
addr szBuffer,
addr szSuccess
invoke MessageBox,
NULL,
addr szBuffer,
addr szCaption,
MB_OK
.else
invoke MessageBox,
NULL,
addr szErrCreateFile,
addr szCaption,
MB_OK
.endif
exit:
invoke ExitProcess, NULL
end start