Windows 2000/XP/Vista/7磁盘扇区读写技术

有些时候,我们读取磁盘文件,会被hook.我们读到的可能并非实际的文件。

我们直接读取磁盘扇区获取数据。

实现磁盘数据的读写,不依赖WindowsAPI

 

void CSectorEdit2000Dlg::OnView() 
{
    UpdateData(TRUE);
    if (m_uTo < m_uFrom)
        return;
    
    char cTemp[1];
    memcpy(cTemp, m_DrvListBoxSResult.Left(1), 1);
    UINT uDiskID = cTemp[0] - 64;
    DWORD dwSectorNum = m_uTo - m_uFrom + 1;
    if (dwSectorNum > 100)
        return;
    unsigned char* bBuf = new unsigned char[dwSectorNum * 512];
    
    if (ReadSectors(uDiskID, m_uFrom, (UINT)dwSectorNum, bBuf) == FALSE)
    {
        MessageBox("所选磁盘分区不存在!", "错误", MB_OK | MB_ICONERROR);
        return;
    }
    
    char* cBuf = new char[dwSectorNum * 5120];
    memset(cBuf, 0, sizeof(cBuf));
    for (DWORD i = 0; i < dwSectorNum * 512; i++)
    {
        sprintf(cBuf, "%s%02X ", cBuf, bBuf[i]);
        if ((i % 512) == 511)
            sprintf(cBuf, "%s\r\n第%d扇区\r\n", cBuf, (int)(i / 512) + m_uFrom);
        if ((i % 16) == 15)
            sprintf(cBuf, "%s\r\n", cBuf);
        else if ((i % 16) == 7)
            sprintf(cBuf, "%s- ", cBuf);
    }
    SetDlgItemText(IDC_DATA, cBuf);
    delete[] bBuf;
    delete[] cBuf;
}
void CSectorEdit2000Dlg::OnCleardata() 
{
    UpdateData(TRUE);
    char cTemp[1];
    memcpy(cTemp, m_DrvListBoxSResult.Left(1), 1);
    UINT uDiskID = cTemp[0] - 64;
    if (uDiskID > 2)
    {
        if (MessageBox("要清理的是硬盘分区,请确认是否继续?", "提示", MB_YESNO | MB_ICONWARNING) != 6)
            return;
        if (uDiskID == 3)
        {
            if (MessageBox("要清理的是系统分区,请再次确认是否继续?", "提示", MB_YESNO | MB_ICONWARNING) != 6)
                return;
        }
    }
    
    unsigned char bBuf[512];
    UINT i = 0;
    BOOL bRet = TRUE;
    while (m_bAllDisk)      
    {
        memset(bBuf, 0xFF, sizeof(bBuf));
        bRet = WriteSectors(uDiskID, i, 1, bBuf);
        memset(bBuf, 0, sizeof(bBuf));
        bRet = WriteSectors(uDiskID, i, 1, bBuf);
        
        if (bRet == FALSE)
        {
            if (i == 0)
                MessageBox("所选磁盘分区不存在!", "错误", MB_OK | MB_ICONERROR);
            else
                MessageBox("磁盘数据擦除完毕!", "错误", MB_OK | MB_ICONERROR);
            return;
        }
        i++;
    }   
    if (m_bAllDisk == FALSE)
    {
        for (DWORD i = m_uFrom; i <= m_uTo; i++)
        {
            memset(bBuf, 0xFF, sizeof(bBuf));
            bRet = WriteSectors(uDiskID, i, 1, bBuf);
            memset(bBuf, 0, sizeof(bBuf));
            bRet = WriteSectors(uDiskID, i, 1, bBuf);
            if (bRet == FALSE)
            {
                if (i == 0)
                    MessageBox("所选磁盘分区不存在!", "错误", MB_OK | MB_ICONERROR);
                else
                    MessageBox("磁盘数据擦除完毕!", "提示", MB_OK | MB_ICONINFORMATION);
                return;
            }
        }
    }
}
void CSectorEdit2000Dlg::OnBackup() 
{
    UpdateData(TRUE);
    if (m_uTo < m_uFrom)
        return;
    CFileDialog fileDlg(FALSE, "*.sec", "*.sec", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "磁盘扇区数据(*.sec)|*.sec||", NULL);
    CFile file;
    if (fileDlg.DoModal() != IDOK)
        return;
    
    file.Open(fileDlg.GetPathName(), CFile::modeCreate | CFile::modeReadWrite);
    char cTemp[1];
    memcpy(cTemp, m_DrvListBoxSResult.Left(1), 1);
    UINT uDiskID = cTemp[0] - 64;
    DWORD dwSectorNum = m_uTo - m_uFrom + 1;
    unsigned char* bBuf = new unsigned char[dwSectorNum * 512];
    
    if (ReadSectors(uDiskID, m_uFrom, (UINT)dwSectorNum, bBuf) == FALSE)
    {
        MessageBox("所选磁盘分区不存在!", "错误", MB_OK | MB_ICONERROR);
        return;
    }
    file.Write(bBuf, dwSectorNum * 512);
    file.Close();
    delete[] bBuf;
    MessageBox("数据备份完毕!", "提示", MB_OK | MB_ICONINFORMATION);
}
void CSectorEdit2000Dlg::OnRestore() 
{
    UpdateData(TRUE);
    
    char cTemp[1];
    memcpy(cTemp, m_DrvListBoxSResult.Left(1), 1);
    UINT uDiskID = cTemp[0] - 64;
    CFileDialog fileDlg(TRUE, "*.sec", "*.sec", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "磁盘扇区数据(*.sec)|*.sec||", NULL);
    CFile file;
    if (fileDlg.DoModal() != IDOK)
        return;
    file.Open(fileDlg.GetPathName(), CFile::modeReadWrite);
    DWORD dwSectorNum = file.GetLength();
    if (dwSectorNum % 512 != 0)
        return;
    dwSectorNum /= 512;
    unsigned char* bBuf = new unsigned char[dwSectorNum * 512];
    file.Read(bBuf, dwSectorNum * 512);
    if (WriteSectors(uDiskID, m_uFrom, (UINT)dwSectorNum, bBuf) == FALSE)
    {
        MessageBox("所选磁盘分区不存在!", "错误", MB_OK | MB_ICONERROR);
        return;
    }
    file.Close();
    delete[] bBuf;
    MessageBox("数据恢复完毕!", "提示", MB_OK | MB_ICONINFORMATION);
}
BOOL CSectorEdit2000Dlg::WriteSectors(BYTE bDrive, DWORD dwStartSector, WORD wSectors, LPBYTE lpSectBuff)
{
    if (bDrive == 0)
        return 0;
    char devName[] = "\\\\.\\A:";
    devName[4] ='A' + bDrive - 1;
    HANDLE hDev;
    if(m_bPhysicalDisk==false)
    {
        hDev = CreateFile(devName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    }
    else
        hDev = CreateFile("\\\\.\\PhysicalDrive0", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    if (hDev == INVALID_HANDLE_VALUE)
        return 0;
    SetFilePointer(hDev, 512 * dwStartSector, 0, FILE_BEGIN);
    DWORD dwCB;
    BOOL bRet = WriteFile(hDev, lpSectBuff, 512 * wSectors, &dwCB, NULL);
    CloseHandle(hDev);
    return bRet;
}
BOOL CSectorEdit2000Dlg::ReadSectors(BYTE bDrive, DWORD dwStartSector, WORD wSectors, LPBYTE lpSectBuff)
{
    if (bDrive == 0)
        return 0;
    char devName[] = "\\\\.\\A:";
    devName[4] ='A' + bDrive - 1;
    HANDLE hDev;
    if(m_bPhysicalDisk==false)
        hDev = CreateFile(devName, GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    else
        hDev = CreateFile("\\\\.\\PhysicalDrive0", GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    if (hDev == INVALID_HANDLE_VALUE)
        return 0;
    SetFilePointer(hDev, 512 * dwStartSector, 0, FILE_BEGIN);
    DWORD dwCB;
    BOOL bRet = ReadFile(hDev, lpSectBuff, 512 * wSectors, &dwCB, NULL);
    CloseHandle(hDev);
    return bRet;
}
void CSectorEdit2000Dlg::OnSelchangeComboDrive() 
{
    // TODO: Add your control notification handler code here
    int s;
    s = m_DrvListBox.GetCurSel();
    if( s != CB_ERR )
        m_DrvListBoxSResult = ( const char * )m_DrvListBox.GetItemDataPtr( m_DrvListBox.GetCurSel());
}
void CSectorEdit2000Dlg::OnCheck() 
{
    // TODO: Add your control notification handler code here
    m_bPhysicalDisk=!m_bPhysicalDisk;
    if(m_bPhysicalDisk==true)
    {
        GetDlgItem( IDC_COMBO_DRIVE)->EnableWindow( false );
    }
    if(m_bPhysicalDisk==false)
    {
        GetDlgItem( IDC_COMBO_DRIVE)->EnableWindow( true );
    }   
}