zoukankan      html  css  js  c++  java
  • 指针错位导致对FSD误判

    FSD管理器实现中有如下代码
    DWORD CStore::OpenDisk()
    {
        DWORD dwError = ERROR_SUCCESS;
        STORAGE_IDENTIFICATION storageid;

        if (m_pBlockDevice) {
            m_hDisk = m_pBlockDevice->OpenBlockDevice();
        } else {
            m_hDisk = CreateFileW(m_szDeviceName,
                               GENERIC_READ | GENERIC_WRITE,
                               0,
                               NULL, OPEN_EXISTING, 0, NULL);
       
            if (m_hDisk == INVALID_HANDLE_VALUE) {
                dwError = GetLastError();
                if (dwError == ERROR_ACCESS_DENIED) {
                    dwError = ERROR_SUCCESS;
                    m_hDisk = CreateFileW(m_szDeviceName,
                                       GENERIC_READ,
                                       FILE_SHARE_READ,
                                       NULL, OPEN_EXISTING, 0, NULL);
                    if (m_hDisk != INVALID_HANDLE_VALUE) {
                        m_dwFlags |= STORE_ATTRIBUTE_READONLY;
                    } else {
                        dwError = GetLastError();
                    }   
                }   
            }
        }  
        if (m_hDisk != INVALID_HANDLE_VALUE) {
            DWORD dwRet;
            if (!::DeviceIoControl(m_hDisk, DISK_IOCTL_GETINFO, &m_di, sizeof(DISK_INFO), NULL, 0, &dwRet, NULL)) {
                dwError = GetLastError();
                if ((dwError == ERROR_BAD_COMMAND) || (dwError == ERROR_NOT_SUPPORTED)){
                    memset( &m_di, 0, sizeof(DISK_INFO));  
                    dwError = ERROR_SUCCESS;
                }
            }
            if (dwError == ERROR_SUCCESS) {
                if (!::DeviceIoControl( m_hDisk, IOCTL_DISK_DEVICE_INFO, &m_sdi, sizeof(STORAGEDEVICEINFO), NULL, 0, &dwRet, NULL)) {
                    DEBUGMSG( ZONE_INIT, (L"FSDMGR!CStore::OpenDisk(0x%08X) call to IOCTL_DISK_DEVICE_INFO failed..filling info\r\n", this));
                    m_sdi.dwDeviceClass = STORAGE_DEVICE_CLASS_BLOCK;
                    m_sdi.dwDeviceFlags = STORAGE_DEVICE_FLAG_READWRITE;
                    m_sdi.dwDeviceType = STORAGE_DEVICE_TYPE_UNKNOWN;
                    wcscpy( m_sdi.szProfile, L"Default");
                }
            }   
            DEBUGMSG( ZONE_INIT, (L"FSDMGR!CStore::OpenDisk(0x%08X) DeviceInfo Class(0x%08X) Flags(0x%08X) Type(0x%08X) Profile(%s)\r\n",
                this,
                m_sdi.dwDeviceClass,
                m_sdi.dwDeviceFlags,
                m_sdi.dwDeviceType,
                m_sdi.szProfile));
            SetLastError( ERROR_SUCCESS);   
            dwError = ::DeviceIoControl(m_hDisk, IOCTL_DISK_GET_STORAGEID, NULL, 0, &storageid, sizeof(STORAGE_IDENTIFICATION), &dwRet, NULL);
            if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) {
                m_pStorageId = new BYTE[storageid.dwSize];
                ::DeviceIoControl(m_hDisk, IOCTL_DISK_GET_STORAGEID, NULL, 0, m_pStorageId, storageid.dwSize, &dwRet, NULL);
            }
           
        }
        return dwError;
    }
    IOCTL_DISK_GET_STORAGEID 返回的内容除去STORAGE_IDENTIFICATION 结构外还有附加的信息,这样就会执行后面的条件。我的驱动在代码执行时竟然会影响到dwError位,导致程序的返回内容不正确。故意由于storageid和dwError都为上述函数的栈空间内,自己写的IOCTL访问指针时错位,导致OpenDisk局部变量受影响所导致。

    察看反编译结果后发现后发现,两个的变量的指针位置刚好相邻
    dwError -> 0x040ef83c
    storageid->0x040ef82c

    在没有检查传入buffer长度的情况下直接写入了跟随的信息,导致OpenDisk出错。

  • 相关阅读:
    读取lotus85邮箱未读文档
    Lotus notes 通讯录的导入导出
    如果你发现vpuserinfo.nsf数据库损坏,如何修复?该数据
    如何从iNotes获得未读邮件数量
    NTKO文档控件常见报错信息集合
    页面缓存清除的方法
    通过Lotusscript代码从损坏的数据库中抽取数据
    如何将lotus 通讯簿导入到outlook 2003中
    怎样使用Lotus Domino实用程序(Updall, Compact, Fixup) 进行正常和异常维护。
    0301.Lotus Domino与Windows AD帐户同步和SSO
  • 原文地址:https://www.cnblogs.com/nasiry/p/381515.html
Copyright © 2011-2022 走看看