单位的某一个业务系统用到了DynamiCube组件,很多客户端的IE浏览器都无法正常下载并注册DynamiCube组件,导致页面无法正常显示。手工拷贝DCube3.cab到客户端并解出Dcube3.ocx,然后regsvr32 Dcube3.ocx会有错误提示“LoadLibrary(“DCube3.ocx”) 失败 – 内存分配访问无效”,英文的错误提示是“LoadLibrary(dcube3.ocx”) failed – Invalid Access to Memory Location”。其实这是因为Dcube3.ocx受到DEP(Data Eexcute Protection)阻止造成的。解决办法也很简单,先禁止DEP,然后注册Dcube3.ocx,然后再打开DEP即可。
XP SP3可以这样关闭DEP,打开boot.ini文件,将/noexecute的值改为AlwaysOff或者将/noexecute及等号后的值一起改为/execute,保存重启系统即可。
During initialization, the Windows I/O manager starts the disk storage drivers. Storage drivers in Windows follow a class/port/miniport architecture, in which Microsoft supplies a storage class driver that implements functionality common to all storage devices and a storage port driver that implements functionality common to a particular bus—such as a Small Computer System Interface (SCSI) bus or an Integrated Device Electronics (IDE) system—and OEMs supply miniport drivers that plug into the port driver to interface Windows to a particular controller implementation.
系统初始化期间,windows I/O管理器开始装载磁盘存储驱动.windows中的存储驱动遵循类/端口/小端口(class/port/miniport)架构,MS提供一个存储类驱动实现与具体设备无关的、所有存储设备共同的功能特性和一个存储端口驱动实现一类特殊总线共同的功能—比如SCSI(Small Computer System Interface)总线或者IDE(Integrated Device Electronics)总线—然后OEM(Original Equipment Manufacturer)制造商提供挂接到端口驱动的小端口驱动来为windows提供到一个特殊控制器实现的访问接口。
—译自《windows internals》(5th)
一台xp系统机器,无法上网浏览, ping本地私有地址和外部公有地址都通,但是ping命令输出出现问号并伴随一声蜂鸣。输出类似如下:
ping ? 192.168.1.1 with 32 bytes of data:
reply from 192.168.1.1: bytes=32 time <10 ttl=64
reply from 192.168.1.1: bytes=32 time <10 ttl=64
reply from 192.168.1.1: bytes=32 time <10 ttl=64
卸载网卡驱动,重新安装故障依旧。交换机及网线确认无问题,执行如下命令
netsh winsock reset
重置winsock组件,问题解决,应该是恶意软件或插件所为。
借PC处理器架构由x86向x64过渡之机,MS清理了windows x64平台上的函数调用约定,由原来的数种包括stdcall,thiscall,fastcall,cdecl,pascal等,统一为一种新的fastcall调用方式。这种调用方式得益于x64平台寄存器数量的增加。
windows x64平台fastcall调用约定的主要特性如下:
- 前四个整型或指针类型参数由RCX,RDX,R8,R9依次传递,前四个浮点类型参数由XMM0,XMM1,XMM2,XMM3依次传递。
- 调用函数为前四个参数在调用栈上保留相应的空间,称作shadow space或spill slot。即使被调用方没有或小于4个参数,调用函数仍然保留那么多的栈空间,这有助于在某些特殊情况下简化调用约定。
- 除前四个参数以外的任何其他参数通过栈来传递,从右至左依次入栈。
- 由调用函数负责清理调用栈。
- 小于等于64位的整型或指针类型返回值由RAX传递。
- 浮点返回值由XMM0传递。
- 更大的返回值(比如结构体),由调用方在栈上分配空间,并有RCX持有该空间的指针并传递给被调用函数,因此整型参数使用的寄存器依次右移一格,实际只可以利用3个寄存器,其余参数入栈。函数调用结束后,RAX返回该空间的指针。
- 除RCX,RDX,R8,R9以外,RAX、R10、R11、XMM4 和 XMM5也是易变化的(volatile)寄存器。
- RBX, RBP, RDI, RSI, R12, R14, R14, and R15寄存器则必须在使用时进行保护。
- 在寄存器中,所有参数都是右对齐的。小于64位的参数并不进行高位零扩展,也就是高位是无法预测的垃圾数据。
因为访问可编程中断控制器(PIC)是相对较慢的操作,需要访问I/O总线来改变中断请求级(IRQL)的硬件抽象层(HAL),比如为了访问中断控制器(PIC)和32位高级配置电源接口(ACPI)系统,实现了一个性能优化 ,谓之延迟中断请求级(lazy IRQL),来尽量避免可编程中断控制器(PIC)访问。当中断请求级(IRQL)上升以后,硬件抽象层(HAL)在内部记录该中断请求级(IRQL)而不是来改变中断屏蔽(interrupt mask)。如果一个低优先级的中断随之而来,硬件抽象层(HAL)为前面的中断设置合适的中断屏蔽(interrupt mask),也就是实实在在的提升中断请求级(IRQL),从而延迟这个低优先级的中断直到中断请求级(IRQL)降低。这样以来,当中断请求级(IRQL)升高时如果没有低优先级的中断发生,硬件抽象层(HAL)并不真正的去修改可编程中断控制器(PIC)。
windows内核函数命名的一般格式为:
<Prefix><Operation><Object>
Prefix指示导出该例程的组件,Operation指出对对象或资源做什么样的动作,Object标示操作的对象或资源。比如ExAllocatePoolWithTag是一个执行体(Executive)例程,用来从分页池(paged pool)或非分页池(nonpaged pool)中分配内存。KeInitializeThread是一个分配并且设置内核线程对象(kernel thread object)的内核例程。
Read more…