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
Hello,
I encountered a VMProtect protected executable that caused a BSOD inside HyperHide driver.
After looking at the minidump in WinDbg I found out that RtlEqualUnicodeString called from HookedNtQueryObject tried to dereference a null pointer which led to a crash.
if (RtlEqualUnicodeString(&Type->TypeName, &DebugObject, FALSE) == TRUE)
Seems like VMProtect zeros the TypeName.Buffer pointer inside the OBJECT_TYPE_INFORMATION before HyperHide has a chance to compare the strings.
I was able to replicate the issue with following PoC:
BYTE memory[0x1000];
void zeroStrPtr()
{
POBJECT_TYPE_INFORMATION info = (POBJECT_TYPE_INFORMATION)memory;
while (true)
{
info->TypeName.Buffer = 0;
}
}
int main()
{
HANDLE debugObject;
OBJECT_ATTRIBUTES oa;
InitializeObjectAttributes(&oa, 0, 0, 0, 0);
if (NtCreateDebugObject(&debugObject, DEBUG_ALL_ACCESS, &oa, 0) >= 0)
{
std::thread(zeroStrPtr).detach();
NTSTATUS status = 0;
do
{
status = NtQueryObject(debugObject, ObjectTypeInformation, memory, sizeof(memory), 0);
}
while (status >= 0);
NtClose(debugObject);
}
std::cin.get();
return 0;
}
PoC uses two threads that share a pointer to a single OBJECT_TYPE_INFORMATION structure. Main thread constantly calls NtQueryObject to fill the structure with data while the other one constantly clears the TypeName.Buffer pointer in it. When debugging such PoC with HyperHide enabled it will sonner or later cause a BSOD. Otherwise it will loop indefinitely.
TitanHide seems to "fix" it by wrapping string comparison in __try / __except block and returning an error status to the caller but such approach can be used to detect that an anti-anti-debug tool is running.
I believe that the only proper solution is to allocate memory for a temporary OBJECT_TYPE_INFORMATION struct, call the original NtQueryObject with pointer to that memory, modify it accordingly and then memcpy its contents back into memory block provided by the caller. Similar thing should be done with ReturnLength param. This way a different user-mode thread won't be able to read and write data HyperHide driver hasn't finished working with.
The text was updated successfully, but these errors were encountered:
Hello,
I encountered a VMProtect protected executable that caused a BSOD inside HyperHide driver.
After looking at the minidump in WinDbg I found out that RtlEqualUnicodeString called from HookedNtQueryObject tried to dereference a null pointer which led to a crash.
Here is an excerpt output from WinDbg:
The line where string comparison happens:
HyperHide/HyperHideDrv/HookedFunctions.cpp
Line 572 in cbbf364
Seems like VMProtect zeros the
TypeName.Buffer
pointer inside theOBJECT_TYPE_INFORMATION
before HyperHide has a chance to compare the strings.I was able to replicate the issue with following PoC:
PoC uses two threads that share a pointer to a single
OBJECT_TYPE_INFORMATION
structure. Main thread constantly calls NtQueryObject to fill the structure with data while the other one constantly clears theTypeName.Buffer
pointer in it. When debugging such PoC with HyperHide enabled it will sonner or later cause a BSOD. Otherwise it will loop indefinitely.TitanHide seems to "fix" it by wrapping string comparison in __try / __except block and returning an error status to the caller but such approach can be used to detect that an anti-anti-debug tool is running.
I believe that the only proper solution is to allocate memory for a temporary
OBJECT_TYPE_INFORMATION
struct, call the original NtQueryObject with pointer to that memory, modify it accordingly and then memcpy its contents back into memory block provided by the caller. Similar thing should be done withReturnLength
param. This way a different user-mode thread won't be able to read and write data HyperHide driver hasn't finished working with.The text was updated successfully, but these errors were encountered: