winston 发表于 2012-3-8 15:06:44

[原]VC++信息安全编程(18)Windows2000/xp/vista/7磁盘扇区读写

有些时候,我们读取磁盘文件,会被hook.我们读到的可能并非实际的文件。
我们直接读取磁盘扇区获取数据。
实现磁盘数据的读写,不依赖WindowsAPI。


void CSectorEdit2000Dlg::OnView()
{
        UpdateData(TRUE);
        if (m_uTo < m_uFrom)
                return;
       
        char cTemp;
        memcpy(cTemp, m_DrvListBoxSResult.Left(1), 1);
        UINT uDiskID = cTemp - 64;

        DWORD dwSectorNum = m_uTo - m_uFrom + 1;
        if (dwSectorNum > 100)
                return;

        unsigned char* bBuf = new unsigned char;
       
        if (ReadSectors(uDiskID, m_uFrom, (UINT)dwSectorNum, bBuf) == FALSE)
        {
                MessageBox("所选磁盘分区不存在!", "错误", MB_OK | MB_ICONERROR);
                return;
        }
       
        char* cBuf = new char;
        memset(cBuf, 0, sizeof(cBuf));

        for (DWORD i = 0; i < dwSectorNum * 512; i++)
        {
                sprintf(cBuf, "%s%02X ", cBuf, bBuf);

                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;
        memcpy(cTemp, m_DrvListBoxSResult.Left(1), 1);
        UINT uDiskID = cTemp - 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;

        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;
        memcpy(cTemp, m_DrvListBoxSResult.Left(1), 1);
        UINT uDiskID = cTemp - 64;

        DWORD dwSectorNum = m_uTo - m_uFrom + 1;
        unsigned char* bBuf = new unsigned char;
       
        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;
        memcpy(cTemp, m_DrvListBoxSResult.Left(1), 1);
        UINT uDiskID = cTemp - 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;
        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 ='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 ='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 );
        }       
}

作者:yincheng01 发表于2011-12-15 8:04:42 原文链接

页: [1]
查看完整版本: [原]VC++信息安全编程(18)Windows2000/xp/vista/7磁盘扇区读写