我有一个低级别(比如真的低级别,它基本上都是所有IOCTL调用和几次调用枚举API)在客户机上的Windows Vista / 7上偶尔崩溃。不幸的是,我无法获得任何故障转储,但一位有用的用户确实提到在XP兼容模式下运行该程序解决了这个问题。
应用程序始终以完全管理员权限启动(它是从另一个需要管理员授权的程序启动的),因此它不是UAC问题。我不使用任何已弃用的API,而且我不依赖任何注册表黑客等。我只是发出枚举磁盘的调用,然后使用IOCTL命令获取有关所有连接设备的更多低级信息。
XP兼容模式会发生什么? Windows注入我的应用程序或以其他方式沙箱,以防止它在Vista / 7上崩溃?我原本怀疑堆腐败(虽然我已经把我的头发拉出来试图复制或追查问题),然后被告知它在XP兼容模式下运行良好。
任何人都可以建议在XP Compat模式中可以避免的任何可能的问题,我应该尝试解决这个问题吗?谢谢!
编辑:
还有一件事可能非常重要:我从用户空间调用DDK / Kernel函数,以获得未通过WIN32 API公开的某些功能。
我正在使用ZwReadFile,ZwCreateFile,ZwWriteFile,RtlInitUnicodeString,ZwQueryVolumeInformationFile,ZwDeviceIoControlFile,ZwSetInformationFile,ZwClose。
我正在调用的IOCTL包括IOCTL_DISK_GET_PARTITION_INFO_EX,IOCTL_STORAGE_GET_DEVICE_NUMBER,IOCTL_DISK_GET_LENGTH_INFO和IOCTL_DISK_GET_DRIVE_LAYOUT_EX。
答案 0 :(得分:1)
这很奇怪,但我在调用ZwQueryVolumeInformationFile时将FsInformationClass设置为FileFsVolumeInformation。
我先传入FILE_FS_VOLUME_INFORMATION缓冲区,首先正常分配,然后过度分配到(sizeof(FILE_FS_VOLUME_INFORMATION) + sizeof(TCHAR)*FILE_FS_VOLUME_INFORMATION->VolumeLabelLength)
。
然后我打电话 <{1}}和只在某些计算机上,这会导致内存损坏。
无论分配的大小如何(甚至尝试额外分配完整的256个字符!),当使用FILE_FS_VOLUME_INFORMATION->VolumeLabel[FILE_FS_VOLUME_INFORMATION->VolumeLabelLength/2] = _T('\0');
作为FILE_FS_VOLUME_INFORMATION缓冲区时,这将可靠地导致堆损坏甚至。
似乎内核会以某种方式在缓冲区上放置某种写保护,无论大小如何都会导致损坏。将第一个VolumeLableLength字节复制到第二个缓冲区,然后后挂起vector<unsigned char>
解决了这个问题。不确定Windows如何/为什么将 I 分配的缓冲区作为参数readonly 或传入,如果它在 FILE_FS_VOLUME_INFORMATION结构之后存储 (应该以字符数组结束!),但是根本不修改我传递的缓冲区中的任何数据就行了....这很疯狂,因为它只发生(始终如一且100%可重复) )在某些机器上。
无论如何:问题解决了* phew *!
答案 1 :(得分:0)
从XP到vista的低级驱动程序有很多变化。我怀疑你正在使用受其影响的IOCTL。