能否用VB读写一个分区头的字节,让这个分区无法访问?当然也是可逆的~~

解决方案 »

  1.   

    Option Explicit'/////////////////////////////////////////
    '//对磁盘的物理扇区数据读/写操作
    '//lastupdate:2004-8-7
    '//KwanhongYoung
    '/////////////////////////////////////////
    '//filesystem
    Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, ByVal lpOverlapped As Long) As Long '//declare has changed
    Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, ByVal lpOverlapped As Long) As Long '//declare has changed
    Private Declare Function SetFilePointer Lib "kernel32" (ByVal hFile As Long, ByVal lDistanceToMove As Long, lpDistanceToMoveHigh As Long, ByVal dwMoveMethod As Long) As LongPrivate Const GENERIC_READ = &H80000000
    Private Const GENERIC_WRITE = &H40000000Private Const FILE_SHARE_READ = &H1
    Private Const FILE_SHARE_WRITE = &H2
    Private Const OPEN_EXISTING = 3Private Const INVALID_HANDLE_VALUE = -1'//file seek
    Private Const FILE_BEGIN = 0
    Private Const FILE_CURRENT = 1
    Private Const FILE_END = 2Private Const ERROR_SUCCESS = 0&'//device io control
    Private Declare Function DeviceIoControl Lib "kernel32" (ByVal hDevice As Long, ByVal dwIoControlCode As Long, lpInBuffer As Any, ByVal nInBufferSize As Long, lpOutBuffer As Any, ByVal nOutBufferSize As Long, lpBytesReturned As Long, ByVal lpOverlapped As Long) As LongPrivate Const IOCTL_DISK_GET_DRIVE_GEOMETRY As Long = &H70000 '458752
    Private Const IOCTL_STORAGE_GET_MEDIA_TYPES_EX As Long = &H2D0C04
    Private Const IOCTL_DISK_FORMAT_TRACKS As Long = &H7C018
    Private Const FSCTL_LOCK_VOLUME As Long = &H90018
    Private Const FSCTL_UNLOCK_VOLUME As Long = &H9001C
    Private Const FSCTL_DISMOUNT_VOLUME As Long = &H90020
    Private Const FSCTL_GET_VOLUME_BITMAP = &H9006F'//type
    Private Type LARGE_INTEGER
    lowpart As Long
    highpart As Long
    End TypePrivate Enum MEDIA_TYPE
    Unknown
    F5_1Pt2_512
    F3_1Pt44_512
    F3_2Pt88_512
    F3_20Pt8_512
    F3_720_512
    F5_360_512
    F5_320_512
    F5_320_1024
    F5_180_512
    F5_160_512
    RemovableMedia
    FixedMedia
    End EnumPrivate Type DISK_GEOMETRY
    Cylinders As LARGE_INTEGER
    MediaType As MEDIA_TYPE
    TracksPerCylinder As Long
    SectorsPerTrack As Long
    BytesPerSector As Long
    End Type'//private vars
    Private hDisk As Long 'disk handle
    Private lpGeometry As DISK_GEOMETRY 'disk info
    Private lBufferSize As Long 'the buffer size of read/writePublic Function OpenDisk(ByVal FileName As String) As Boolean
    '// 打开磁盘
    hDisk = CreateFile(FileName, _
    GENERIC_READ or GENERIC_WRITE, _
    FILE_SHARE_READ or FILE_SHARE_WRITE, _
    ByVal 0&, _
    OPEN_EXISTING, _
    0, _
    0)
    OpenDisk = Not (hDisk = INVALID_HANDLE_VALUE)
    End FunctionPublic Function CloseDisk() As Boolean
    '//关闭磁盘
    CloseDisk = CloseHandle(hDisk)
    End FunctionPublic Function GetDiskGeometry() As Boolean
    '//获取磁盘参数
    Dim dwOutBytes As Long
    Dim bResult As BooleanbResult = DeviceIoControl(hDisk, _
    IOCTL_DISK_GET_DRIVE_GEOMETRY, _
    ByVal 0&, 0, _
    lpGeometry, Len(lpGeometry), _
    dwOutBytes, _
    ByVal 0&)If bResult Then lBufferSize = lpGeometry.BytesPerSector * lpGeometry.SectorsPerTrack
    GetDiskGeometry = bResult
    End FunctionPublic Sub GetDiskInfo(MediaType As Long, _
    Cylinders As Long, _
    TracksPerCylinder As Long, _
    SectorsPerTrack As Long, _
    BytesPerSector As Long)
    '//返回磁盘的参数
    MediaType = lpGeometry.MediaType
    Cylinders = lpGeometry.Cylinders.lowpart
    TracksPerCylinder = lpGeometry.TracksPerCylinder
    SectorsPerTrack = lpGeometry.SectorsPerTrack
    BytesPerSector = lpGeometry.BytesPerSectorEnd SubPublic Property Get BufferSize() As Long
    '//返回每次读/写的缓冲大小
    BufferSize = lBufferSize
    End Property
    Public Function LockVolume() As Boolean
    '// 将卷锁定
    Dim dwOutBytes As Long
    Dim bResult As BooleanbResult = DeviceIoControl(hDisk, _
    FSCTL_LOCK_VOLUME, _
    ByVal 0&, 0, _
    ByVal 0&, 0, _
    dwOutBytes, _
    ByVal 0&)
    LockVolume = bResult
    End Function
    Public Function UnlockVolume() As Boolean
    '// 将卷解锁
    Dim dwOutBytes As Long
    Dim bResult As BooleanbResult = DeviceIoControl(hDisk, _
    FSCTL_UNLOCK_VOLUME, _
    ByVal 0&, 0, _
    ByVal 0&, 0, _
    dwOutBytes, _
    ByVal 0&)
    UnlockVolume = bResult
    End Function
    Public Function DismountVolume() As Boolean
    '// 将卷卸下,使系统重新辨识磁盘,等效于重新插盘
    Dim dwOutBytes As Long
    Dim bResult As BooleanbResult = DeviceIoControl(hDisk, _
    FSCTL_DISMOUNT_VOLUME, _
    ByVal 0&, 0, _
    ByVal 0&, 0, _
    dwOutBytes, _
    ByVal 0&)
    DismountVolume = bResult
    End Function
    Public Function ReadDisk(ByVal Cylinders As Long, _
    ByVal Tracks As Long, _
    db() As Byte) As Boolean
    '//按柱面和磁道来读取磁盘数据
    Dim iPos As Long
    Dim lRead As LongiPos = Cylinders * Tracks * lBufferSizeIf SeekAbsolute(0, iPos) Then
    ReadDisk = ReadBytes(lBufferSize, db(), lRead)
    End If
    End FunctionPublic Function WriteDisk(ByVal Cylinders As Long, _
    ByVal Tracks As Long, _
    db() As Byte) As Boolean
    '//按柱面和磁道来写磁盘数据
    Dim iPos As Long
    Dim lRead As LongiPos = Cylinders * Tracks * lBufferSizeIf SeekAbsolute(0, iPos) Then
    WriteDisk = WriteBytes(lBufferSize, db())
    End If
    End Function
    '/////////////////////////////////////////////////////////////////////////////////////
    '//file systemPrivate Function SeekAbsolute(ByVal HighPos As Long, ByVal LowPos As Long) As Boolean
    '//seek file
    '//Notice: when you set LowPos=5, the read/write will begin with the 6th(LowPos+1) byte
    LowPos = SetFilePointer(hDisk, LowPos, HighPos, FILE_BEGIN)
    If LowPos = -1 Then
    SeekAbsolute = (Err.LastDllError = ERROR_SUCCESS)
    Else
    SeekAbsolute = True
    End IfEnd Function
    Private Function ReadBytes(ByVal ByteCount As Long, ByRef DataBytes() As Byte, ByRef ActuallyReadByte As Long) As Boolean
    '//read data to array
    Dim RetVal As Long
    RetVal = ReadFile(hDisk, DataBytes(0), ByteCount, ActuallyReadByte, 0)
    'ActuallyReadByte =>> if the bytesRead=0 mean EOF
    ReadBytes = Not (RetVal = 0)End FunctionPrivate Function WriteBytes(ByVal ByteCount As Long, ByRef DataBytes() As Byte) As Boolean
    '//write data from array
    Dim RetVal As Long
    Dim BytesToWrite As Long
    Dim BytesWritten As LongRetVal = WriteFile(hDisk, DataBytes(0), ByteCount, BytesWritten, 0)WriteBytes = Not (RetVal = 0)
    End Function
      

  2.   

    以上代码貌似在opendisk "f:" 时就返回false
      

  3.   

    转两篇文章:
    VB实现逻辑盘隐藏分区    本处说的是逻辑盘,不是整个硬盘(对整个硬盘,用windos编程我还没做过)
        本文纯为个人猜想而作,无任何参考资料,若有错,敬请指出
        准备材料:硬盘上的一个空区,比如G:盘,可以先格式化一下,建议用快速的
        机器上本来有个G:盘3G,已经格式化成Fat32文件系统,测试将I:盘(一个usb盘,119M,存有文件,Fat系统)直接复制到G:。复制后G:盘文件完全可读,但是G:成了fat系统,大小成了119M,和I:完全一样。用磁盘查错工具检查,没发现错误,而剩下的2G多的空间“不翼而飞”。也就是说系统的普通方法已经读不出这些空间(用FDisk可以)但用我们原来的方法仍然可以读取(用close后会出现错误,请改用createfile编写)。现在把自己的保密文件存在这里,该没人发现了吧!
        上面只是测试过程,要把G:设定成任意大小,请参看磁盘的结构的书。如果手头没书,用下面方法也可实现(需要点不怕苦的精神):
        制作一个文件读取工具(把文件读取成16进制,有点象dos下面debug程序 -d列出来的东西,为了编程需要,很早我就做了一个)。查看G盘的精确大小(存储数据包括文件系统类型,比如fat16,那么有个数就是16,还有1个是簇的大小(这个用open读不出来,换用createfile+deviceiocontrol读取该盘参数),然后用读取工具查看G盘数据,找出这个地址(就在G盘开头),最后修改吧,祝你好运。同理,用以上方法可以实现对磁盘格式化。
        隐藏区的删除:如果没做卷的备份,那就格式化吧。
    (以上在win2000、VB6.0实现)VB最简单的磁盘直读的代码
    精通API的朋友可能都知道CreateFile可以用来打开很多东西,比如说硬盘之类,而且在用它们的时候可能对一大堆函数和参数已经伤透了脑筋。猜想vb自带的语句"Open"也是由createfile编写的,但不知道有多少人想到用open 来打开硬盘?!(经过网上查找,没有一句类似的代码) 
    (以下代码在win2000、Fat16,32文件系统、VisualBasic6.0测试成功,window98肯定不行,其他系统没试过)
    因为本人一直都用windows98,最近刚装了个2000,就测试用open来实现逻辑盘直读(光盘和其他东西也可以,不过有时要出问题)。注:其实这里并不是直接访问硬盘(win2000等是不允许应用程序这样做的),还是通过了文件系统,只不过文件和我们通常见到的不同而已。
    其中一代码基本如下
    dim MyN(511) as byte
    Open "\\.\c:" for binary as #1
    open "\\.\h:" for binary as #2
      do while not eof(1)'实际上这句在这里没什么用
        get #1,,MyN
        put #2,,MyN
      loop
    close
    请在以上适当位置加上doevents和控制退出的代码
    其中MyN的长度必须是512的倍数,读取起始位置必须是512倍数+1(C语言中就是512倍数)
    以上代码实现将c盘的东西直接读出并写到h盘
    (本代码将把h盘原来数据清空,请小心测试,责任自负)
    对于系统可读取的盘(已经格式化过了的),用open几乎可以做任何操作,甚至在win2000下把系统盘(c:)写掉(请不要用此来搞破坏活动哈)。
    如果写入的数据都是0,那么该盘将成为“没格式化的盘”,有点象低格,在这种情况下只要close掉文件,用open将不能再打开,而改用createfile仍然可以操作
    用本语句已经实现恢复格式化前盘上的数据、格式化盘(因为只用open没法读取扇区和磁道数,只有自己设定值,而且前提是盘上已经有了FAT)、恢复已删除的文件、删除正在运行的程序文件、光盘直读,相信还可以做其他事,当然做个病毒也可以, 呵呵。有兴趣的朋友可以测试一下看能不能打开其他设备。
    本来想用Open做个在win2000下的类似ghost的东西,却发现支持文件长度只有Long,晕,暂时还没想到办法(不过还是用c语言做安全,用这个系统可能要报废)目前在这方面的处理上我倾向于用open,毕竟用createfile太繁了,还要配合一堆函数和参数,实在没办法再考虑它吧!