靠BUG运行起来的程序
2024-03-26
33
0
经常看短子:程序员的代码都是靠代码运行起来的。
没想到经常吃瓜,也有吃到自己的身上。
前几天写的代码,功能一切正常。今天在review代码的时候,竟然有如下的代码:
PdoDeviceExternsion = (PPDO_DEVICE_EXTENSION)DeviceObject;
这是个明显的错误,理论代码应该是这样的:
PPDO_DEVICE_EXTENSION PdoDeviceExternsion2 = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
然以上的代码竟然可以完整无误的运行起来。
所以就加了调试日志,说话代码如下:
PdoDeviceExternsion = (PPDO_DEVICE_EXTENSION)DeviceObject;
PPDO_DEVICE_EXTENSION PdoDeviceExternsion2 = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
DbgPrint("NextDeviceObject=%p %p\n", PdoDeviceExternsion2->NextDeviceObject, PdoDeviceExternsion->NextDeviceObject);
你猜打印的结果怎么样,竟然是相同的:
NextDeviceObject=FFFFCD05704B7260 FFFFCD05704B7260
这惟一的解释就两个不同的地址其NextDeviceObject字段的偏移刚好内存是一样的:
通过查询内容:
3: kd> dt _DEVICE_OBJECT
nt!_DEVICE_OBJECT
+0x000 Type : Int2B
+0x002 Size : Uint2B
+0x004 ReferenceCount : Int4B
+0x008 DriverObject : Ptr64 _DRIVER_OBJECT
+0x010 NextDevice : Ptr64 _DEVICE_OBJECT
+0x018 AttachedDevice : Ptr64 _DEVICE_OBJECT
+0x020 CurrentIrp : Ptr64 _IRP
+0x028 Timer : Ptr64 _IO_TIMER
+0x030 Flags : Uint4B
+0x034 Characteristics : Uint4B
+0x038 Vpb : Ptr64 _VPB
+0x040 DeviceExtension : Ptr64 Void
+0x048 DeviceType : Uint4B
+0x04c StackSize : Char
+0x050 Queue : <unnamed-tag>
+0x098 AlignmentRequirement : Uint4B
+0x0a0 DeviceQueue : _KDEVICE_QUEUE
+0x0c8 Dpc : _KDPC
+0x108 ActiveThreadCount : Uint4B
+0x110 SecurityDescriptor : Ptr64 Void
+0x118 DeviceLock : _KEVENT
+0x130 SectorSize : Uint2B
+0x132 Spare1 : Uint2B
+0x138 DeviceObjectExtension : Ptr64 _DEVOBJ_EXTENSION
+0x140 Reserved : Ptr64 Void
3: kd> dt _PDO_DEVICE_EXTENSION
f9323!_PDO_DEVICE_EXTENSION
+0x000 Common : _COMMON_DEVICE_EXTENSION
+0x008 FunctionDescriptor : Ptr64 _USBC_FUNCTION_DESCRIPTOR
+0x010 NextDeviceObject : Ptr64 _DEVICE_OBJECT
+0x018 Capabilities : _DEVICE_CAPABILITIES
+0x058 FunctionIndex : Uint4B
+0x05c DeviceDescriptor : _USB_DEVICE_DESCRIPTOR
+0x070 ConfigurationDescriptor : Ptr64 _USB_CONFIGURATION_DESCRIPTOR
+0x078 ConfigurationHandle : Ptr64 Void
+0x080 InterfaceList : Ptr64 _USBD_INTERFACE_LIST_ENTRY
+0x088 InterfaceListCount : Uint4B
+0x090 FDODeviceExtension : Ptr64 FDO_DEVICE_EXTENSION
+0x098 StopInProgress : UChar
+0x09c state : deviceState
+0x0a0 IsPresent : UChar
+0x0a4 TestCount : Uint4B
两个字段的内存基于基地址的偏移刚好都是0x10,并且DEVICE_OBJECT是系统自己填充的,而PDO_DEVICE_EXTENSION中的NextDeviceObject是自己赋值的。
所以刚好说成了:
PdoDeviceExternsion的
PdoDeviceExternsion2的:
我感觉我可以买彩票了。
另一种回答:
高手写代码都计算的是内存,哪管它什么代码的。老子引用的数据对了就行了。这就叫做防御性编程,你懂不懂。