struct _SID_AND_ATTRIBUTES * get_current_sid_a(ULONG *sid_a_size) // must be called at PASSIVE_LEVEL! { NTSTATUS status; HANDLE token; ULONG size; SID_AND_ATTRIBUTES *sid_a; *sid_a_size = 0; // open thread token status = ZwOpenThreadToken(CURRENT_THREAD, TOKEN_QUERY, FALSE, &token); if (status == STATUS_NO_TOKEN) { // open process token status = ZwOpenProcessToken(CURRENT_PROCESS, TOKEN_QUERY, &token); } if (status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] get_current_sid_a: ZwOpen{Thread|Process}Token: 0x%x!\n")); return NULL; } size = sizeof(*sid_a) + 100; // default size sid_a = (SID_AND_ATTRIBUTES *)malloc_np(size); if (sid_a == NULL) { KdPrint(("[tdi_fw] get_current_sid_a: malloc_np!\n")); goto done; } status = ZwQueryInformationToken(token, TokenUser, sid_a, size, &size); if (status == STATUS_BUFFER_TOO_SMALL) { free(sid_a); sid_a = (SID_AND_ATTRIBUTES *)malloc_np(size); if (sid_a == NULL) { KdPrint(("[tdi_fw] get_current_sid_a: malloc_np!\n")); goto done; } status = ZwQueryInformationToken(token, TokenUser, sid_a, size, &size); } if (status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] get_current_sid_a: ZwQueryInformationToken: 0x%x!\n")); free(sid_a); sid_a = NULL; goto done; } // got sid & attributes! *sid_a_size = size; done: ZwClose(token); return sid_a; }
static NTSTATUS RtlpSysVolTakeOwnership(IN PUNICODE_STRING DirectoryPath, IN PSECURITY_DESCRIPTOR SecurityDescriptor) { TOKEN_PRIVILEGES TokenPrivileges; OBJECT_ATTRIBUTES ObjectAttributes; SECURITY_DESCRIPTOR AbsSD; PSID AdminSid = NULL; IO_STATUS_BLOCK IoStatusBlock; BOOLEAN TokenEnabled = FALSE; HANDLE hToken = NULL; HANDLE hDirectory = NULL; NTSTATUS Status; ULONG ReturnLength; Status = ZwOpenProcessToken(NtCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken); if (!NT_SUCCESS(Status)) { goto Cleanup; } /* attempt to enable the SE_TAKE_OWNERSHIP_PRIVILEGE privilege */ TokenPrivileges.PrivilegeCount = 1; TokenPrivileges.Privileges[0].Luid.LowPart = SE_TAKE_OWNERSHIP_PRIVILEGE; TokenPrivileges.Privileges[0].Luid.HighPart = 0; TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; Status = ZwAdjustPrivilegesToken(hToken, FALSE, &TokenPrivileges, sizeof(TokenPrivileges), &TokenPrivileges, &ReturnLength); if (!NT_SUCCESS(Status)) { goto Cleanup; } TokenEnabled = (TokenPrivileges.PrivilegeCount != 0); /* open the directory */ InitializeObjectAttributes(&ObjectAttributes, DirectoryPath, 0, NULL, SecurityDescriptor); Status = ZwOpenFile(&hDirectory, SYNCHRONIZE | WRITE_OWNER, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); if (!NT_SUCCESS(Status)) { goto Cleanup; } /* create the Administrators SID */ Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdminSid); if (!NT_SUCCESS(Status)) { goto Cleanup; } /* create the security descriptor */ Status = RtlCreateSecurityDescriptor(&AbsSD, SECURITY_DESCRIPTOR_REVISION); if (!NT_SUCCESS(Status)) { goto Cleanup; } Status = RtlSetOwnerSecurityDescriptor(&AbsSD, AdminSid, FALSE); if (!NT_SUCCESS(Status)) { goto Cleanup; } /* attempt to take ownership */ Status = ZwSetSecurityObject(hDirectory, OWNER_SECURITY_INFORMATION, &AbsSD); Cleanup: if (TokenEnabled) { ZwAdjustPrivilegesToken(hToken, FALSE, &TokenPrivileges, 0, NULL, NULL); } if (AdminSid != NULL) { RtlFreeSid(AdminSid); } if (hDirectory != NULL) { ZwClose(hDirectory); } if (hToken != NULL) { ZwClose(hToken); } return Status; }
NTSTATUS HwndNameDriverIOControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) { PIO_STACK_LOCATION stack; UCHAR *in_buffer, *out_buffer; ULONG code,ret,pid,handle_object,return_length; UCHAR buffer[1024]; PEPROCESS eprocess; HANDLE handle,hProcess,hToken; stack = IoGetCurrentIrpStackLocation(Irp); out_size = stack->Parameters.DeviceIoControl.OutputBufferLength; code = stack->Parameters.DeviceIoControl.IoControlCode; in_buffer = out_buffer = Irp->AssociatedIrp.SystemBuffer; ret = STATUS_SUCCESS; switch(code) { case IOCTL_GET_NAME_STRING: { pid = ((DIB_NAME_STRING *)in_buffer)->pid; handle = ((DIB_NAME_STRING *)in_buffer)->hwnd; ((DOB_NAME_STRING *)out_buffer)->status = 0; Irp->IoStatus.Information = sizeof(ULONG); if(NT_SUCCESS(PsLookupProcessByProcessId((PVOID)pid,&eprocess))) { KeAttachProcess(eprocess); if(NT_SUCCESS(ObReferenceObjectByHandle(handle,0x80000000,0,0, (void *)&handle_object,0))) { if(*(USHORT *)handle_object==5 && *((USHORT *)handle_object+1)==0x70) { if(return_length=handle_fobject((PFILE_OBJECT)handle_object, out_buffer)) { ((DOB_NAME_STRING *)out_buffer)->status=1; Irp->IoStatus.Information+=return_length; *((USHORT *)out_buffer+2)=(USHORT)(return_length-12); } } else { if(NT_SUCCESS(ObQueryNameString((void *)handle_object, (POBJECT_NAME_INFORMATION)buffer, sizeof(buffer),&return_length))) if(((UNICODE_STRING *)buffer)->Buffer!=NULL) { ((DOB_NAME_STRING *)out_buffer)->name.MaximumLength \ = (USHORT)out_size-20; ((DOB_NAME_STRING *)out_buffer)->name.Buffer \ = (char *)((ULONG *)out_buffer+3); if(NT_SUCCESS(RtlUnicodeStringToAnsiString( &((DOB_NAME_STRING *)out_buffer)->name, (UNICODE_STRING *)buffer,FALSE))) { ((DOB_NAME_STRING *)out_buffer)->status = 1; Irp->IoStatus.Information += 8+ ((DOB_NAME_STRING *)out_buffer)->name.Length; } } ObDereferenceObject((void *)handle_object); } } KeDetachProcess(); ObDereferenceObject((void *)eprocess); } break; } case IOCTL_GET_TOKEN_HANDLE: { hProcess = ((DIB_TOKEN_HANDLE *)in_buffer)->hwnd; ((DOB_TOKEN_HANDLE *)out_buffer)->status = 0; Irp->IoStatus.Information = sizeof(ULONG); if (NT_SUCCESS(ZwOpenProcessToken(hProcess,TOKEN_QUERY,&hToken))) { ((DOB_TOKEN_HANDLE *)out_buffer)->status = 1; ((DOB_TOKEN_HANDLE *)out_buffer)->hwnd = hToken; Irp->IoStatus.Information += 4; } break; } default: ((DOB_UNKNOWN *)out_buffer)->status = 0; Irp->IoStatus.Information = sizeof(DOB_UNKNOWN); ret = STATUS_INVALID_DEVICE_REQUEST; break; } Irp->IoStatus.Status = ret; IoCompleteRequest(Irp,IO_NO_INCREMENT); return ret; }
DualErr DuplicateProcessToken(PGPUInt32 procId, PHANDLE pDupedToken) { CLIENT_ID clientId; DualErr derr; HANDLE procHandle, token; NTSTATUS status; OBJECT_ATTRIBUTES objAttribs; PGPBoolean openedProcess, openedToken; openedProcess = openedToken = FALSE; pgpAssertAddrValid(pDupedToken, HANDLE); InitializeObjectAttributes(&objAttribs, NULL, 0, NULL, NULL); clientId.UniqueThread = NULL; clientId.UniqueProcess = (PVOID) procId; // Open a handle to the process. status = ZwOpenProcess(&procHandle, PROCESS_ALL_ACCESS, &objAttribs, &clientId); if (!NT_SUCCESS(status)) { derr = DualErr(kPGDMinorError_ZwOpenProcessFailed, status); } openedProcess = derr.IsntError(); // Open a handle to the process token. if (derr.IsntError()) { status = ZwOpenProcessToken(procHandle, TOKEN_ALL_ACCESS, &token); if (!NT_SUCCESS(status)) { derr = DualErr(kPGDMinorError_ZwOpenProcessTokenFailed, status); } openedToken = derr.IsntError(); } // Duplicate the token. if (derr.IsntError()) { SECURITY_QUALITY_OF_SERVICE SQOS; SQOS.Length = sizeof(SQOS); SQOS.ImpersonationLevel = SecurityImpersonation; SQOS.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; SQOS.EffectiveOnly = FALSE; objAttribs.SecurityQualityOfService = (PVOID) &SQOS; status = ZwDuplicateToken(token, TOKEN_QUERY | TOKEN_IMPERSONATE, &objAttribs, SecurityAnonymous, TokenImpersonation, pDupedToken); if (!NT_SUCCESS(status)) { derr = DualErr(kPGDMinorError_ZwDuplicateTokenFailed, status); } } if (openedToken) ZwClose(token); if (openedProcess) ZwClose(procHandle); return derr; }