You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Pretty much every single IOCTL handler has incorrect input buffer checking.
size % sizeof(X) == 0 is true when size == 0, so passing an empty buffer to pretty much any of them will crash you.
None of the user supplied pointers in the buffers are are probed for length/alignment/actually being an UM pointer.
Data inside user supplied pointers is not copied and creates TOCTOU vulnerabilities.
For none of the things you end up signature scanning, do you validate whether the dereferenced offsets make any sense or are even inside the image.
Use mutexes consistently. Some of your APIs expect the caller to acquire the mutex, some of them acquire it themselves. There are no comments that indicate this and FAST_MUTEX is not recursive. IIRC there were places that the data wasn't protected by a mutex at all.
What is the point of copying over every single signature to its own paged pool, instead of just using it directly (or at least to a stack buffer since size is known at compile time).
You already use AutoLock. Same thing can be done for 90% of the allocations to avoid the goto Cleanup spam.
There are no SAL annotations for anything.
Bugs list
Incorrect iteration / removal from sparse array.
If you're iterating an array and decrementing its size while doing that, you'll miss/leak half of the entries.
If the array is sparse and you remove not from the end, decrementing the size will make you miss/leak last entry.
if (info->Threads[i].ClientId.UniqueThread == PsGetCurrentThread())
Missing buffer size check and assumption that an UNICODE_STRING will be null terminated. MAX_PATH Buffers and assumption of C disk isn't something you'd expect from a driver either.
Operator new is not allowed to return null, consider using std::nothrow version instead. The opposite is true for operator delete where it allows being passed in a null pointer, but ExFreePoolWithTag doesn't.
General notes
size % sizeof(X) == 0
is true whensize == 0
, so passing an empty buffer to pretty much any of them will crash you.goto Cleanup
spam.Bugs list
Incorrect iteration / removal from sparse array.
Nidhogg/Nidhogg/AntiAnalysis.cpp
Lines 759 to 768 in d8697ca
Nidhogg/Nidhogg/FileUtils.cpp
Lines 16 to 20 in d8697ca
Nidhogg/Nidhogg/FileUtils.cpp
Lines 194 to 200 in d8697ca
Nidhogg/Nidhogg/MemoryUtils.cpp
Lines 16 to 18 in d8697ca
Nidhogg/Nidhogg/MemoryUtils.cpp
Lines 1268 to 1277 in d8697ca
Nidhogg/Nidhogg/ProcessUtils.cpp
Lines 304 to 311 in d8697ca
Nidhogg/Nidhogg/ProcessUtils.cpp
Lines 420 to 425 in d8697ca
Comparing thread ID with thread object.
Nidhogg/Nidhogg/MemoryUtils.cpp
Line 1168 in d8697ca
Missing buffer size check and assumption that an UNICODE_STRING will be null terminated.
MAX_PATH
Buffers and assumption of C disk isn't something you'd expect from a driver either.Nidhogg/Nidhogg/FileUtils.cpp
Lines 39 to 48 in d8697ca
Dereferencing object you have not acquired if
PsLookupThreadByThreadId
is unsuccessful.Nidhogg/Nidhogg/MemoryUtils.cpp
Lines 1171 to 1177 in d8697ca
Incorrect size for terminating character.
Nidhogg/Nidhogg/MemoryUtils.cpp
Line 1234 in d8697ca
Missing removal of hooks on driver unload.
Nidhogg/Nidhogg/AntiAnalysis.cpp
Line 14 in d8697ca
Object is not dereferenced anywhere.
Nidhogg/Nidhogg/MemoryUtils.cpp
Line 187 in d8697ca
Nidhogg/Nidhogg/MemoryUtils.cpp
Line 425 in d8697ca
Missing output buffer length validation for the callbacks array that is populated from an unbounded list.
Nidhogg/Nidhogg/AntiAnalysis.cpp
Lines 396 to 409 in d8697ca
Nidhogg/Nidhogg/AntiAnalysis.cpp
Lines 568 to 582 in d8697ca
Missing null checks.
Nidhogg/Nidhogg/Nidhogg.cpp
Lines 210 to 214 in d8697ca
Missing lock for iteration of PsLoadedModuleList.
Nidhogg/Nidhogg/MemoryUtils.cpp
Line 497 in d8697ca
Nidhogg/Nidhogg/MemoryUtils.cpp
Line 545 in d8697ca
Missing address space / VAD locks.
Nidhogg/Nidhogg/MemoryUtils.cpp
Line 672 in d8697ca
Trusting usermode PEB pointers to be valid or for the address space to be intact at all.
Nidhogg/Nidhogg/MemoryUtils.cpp
Line 454 in d8697ca
Nidhogg/Nidhogg/MemoryUtils.cpp
Line 822 in d8697ca
Trusting any RVA to be correct while parsing PE headers or for the pointer to be valid at all.
Nidhogg/Nidhogg/MemoryUtils.cpp
Line 850 in d8697ca
All allocated features are leaked in case of failure in driver entry.
Nidhogg/Nidhogg/Nidhogg.cpp
Line 46 in d8697ca
MmHighestUserAddress
,MmUserProbeAddress
,MmSystemRangeStart
are a better choice. Not that this really does any useful validation.Nidhogg/Nidhogg/pch.h
Lines 9 to 11 in d8697ca
Operator new is not allowed to return null, consider using std::nothrow version instead. The opposite is true for operator delete where it allows being passed in a null pointer, but ExFreePoolWithTag doesn't.
Nidhogg/Nidhogg/AntiAnalysis.hpp
Lines 119 to 121 in d8697ca
Missing NTSTATUS check.
Nidhogg/Nidhogg/AntiAnalysis.cpp
Line 72 in d8697ca
The text was updated successfully, but these errors were encountered: