Skip to content

Commit dbbfa63

Browse files
committed
fix: avoid APC mismatch in caller signature lookup
Use SeLocateProcessImageName instead of opening the current process and querying ProcessImageFileName so signature checks no longer destabilize system-call exit paths and trigger APC_INDEX_MISMATCH crashes. Made-with: Cursor
1 parent 19b2f27 commit dbbfa63

1 file changed

Lines changed: 25 additions & 59 deletions

File tree

src/signature.cpp

Lines changed: 25 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,12 @@
1515
#endif
1616

1717
extern "C" {
18-
NTSTATUS NTAPI ZwQueryInformationProcess(
19-
HANDLE ProcessHandle,
20-
ULONG ProcessInformationClass,
21-
PVOID ProcessInformation,
22-
ULONG ProcessInformationLength,
23-
PULONG ReturnLength
18+
NTSTATUS NTAPI SeLocateProcessImageName(
19+
_In_ PEPROCESS Process,
20+
_Outptr_ PUNICODE_STRING* pImageFileName
2421
);
25-
26-
NTSTATUS NTAPI ObOpenObjectByPointer(
27-
PVOID Object,
28-
ULONG HandleAttributes,
29-
PACCESS_STATE PassedAccessState,
30-
ACCESS_MASK DesiredAccess,
31-
POBJECT_TYPE ObjectType,
32-
KPROCESSOR_MODE AccessMode,
33-
PHANDLE Handle
34-
);
35-
36-
extern POBJECT_TYPE *PsProcessType;
3722
}
3823

39-
#define ProcessImageFileName 27
4024

4125
static PVOID SigAllocMem(SIZE_T Size)
4226
{
@@ -383,53 +367,35 @@ static BOOLEAN ExtractMessageDigest(
383367

384368
NTSTATUS GetCallerImagePath(PUNICODE_STRING ImagePath)
385369
{
386-
NTSTATUS status;
387-
HANDLE processHandle = NULL;
388-
PEPROCESS process = NULL;
389-
PVOID buffer = NULL;
390-
ULONG returnLength = 0;
391-
392-
process = IoGetCurrentProcess();
393-
if (!process) return STATUS_UNSUCCESSFUL;
394-
395-
status = ObOpenObjectByPointer(
396-
process, OBJ_KERNEL_HANDLE, NULL, 0x0400,
397-
*PsProcessType, KernelMode, &processHandle);
398-
if (!NT_SUCCESS(status)) {
399-
SigLog("ObOpenObjectByPointer failed: 0x%08X", status);
400-
return status;
370+
if (!ImagePath || !ImagePath->Buffer || ImagePath->MaximumLength < sizeof(WCHAR)) {
371+
return STATUS_INVALID_PARAMETER;
401372
}
402373

403-
status = ZwQueryInformationProcess(
404-
processHandle, ProcessImageFileName, NULL, 0, &returnLength);
405-
if (status != STATUS_INFO_LENGTH_MISMATCH || returnLength == 0) {
406-
ZwClose(processHandle);
407-
return STATUS_UNSUCCESSFUL;
408-
}
374+
ImagePath->Length = 0;
375+
ImagePath->Buffer[0] = L'\0';
409376

410-
buffer = SigAllocMem(returnLength);
411-
if (!buffer) {
412-
ZwClose(processHandle);
413-
return STATUS_INSUFFICIENT_RESOURCES;
377+
PUNICODE_STRING processImagePath = NULL;
378+
NTSTATUS status = SeLocateProcessImageName(IoGetCurrentProcess(), &processImagePath);
379+
if (!NT_SUCCESS(status) || !processImagePath || !processImagePath->Buffer) {
380+
SigLog("SeLocateProcessImageName failed: 0x%08X", status);
381+
if (processImagePath) {
382+
ExFreePool(processImagePath);
383+
}
384+
return !NT_SUCCESS(status) ? status : STATUS_UNSUCCESSFUL;
414385
}
415386

416-
status = ZwQueryInformationProcess(
417-
processHandle, ProcessImageFileName, buffer, returnLength, &returnLength);
418-
if (NT_SUCCESS(status)) {
419-
PUNICODE_STRING srcPath = (PUNICODE_STRING)buffer;
420-
if (ImagePath->MaximumLength >= srcPath->Length + sizeof(WCHAR)) {
421-
RtlCopyMemory(ImagePath->Buffer, srcPath->Buffer, srcPath->Length);
422-
ImagePath->Length = srcPath->Length;
423-
ImagePath->Buffer[ImagePath->Length / sizeof(WCHAR)] = L'\0';
424-
SigLog("Caller image path: %wZ", ImagePath);
425-
} else {
426-
status = STATUS_BUFFER_TOO_SMALL;
427-
}
387+
if (ImagePath->MaximumLength < processImagePath->Length + sizeof(WCHAR)) {
388+
ExFreePool(processImagePath);
389+
return STATUS_BUFFER_TOO_SMALL;
428390
}
429391

430-
SigFreeMem(buffer);
431-
ZwClose(processHandle);
432-
return status;
392+
RtlCopyMemory(ImagePath->Buffer, processImagePath->Buffer, processImagePath->Length);
393+
ImagePath->Length = processImagePath->Length;
394+
ImagePath->Buffer[ImagePath->Length / sizeof(WCHAR)] = L'\0';
395+
SigLog("Caller image path: %wZ", ImagePath);
396+
397+
ExFreePool(processImagePath);
398+
return STATUS_SUCCESS;
433399
}
434400

435401
// ================================================================

0 commit comments

Comments
 (0)