马上注册,免受广告困扰,轻松兑换eSIM!
您需要 登录 才可以下载或查看,没有账号?注册
×
它是来自内存不安全的 C++ 语言的空指针解引用导致。
这个sys文件在0x9c 属于无效地址。而计算机中的内存被设计成一个巨大的数字数组。
我们在这里将这些数字表示为十六进制,即以 16 为基数(十六进制),计算机尝试读取内存地址 0x9c(又名 156),对于任何程序来说,这都是无效的内存区域。任何试图读取此区域的程序都会立即被 Windows 杀死。
事实证明,crowdstrike 使用的语言 C++ 喜欢使用地址 0x0 作为特殊值,表示“这里什么都没有”,不要尝试访问它,否则你会模块将会死去。
C++ 程序员在传递对象时应该通过“检查完全空值”来检查这一点。
通常你会看到类似这样的内容:
string* p = get_name();
if (p == NULL) { print("Could not get name"); }
struct Obj {
int a;
int b;
};
如果我们创建一个指向它的指针:Obj* obj = new Obj();我们可以得到它的起始地址,假设它是一个随机数,如 0x9030=36912 (I我使用较小的数字)然后是地址:obj is 0x9030
obj->a is 0x9030 + 0x4
obj->b is 0x9030 + 0x8
每个成员都是距离起始地址的偏移量。
现在我们假设以下情况:Obj* obj = NULL;然后是地址:obj is 0
obj->a is 0 + 4
obj->b is 0 + 8
所以如果我对 NULL 指针执行此操作:print(obj->a);程序堆栈转储如上所示。它无法读取值 0x000000004
在此堆栈转储中,您可以看到它正在尝试读取内存值 0x9c。用人类数字来说,这是值 156。所以发生的事情是程序员忘记检查它正在处理的对象是否无效,它试图访问其中一个对象的成员变量
NULL + 0x9C = 0x9C = 156 ,因此0x9c的内存区域是无效区域。最致命的是,这是一个称为系统驱动程序的特殊程序,它对计算机具有特权访问权限。
因此,出于谨慎考虑,操作系统被迫立即崩溃。这就是导致蓝屏死机的原因。计算机可以通过简单地终止程序来从非特权代码崩溃中恢复,但不能终止系统驱动程序。当您的计算机崩溃时,95% 的时间是因为系统驱动程序崩溃。如果程序员检查了 NULL,或者使用了检查这类东西的现代工具,它本可以被发现。但不知何故它进入了生产环境,然后被 Crowdstrike 强制更新。
未来的解决办法是,微软需要有更好的政策来回滚有缺陷的驱动程序,而不仅仅是向客户提供原始的、危险的更新。Crowdstrike 可能会促使其代码安全官安装能够自动捕获此类问题的代码清理工具。而 Crowdstrike 可能会认真考虑将其系统驱动程序从当前的 C++ 重写为更现代的语言,如 Rust,而 Rust 不存在此问题。毕竟C++还是太古老了
|