天天看點

VC++資訊安全程式設計(13)Windows2000/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)  

    unsigned char* bbuf = new unsigned char[dwsectornum * 512];  

    if (readsectors(udiskid, m_ufrom, (uint)dwsectornum, bbuf) == false)  

    {  

        messagebox("所選磁盤分區不存在!", "錯誤", mb_ok | mb_iconerror);  

    }  

    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()   

    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));  

        if (bret == false)  

            if (i == 0)  

                messagebox("所選磁盤分區不存在!", "錯誤", mb_ok | mb_iconerror);  

            else  

                messagebox("磁盤資料擦除完畢!", "錯誤", mb_ok | mb_iconerror);  

        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));  

            if (bret == false)  

            {  

                if (i == 0)  

                    messagebox("所選磁盤分區不存在!", "錯誤", mb_ok | mb_iconerror);  

                else  

                    messagebox("磁盤資料擦除完畢!", "提示", mb_ok | mb_iconinformation);  

            }  

void csectoredit2000dlg::onbackup()   

    cfiledialog filedlg(false, "*.sec", "*.sec", ofn_hidereadonly | ofn_overwriteprompt, "磁盤扇區資料(*.sec)|*.sec||", null);  

    cfile file;  

    if (filedlg.domodal() != idok)  

    file.open(filedlg.getpathname(), cfile::modecreate | cfile::modereadwrite);  

    file.write(bbuf, dwsectornum * 512);  

    file.close();  

    messagebox("資料備份完畢!", "提示", mb_ok | mb_iconinformation);  

void csectoredit2000dlg::onrestore()   

    cfiledialog filedlg(true, "*.sec", "*.sec", ofn_hidereadonly | ofn_overwriteprompt, "磁盤扇區資料(*.sec)|*.sec||", null);  

    file.open(filedlg.getpathname(), cfile::modereadwrite);  

    dword dwsectornum = file.getlength();  

    if (dwsectornum % 512 != 0)  

    dwsectornum /= 512;  

    file.read(bbuf, dwsectornum * 512);  

    if (writesectors(udiskid, m_ufrom, (uint)dwsectornum, bbuf) == false)  

    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)  

    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)  

        hdev = createfile(devname, generic_read, file_share_write, null, open_existing, 0, null);  

        hdev = createfile("\\\\.\\physicaldrive0", generic_read, file_share_write, null, open_existing, 0, null);  

    bool bret = readfile(hdev, lpsectbuff, 512 * wsectors, &dwcb, null);  

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()   

    m_bphysicaldisk=!m_bphysicaldisk;  

    if(m_bphysicaldisk==true)  

        getdlgitem( idc_combo_drive)->enablewindow( false );  

        getdlgitem( idc_combo_drive)->enablewindow( true );  

繼續閱讀