So no an unmapped address is a completely different BSOD, usually PAGE_FAULT_IN_UNPAGED_AREA which is a very bad sign
(DRIVER_)IRQL_NOT_LESS_OR_EQUAL[2][3] is not this case, but it's probably one of the most common reasons drivers crash the system generally. Like you said it's basically attempting to access pageable memory at a time that paging isn't allowed (i.e. when at DISPATCH_LEVEL or higher).
[1]: https://learn.microsoft.com/en-us/windows-hardware/drivers/d...
[2]: https://learn.microsoft.com/en-us/windows-hardware/drivers/d...
[3]: https://learn.microsoft.com/en-us/windows-hardware/drivers/d...
R8 is 0x9c in that example, which is somewhat typical for null+offset, but in the twitter thread it's 0xffff9c8e0000008a.
So the actual bug is further back. It's not a null pointer dereference, but it somehow results in the mov r8, [rax+r11*8] instruction reading random data (could be anything) into r8, which then gets used as a pointer.
Maybe this is a use-after-free?
int *array = NULL
int position = 0x9C
int a = *(array[pos]) //equivalent to *(array + 0x9C) - dereferencing NULL+0x9C, which is just 0x9C
This will segfault (or equivalent) due to reading invalid memory at address 0x9C. Most people would call array[pos] a null pointer dereference casually, even though it’s actually a 0x9C pointer dereference, because there’s very little effective difference between them.
Now, whether this case was actually something like this (dereferencing some element of a null array pointer) or something like type confusion (value 0x9C was supposed to be loaded into an int, or char, or some other non-pointer type) isn’t clear to me. But I haven’t dug into it really, someone smarter than me could probably figure out which it is.
struct BigObject {
char stuff[0x9c]; // random fields
int field;
}
BigObject* object = nullptr;
printf("%d", object->field);
That will result in "Attempt to read from address 0x9c". Just because it's not trying to read from literal address 0x0 doesn't mean it's not nullptr error.That's true for the literal constant 0. For 0 in a variable it is not necessarily true. Basically when a literal 0 is assigned to a pointer or compared to a pointer the compiler takes that 0 to mean whatever bit pattern represents the null pointer on the target system.
It's not guaranteed that NULL is 0.
Still, I don't think you'd find a counterexample in the wild these days.