mirror of
https://github.com/mirkobrombin/raven.git
synced 2026-11-05 21:56:33 +00:00
The PEB names a free FastPebLock that RtlEnterCriticalSection and RtlLeaveCriticalSection take and release; a program's own critical section is initialized, entered again by its owner, tried and deleted through ntdll. Assisted-by: Claude Code:claude-opus-5-5 AI-Scope: the test client and its registration (cherry picked from commit 6ca000e45c77933d5ffa46c8e18fb71698d6a116)
34 lines
1.6 KiB
C
34 lines
1.6 KiB
C
#include <windows.h>
|
|
#include <intrin.h>
|
|
|
|
// ntdll's critical sections, which the guest RTL serves as it serves kernel32's: the PEB names a free one at FastPebLock, which code
|
|
// that reads the process parameters takes, and a program's own can be initialized, entered again by its owner, tried and deleted.
|
|
// Returns 0, or the number of the check that failed.
|
|
typedef LONG NTSTATUS;
|
|
__declspec(dllimport) NTSTATUS NTAPI RtlEnterCriticalSection(CRITICAL_SECTION *);
|
|
__declspec(dllimport) NTSTATUS NTAPI RtlLeaveCriticalSection(CRITICAL_SECTION *);
|
|
__declspec(dllimport) BOOLEAN NTAPI RtlTryEnterCriticalSection(CRITICAL_SECTION *);
|
|
__declspec(dllimport) NTSTATUS NTAPI RtlInitializeCriticalSection(CRITICAL_SECTION *);
|
|
__declspec(dllimport) NTSTATUS NTAPI RtlDeleteCriticalSection(CRITICAL_SECTION *);
|
|
|
|
int raven_entry(void)
|
|
{
|
|
CRITICAL_SECTION *peb_lock = *(CRITICAL_SECTION **)(__readgsqword(0x60) + 0x38);
|
|
if (!peb_lock || peb_lock->LockCount != -1 || peb_lock->OwningThread)
|
|
return 1;
|
|
if (RtlEnterCriticalSection(peb_lock) != 0 || peb_lock->OwningThread != (HANDLE)(ULONG_PTR)GetCurrentThreadId() ||
|
|
RtlLeaveCriticalSection(peb_lock) != 0 || peb_lock->OwningThread)
|
|
return 2;
|
|
static CRITICAL_SECTION own;
|
|
if (RtlInitializeCriticalSection(&own) != 0 || RtlEnterCriticalSection(&own) != 0 || RtlEnterCriticalSection(&own) != 0 ||
|
|
own.RecursionCount != 2)
|
|
return 3;
|
|
if (!RtlTryEnterCriticalSection(&own) || own.RecursionCount != 3)
|
|
return 4;
|
|
for (int index = 0; index < 3; ++index)
|
|
RtlLeaveCriticalSection(&own);
|
|
if (own.OwningThread || own.RecursionCount || RtlDeleteCriticalSection(&own) != 0)
|
|
return 5;
|
|
return 0;
|
|
}
|