Exemplo n.º 1
0
NTSTATUS GetObjectName(PVOID Object, PUNICODE_STRING *pObjectName)
{
    POBJECT_NAME_INFORMATION ObjectNameInfo;
    NTSTATUS Status;
    ULONG ReturnLength;

    ObjectNameInfo = NULL;
    Status = ObQueryNameString(Object, ObjectNameInfo, 0, &ReturnLength);
    if (!NT_SUCCESS(Status) && (Status != STATUS_INFO_LENGTH_MISMATCH)) {
        KLErr("ObQueryNameString Object %p Status 0x%x", Object, Status);
        return Status;
    }

    ObjectNameInfo = NpAlloc(ReturnLength, MTAG_GEN);
    if (!ObjectNameInfo)
        return STATUS_INSUFFICIENT_RESOURCES;

    Status = ObQueryNameString(Object, ObjectNameInfo, ReturnLength, &ReturnLength);
    if (!NT_SUCCESS(Status)) {
        KLErr("ObQueryNameString Object %p Status 0x%x", Object, Status);
        NpFree(ObjectNameInfo, MTAG_GEN);
        return Status;
    }

    *pObjectName = &ObjectNameInfo->Name;
    return Status;
}
Exemplo n.º 2
0
/****************************************************************************\
 *
 * NT_QueryObjectName()
 *
 * DESCRIPTION:
 *
 *  Queries the name of the object (such as a device or file object).
 *  The caller must deallocate the return value with MEM_Free. The
 *  returned string (if not NULL) is guaranteed to be NULL terminated.
 *
 * ARGUMENTS:
 *
 *  obj - the object whose name to query
 *
\****************************************************************************/
OBJECT_NAME_INFORMATION * NT_QueryObjectName(PVOID obj)
{
    ULONG len = 0;
    NTSTATUS status = ObQueryNameString(obj, NULL, 0, &len);
    ASSERT(status != STATUS_SUCCESS);

    /*  Unlike the rest of the system, ObQueryNameString returns
     *  STATUS_INFO_LENGTH_MISMATCH instead of STATUS_BUFFER_TOO_SMALL 
     *  when passed too small a buffer. We expect to get this error here.
     *  Anything else we can't handle.
     */
    if (status == STATUS_INFO_LENGTH_MISMATCH && len > 0) {
        OBJECT_NAME_INFORMATION * name = MEM_Alloc(len + sizeof(WCHAR));
        if (name) {
            /* NOTE: ObQueryNameString may return STATUS_SUCCESS and empty
             * string for unnamed objects */
            status = ObQueryNameString(obj, name, len, &len);
            if (NT_SUCCESS(status) && name->Name.MaximumLength > 0) {
                /* make sure it's NULL terminated */
                ULONG Last = name->Name.Length/sizeof(name->Name.Buffer[0]);
                name->Name.Buffer[Last] = 0; 
                return name;
            }
            MEM_Free(name);
        }
    }
    return NULL;
}
Exemplo n.º 3
0
static NTSTATUS _GetObjectName(_In_ PVOID Object, _Out_ POBJECT_NAME_INFORMATION *ObjectName)
{
	ULONG objectNameLen = 0;
	POBJECT_NAME_INFORMATION tmpObjectName = NULL;
	NTSTATUS status = STATUS_UNSUCCESSFUL;
	DEBUG_ENTER_FUNCTION("Object=0x%p; ObjectName=0x%p", Object, ObjectName);

	*ObjectName = NULL;
	status = ObQueryNameString(Object, NULL, 0, &objectNameLen);
	if (status == STATUS_INFO_LENGTH_MISMATCH) {
		objectNameLen += sizeof(OBJECT_NAME_INFORMATION);
		tmpObjectName = (POBJECT_NAME_INFORMATION)HeapMemoryAllocPaged(objectNameLen);
		if (tmpObjectName != NULL) {
			status = ObQueryNameString(Object, tmpObjectName, objectNameLen, &objectNameLen);
			if (NT_SUCCESS(status))
				*ObjectName = tmpObjectName;

			if (!NT_SUCCESS(status))
				HeapMemoryFree(tmpObjectName);
		} else status = STATUS_INSUFFICIENT_RESOURCES;
	} else if (NT_SUCCESS(status)) {
		objectNameLen = sizeof(OBJECT_NAME_INFORMATION);
		tmpObjectName = (POBJECT_NAME_INFORMATION)HeapMemoryAllocPaged(objectNameLen);
		if (tmpObjectName != NULL) {
			memset(tmpObjectName, 0, objectNameLen);
			*ObjectName = tmpObjectName;
			status = STATUS_SUCCESS;
		} else status = STATUS_INSUFFICIENT_RESOURCES;
	}

	DEBUG_EXIT_FUNCTION("0x%x, *ObjectName=0x%p", status, *ObjectName);
	return status;
}
Exemplo n.º 4
0
NTSTATUS
FltpGetObjectName(_In_ PVOID Object,
                  _Inout_ PUNICODE_STRING ObjectName)
{
    POBJECT_NAME_INFORMATION ObjectNameInfo = NULL;
    OBJECT_NAME_INFORMATION LocalNameInfo;
    ULONG ReturnLength;
    NTSTATUS Status;

    if (ObjectName == NULL)
        return STATUS_INVALID_PARAMETER;

    /* Get the size of the buffer required to hold the nameinfo */
    Status = ObQueryNameString(Object,
                              &LocalNameInfo,
                              sizeof(LocalNameInfo),
                              &ReturnLength);
    if (Status == STATUS_INFO_LENGTH_MISMATCH)
    {
        ObjectNameInfo = ExAllocatePoolWithTag(PagedPool,
                                               ReturnLength,
                                               FM_TAG_UNICODE_STRING);
        if (ObjectNameInfo == NULL) return STATUS_INSUFFICIENT_RESOURCES;

        /* Get the actual name info now we have the buffer to hold it */
        Status = ObQueryNameString(Object,
                                    ObjectNameInfo,
                                    ReturnLength,
                                    &ReturnLength);
    }


    if (NT_SUCCESS(Status))
    {
        /* Make sure the buffer we were passed is large enough to hold the string */
        if (ObjectName->MaximumLength < ObjectNameInfo->Name.Length)
        {
            /* It wasn't, let's enlarge the buffer */
            Status = FltpReallocateUnicodeString(ObjectName,
                                                 ObjectNameInfo->Name.Length,
                                                 FALSE);
            
        }

        if (NT_SUCCESS(Status))
        {
            /* Copy the object name into the callers buffer */
            RtlCopyUnicodeString(ObjectName, &ObjectNameInfo->Name);
        }
    }

    if (ObjectNameInfo)
    {
        ExFreePoolWithTag(ObjectNameInfo, FM_TAG_UNICODE_STRING);
    }

    return Status;
}
NTSTATUS
ImScsiGetControllerObject()
{
    PDEVICE_OBJECT dev_obj;

    if (pMPDrvInfoGlobal->ControllerObject != NULL)
    {
        return STATUS_SUCCESS;
    }

    KdBreakPoint();

    for (dev_obj = pMPDrvInfoGlobal->pDriverObj->DeviceObject;
        dev_obj != NULL;
#pragma warning(suppress: 28175)
        dev_obj = dev_obj->NextDevice)
    {
        if (dev_obj->DeviceType == FILE_DEVICE_CONTROLLER)
        {
            ObReferenceObject(dev_obj);

            pMPDrvInfoGlobal->ControllerObject = dev_obj;

#if DBG
            {
                POBJECT_NAME_INFORMATION objstr = (POBJECT_NAME_INFORMATION)
                    ExAllocatePoolWithTag(NonPagedPool,
                        1024, MP_TAG_GENERAL);

                if (objstr != NULL)
                {
                    ULONG retl;
                    NTSTATUS status;

                    status = ObQueryNameString(pMPDrvInfoGlobal->ControllerObject,
                        objstr, 1024, &retl);

                    if (NT_SUCCESS(status))
                    {
                        DbgPrint("PhDskMnt::ImScsiGetControllerObject: Successfully opened '%wZ'.\n",
                            &objstr->Name);
                    }

                    ExFreePoolWithTag(objstr, MP_TAG_GENERAL);
                }
            }
#endif

            return STATUS_SUCCESS;
        }
    }
    

    DbgPrint("PhDskMnt::ImScsiGetControllerObject: Could not locate SCSI adapter device object by name.\n");

    return STATUS_DEVICE_DOES_NOT_EXIST;
}
Exemplo n.º 6
0
BOOLEAN GetRegistryObjectCompleteName(PUNICODE_STRING pRegistryPath, PUNICODE_STRING pPartialRegistryPath, PVOID pRegistryObject)
{
     BOOLEAN foundCompleteName = FALSE;
     BOOLEAN partial = FALSE;
     if((!MmIsAddressValid(pRegistryObject)) ||
     (pRegistryObject == NULL))
	 {
      return FALSE;
	 }
      /* Check to see if the partial name is really the complete name */
     if(pPartialRegistryPath != NULL)
	 {
        if((((pPartialRegistryPath->Buffer[0] == '\\') || (pPartialRegistryPath->Buffer[0] == '%')) ||
         ((pPartialRegistryPath->Buffer[0] == 'T') && (pPartialRegistryPath->Buffer[1] == 'R') && (pPartialRegistryPath->Buffer[2] == 'Y') && (pPartialRegistryPath->Buffer[3] == '\\'))) )
		{
           RtlUnicodeStringCopy(pRegistryPath, pPartialRegistryPath);
           partial = TRUE;
           foundCompleteName = TRUE;
		}
	 }

     if(!foundCompleteName)
	 {
         /* Query the object manager in the kernel for the complete name */
        NTSTATUS status;
       ULONG returnedLength;
       PUNICODE_STRING pObjectName = NULL;

       status = ObQueryNameString(pRegistryObject, (POBJECT_NAME_INFORMATION)pObjectName, 0, &returnedLength );
       if(status == STATUS_INFO_LENGTH_MISMATCH)
	   {
         pObjectName = ExAllocatePoolWithTag(NonPagedPool, returnedLength, REGISTRY_POOL_TAG); 
         status = ObQueryNameString(pRegistryObject, (POBJECT_NAME_INFORMATION)pObjectName, returnedLength, &returnedLength );
         if(NT_SUCCESS(status))
		 {
            RtlUnicodeStringCopy(pRegistryPath, pObjectName);
            foundCompleteName = TRUE;
		 }
          ExFreePoolWithTag(pObjectName, REGISTRY_POOL_TAG);
	   }
	 }
      //ASSERT(foundCompleteName == TRUE);
      return foundCompleteName;
}
Exemplo n.º 7
0
NTSTATUS NewZwMapViewOfSection(
			       HANDLE SectionHandle,
			       HANDLE  ProcessHandle,
			       PVOID  *BaseAddress,
			       ULONG  ZeroBits,
			       ULONG  CommitSize,
			       PLARGE_INTEGER  SectionOffset,
			       PSIZE_T  ViewSize,
			       SECTION_INHERIT  InheritDisposition,
			       ULONG  AllocationType,
			       ULONG  Protect
			       ) {
  NTSTATUS status;
#ifdef DEBUG
  NTSTATUS rtn;
  PVOID Object;
  WCHAR buf[1024];

  rtn=
    ObReferenceObjectByHandle(SectionHandle,
			      0,
			      0,
			      KernelMode,
			      &Object,
			      NULL);
    
  if (rtn==STATUS_SUCCESS) {
    int bytes;
    rtn=ObQueryNameString(Object,
			  (PUNICODE_STRING)buf,
			  sizeof(buf),
			  &bytes);
    ObDereferenceObject(Object);
    if (rtn==STATUS_SUCCESS) {
      WCHAR *p = ((PUNICODE_STRING)buf)->Buffer;
      debugOutput(L"MapViewOfSection ");
      debugOutput(p);

      if ((Protect&PAGE_READWRITE) || 
	  (Protect&PAGE_EXECUTE_READWRITE)) {
	swprintf(buf,L" protect: 0x%lx\n", Protect);
	debugOutput(buf);
      }
      debugOutput(L"\n");
    }
  }
#endif

  status = (OldZwMapViewOfSection)(SectionHandle, ProcessHandle,
				   BaseAddress, ZeroBits,
				   CommitSize, SectionOffset,
				   ViewSize, InheritDisposition,
				   AllocationType,
				   Protect);
  return status;
}
Exemplo n.º 8
0
NTSTATUS RegSetValueKey( IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName,
						IN ULONG TitleIndex, IN ULONG Type, 
						IN PVOID Data, IN ULONG DataSize )
{
	WCHAR			szFullPath[MAXPATHLEN]	= {0};		
	PVOID			pKeyObj					= NULL;
	ULONG			ulRet					= 0;
	PUNICODE_STRING	fullUniName				= NULL;
	int				i;
	ULONG			nAllowd					= 1;
	WCHAR			szValueName[256]		= {0};
	WCHAR			szValue[512]			= {0};

	if(FALSE == IsGuardStart())
		goto allowed;
	if(STATUS_SUCCESS == ObReferenceObjectByHandle(KeyHandle, 0, NULL, KernelMode, &pKeyObj, NULL))
 	{
		PINNERPACK_LIST			pList;
		LONG					nSubType		= 0;

 		fullUniName = ExAllocateFromPagedLookasideList(&gRegMonLooaside);
		if(NULL == fullUniName)
			goto allowed;

 		fullUniName->MaximumLength = MAXPATHLEN * 2;
 		ObQueryNameString(pKeyObj, (POBJECT_NAME_INFORMATION)fullUniName, MAXPATHLEN, &ulRet);
 		ObDereferenceObject(pKeyObj);
		// 转换路径
		ConvertKeyPath(szFullPath, fullUniName->Buffer, MAXPATHLEN);
		ExFreeToPagedLookasideList(&gRegMonLooaside, fullUniName);
		// 复制路径
		wcsncpy(szValueName, (NULL != ValueName)?ValueName->Buffer:L""
			, (NULL != ValueName)?ValueName->Length:0);
		// 比较路径
		if(FALSE == IsRegGuardPath(szFullPath, szValueName, &nSubType))
			goto allowed;
		if(REG_SZ == Type)
		{
			wcsncpy(szValue, Data, arrayof(szValueName));
		}
		// 到用户求请
		if(FALSE != CheckRequestIsAllowed(MAKEGUARDTYPE(MASK_GUARDLITE_REGMON, nSubType)
			, szFullPath, szValueName, szValue))
		{
			goto allowed;
		}
	}
	return STATUS_ACCESS_DENIED;
allowed:
	return RealRegSetValueKey(KeyHandle, ValueName, TitleIndex, Type, Data, DataSize);
}
Exemplo n.º 9
0
int getFullPath(PWCHAR buf, USHORT bufsize,
		POBJECT_ATTRIBUTES oa) {
  NTSTATUS rtn;
  PVOID Object;
  int curlen=0;

  buf[0]=L'\0';
  if (!oa) return 0;

  if (oa->RootDirectory != NULL) {
    rtn=
      ObReferenceObjectByHandle(oa->RootDirectory,
				0,
				0,
				KernelMode,
				&Object,
				NULL);

    if (rtn==STATUS_SUCCESS) {
      int bytes;
      rtn=ObQueryNameString(Object,
			    (PUNICODE_STRING)buf,
			    bufsize,
			    &bytes);
      ObDereferenceObject(Object);
      if (rtn==STATUS_SUCCESS) {
	WCHAR *p = ((PUNICODE_STRING)buf)->Buffer, *q=buf;
	USHORT len = (((PUNICODE_STRING)buf)->Length)/sizeof(WCHAR);
	if ((len+2)*sizeof(WCHAR)<bufsize) {
	  while (len-->0 && *p!=L'\0') {
	    *q++ = *p++;
	    ++curlen;
	  }
	  *q++=OBJ_NAME_PATH_SEPARATOR;
	  ++curlen;
	}
	*q = L'\0';
      }
    }
  }

  if (oa->ObjectName &&
      oa->Length+(curlen+1)*sizeof(WCHAR) < bufsize) {
    curlen += uwcscat(buf+curlen, oa->ObjectName);
  }
  else *buf = L'\0';
  return curlen;
}
Exemplo n.º 10
0
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;
}
Exemplo n.º 11
0
NTSTATUS
PerfInfoFileNameRunDown (
    )
/*++

Routine Description:

    This routine walks through multiple lists to collect the names of all files.
    It includes:
    1. Handle table: for all file handles
    2. Process Vad for all file objects mapped in VAD.
    3. MmUnusedSegment List
    4. CcDirtySharedCacheMapList & CcCleanSharedCacheMapList

Arguments:

    None.

--*/
{
    PEPROCESS Process;
    ULONG AllocateBytes;
    PFILE_OBJECT *FileObjects;
    PFILE_OBJECT *File;
    PERFINFO_ENTRY_TABLE HashTable;
    extern POBJECT_TYPE IoFileObjectType;
    POBJECT_NAME_INFORMATION FileNameInfo;
    ULONG ReturnLen;
    NTSTATUS Status;
    LONG i;

    //
    // First create a temporary hash table to build the list of
    // files to walk through
    //
    AllocateBytes = PAGE_SIZE + sizeof(PVOID) * IoFileObjectType->TotalNumberOfObjects;

    //
    // Run up to page boundary
    //
    AllocateBytes = PERFINFO_ROUND_UP(AllocateBytes, PAGE_SIZE);

    HashTable.Table = ExAllocatePoolWithTag(NonPagedPool, AllocateBytes, PERFPOOLTAG);

    if (HashTable.Table == NULL) {
        return STATUS_NO_MEMORY;
    } else {
        //
        // Allocation Succeeded
        //
        HashTable.NumberOfEntries = AllocateBytes / sizeof(PVOID);
        RtlZeroMemory(HashTable.Table, AllocateBytes);
    }

    //
    // Allocate Buffers for FileNames
    //
    FileNameInfo = ExAllocatePoolWithTag (NonPagedPool, MAX_FILENAME_TO_LOG, PERFPOOLTAG);

    if (FileNameInfo == NULL) {
        ExFreePool(HashTable.Table);
        return STATUS_NO_MEMORY;
    }

    //
    // Walk through the Cc SharedCacheMapList
    //

    CcPerfFileRunDown(&HashTable);

    //
    // Now, walk through each process
    //
    for (Process = PsGetNextProcess (NULL);
         Process != NULL;
         Process = PsGetNextProcess (Process)) {

        //
        // First Walk the VAD tree
        //

        FileObjects = MmPerfVadTreeWalk(Process);
        if (FileObjects != NULL) {
            File = FileObjects;
            while (*File != NULL) {
                PerfInfoAddToFileHash(&HashTable, *File);
                ObDereferenceObject(*File);
                File += 1;
            }
            ExFreePool(FileObjects);
        }

        //
        // Next, walk the handle Table
        //
        ObPerfHandleTableWalk (Process, &HashTable);
    }

    //
    // Walk through the kernel handle table;
    //
    ObPerfHandleTableWalk(NULL, &HashTable);

    //
    // Walk through the MmUnusedSegmentList;
    //

    FileObjects = MmPerfUnusedSegmentsEnumerate();

    if (FileObjects != NULL) {
        File = FileObjects;
        while (*File != NULL) {
            PerfInfoAddToFileHash(&HashTable, *File);
            ObDereferenceObject(*File);
            File += 1;
        }
        ExFreePool(FileObjects);
    }

    //
    // Now we have walked through all list.
    // Log the filenames and dereference the objects.
    //

    for (i = 0; i < HashTable.NumberOfEntries; i++) {
        if (HashTable.Table[i]) {
            PFILE_OBJECT FileObject = HashTable.Table[i];

            Status = ObQueryNameString( FileObject,
                                        FileNameInfo,
                                        MAX_FILENAME_TO_LOG,
                                        &ReturnLen
                                        );

            if (NT_SUCCESS (Status)) {
                PerfInfoLogFileName(FileObject, &FileNameInfo->Name);
            }
            ObDereferenceObject(FileObject);
        }
    }

    //
    // Free the pool reserved.
    //
    ExFreePool(HashTable.Table);
    ExFreePool(FileNameInfo);

    return STATUS_SUCCESS;
}
Exemplo n.º 12
0
NTSTATUS RegistryCallback(IN PVOID CallbackContext, 
						  IN PVOID  Argument1, 
						  IN PVOID  Argument2)
{
	NTSTATUS            			  	ntStatus; 
	PDEVICE_CONTEXT 					pContext = (PDEVICE_CONTEXT) CallbackContext;
	REG_NOTIFY_CLASS 					Action   = (REG_NOTIFY_CLASS) Argument1;
	POBJECT_NAME_INFORMATION 			ObjectNameInfo;
	ULONG 								ReturnLength,ReturnLength1;
	UNICODE_STRING      				*path_str = NULL;
	UNICODE_STRING    				    *key = NULL;
	UNICODE_STRING   				    *value = NULL;
	UNICODE_STRING        				*data = NULL;
	UNICODE_STRING				        unicode_registry ;
	UNICODE_STRING        				KeyInformation;
	UNICODE_STRING 				       *unicode_test=NULL;
	ANSI_STRING 						key_ansi;
	ANSI_STRING 						value_ansi;
	ANSI_STRING 						temp_ansi;
	ANSI_STRING 						pathname_ansi;
	size_t 								size = 9;
	ProcessInformationFile 				process;
	ProcessInformation 					process_uni;
	char 								security_sbject[525];
	char 								droit[324];
	char								droit_temp[300];
	char 								buf_temp[1024];
	int 								bool =0;
	
	PAGED_CODE();
	if( ExGetPreviousMode() == KernelMode)
		return STATUS_SUCCESS;
		
	RtlZeroMemory(&security_sbject, sizeof(security_sbject));
	RtlZeroMemory(&droit, sizeof(droit));
	RtlZeroMemory(&droit_temp, sizeof(droit_temp));
	RtlZeroMemory(&buf_temp, sizeof(buf_temp));
	

	switch (Action) 
	{

		case RegNtPreDeleteKey:
			{

				PREG_DELETE_KEY_INFORMATION pInfo = (PREG_DELETE_KEY_INFORMATION) Argument2;
				__try{
						ntStatus = ObQueryNameString(pInfo->Object, (POBJECT_NAME_INFORMATION)key, 0, &ReturnLength);
						key = (PUNICODE_STRING)ExAllocatePoolWithTag(NonPagedPool, ReturnLength, 0);
						if (ntStatus == STATUS_INFO_LENGTH_MISMATCH)
						{	
							if (key)
							{
								ntStatus = ObQueryNameString(pInfo->Object, (POBJECT_NAME_INFORMATION)key, ReturnLength, &ReturnLength);
							}
							else
								return STATUS_SUCCESS;
						}
						
						process = GetProcessInfoFile();
						if(process.pid == 4)
						{
							sprintf(security_sbject,"system_u:system_r:system_t");
							RtlZeroMemory(&process.pathname, sizeof(process.pathname));
							sprintf(process.pathname, "System");
						}
						else
							GetSecurityContextSubject(process, security_sbject);
							
						GetSecurityContextSubject(process, security_sbject);
						RtlUnicodeStringToAnsiString(&key_ansi, key, TRUE);
						sprintf(droit,"delete ");
						bool = 1;
						
				}
				__except(EXCEPTION_EXECUTE_HANDLER)
				{
					ntStatus=GetExceptionCode();
					DbgPrint("Exception RegNtPreDeleteKey : %x\n", ntStatus);
				}
				
				ExFreePoolWithTag(key,0);
				break;
			}

		case RegNtPreCreateKeyEx:
			{
				PREG_CREATE_KEY_INFORMATION pInfo = (PREG_CREATE_KEY_INFORMATION) Argument2;
				__try{

					ntStatus = ObQueryNameString(pInfo->RootObject, (POBJECT_NAME_INFORMATION)path_str, 0, &ReturnLength);
					path_str = (PUNICODE_STRING)ExAllocatePoolWithTag(NonPagedPool, ReturnLength, 0);
					if (ntStatus == STATUS_INFO_LENGTH_MISMATCH)
					{
						if (path_str)
						{
							ntStatus = ObQueryNameString(pInfo->RootObject, (POBJECT_NAME_INFORMATION)path_str, ReturnLength, &ReturnLength);
						}
						else
								return STATUS_SUCCESS;
					}
					
					process_uni = GetProcessInfo();	
					if(process_uni.pid == 4)
								return STATUS_SUCCESS;
							else
								GetSecurityContextSubjectReg(process_uni.name,security_sbject);
							
					GetDroit(droit, pInfo);
					//sprintf(droit, "create_key_function %s", droit_temp);
					RtlUnicodeStringToAnsiString(&key_ansi, pInfo->CompleteName, TRUE);
					
					WriteInLog(droit,process_uni.pid, process_uni.name, process_uni.ppid , key_ansi.Buffer ,security_sbject , "system_u:object_r:registry_t", "registry",0,0);
				}
				__except(EXCEPTION_EXECUTE_HANDLER)
				{
					ntStatus=GetExceptionCode();
					DbgPrint("Exception RegNtPreCreateKeyEx : %x\n", ntStatus);
				}
				// ExFreePoolWithTag(path_str,0);
				break;
			}

		case RegNtSetValueKey:
			{
				PREG_SET_VALUE_KEY_INFORMATION pInfo = (PREG_SET_VALUE_KEY_INFORMATION) Argument2;
				
				__try{
					ntStatus = ObQueryNameString(pInfo->Object, (POBJECT_NAME_INFORMATION)key, 0, &ReturnLength);
					key = (PUNICODE_STRING)ExAllocatePoolWithTag(NonPagedPool, ReturnLength, 1);
					if (ntStatus == STATUS_INFO_LENGTH_MISMATCH)
					{
						if (key)
						{
							ntStatus = ObQueryNameString(pInfo->Object, (POBJECT_NAME_INFORMATION)key, ReturnLength, &ReturnLength);
							process_uni = GetProcessInfo();	
							
							if(process_uni.pid == 4)
								return STATUS_SUCCESS;
							else
								GetSecurityContextSubjectReg(process_uni.name,security_sbject);
							
							RtlUnicodeStringToAnsiString(&key_ansi, key, TRUE);
							sprintf(droit, "setvaluekey "); 
							DbgPrint("%wZ \n", pInfo->ValueName);
							WriteInLog(droit,process_uni.pid, process_uni.name, process_uni.ppid , key_ansi.Buffer ,security_sbject , "system_u:object_r:registry_t", "registry",0,0);
						}
					}
					if(key)
						ExFreePoolWithTag(key,1);
					
				}
				__except(EXCEPTION_EXECUTE_HANDLER)
				{
					ntStatus=GetExceptionCode();
					DbgPrint("Exception RegNtSetValueKey : %x\n", ntStatus);
				}
				break;
			}
		case RegNtQueryValueKey:
			{
				PREG_QUERY_VALUE_KEY_INFORMATION pInfo = (PREG_QUERY_VALUE_KEY_INFORMATION) Argument2;
				
				__try
				{
					ntStatus = ObQueryNameString(pInfo->Object, (POBJECT_NAME_INFORMATION)key, 0, &ReturnLength);
					key = (PUNICODE_STRING)ExAllocatePoolWithTag(NonPagedPool, ReturnLength, 1);
					if (ntStatus == STATUS_INFO_LENGTH_MISMATCH)
					{
						if (key)
						{
							ntStatus = ObQueryNameString(pInfo->Object, (POBJECT_NAME_INFORMATION)key, ReturnLength, &ReturnLength);
							
							process_uni = GetProcessInfo();	
							
							if(process_uni.pid == 4)
								return STATUS_SUCCESS;
							else
								GetSecurityContextSubjectReg(process_uni.name,security_sbject);
						
							switch(pInfo->KeyValueInformationClass)
							{
								case 0: {sprintf(droit, "KeyValueBasicInformation "); break;}
								case 1: {sprintf(droit, "KeyValueFullInformation "); break;}
								case 2: {sprintf(droit, "KeyValuePartialInformation "); break;}
								case 3: {sprintf(droit, "KeyValueFullInformationAlign64 "); break;}
								case 4: {sprintf(droit, "KeyValuePartialInformationAlign64 "); break;}
								case 5: {sprintf(droit, "MaxKeyValueInfoClass "); break;}
								default: break;
							}
							
							RtlUnicodeStringToAnsiString(&key_ansi, key, TRUE);

							// bool = 1;
						WriteInLog(droit,process_uni.pid, process_uni.name, process_uni.ppid , key_ansi.Buffer ,security_sbject , "system_u:object_r:registry_t", "registry",0,0);
							if(key)
								ExFreePoolWithTag(key,1);
						}
					}
				
				}
				__except(EXCEPTION_EXECUTE_HANDLER)
				{
					ntStatus=GetExceptionCode();
					DbgPrint("Exception : %x\n", ntStatus);
				}
	
				break;
			}
			
		case RegNtQueryKey:
			{
				PREG_QUERY_KEY_INFORMATION pInfo = (PREG_QUERY_KEY_INFORMATION) Argument2;
				
				__try{
					ntStatus = ObQueryNameString(pInfo->Object, (POBJECT_NAME_INFORMATION)key, 0, &ReturnLength);
					key = (PUNICODE_STRING)ExAllocatePoolWithTag(NonPagedPool, ReturnLength, 1);
					if (ntStatus == STATUS_INFO_LENGTH_MISMATCH)
					{
						if (key)
						{
							ntStatus = ObQueryNameString(pInfo->Object, (POBJECT_NAME_INFORMATION)key, ReturnLength, &ReturnLength);
					
							process_uni = GetProcessInfo();	
							
							if(process_uni.pid == 4)
								return STATUS_SUCCESS;
							else
								GetSecurityContextSubjectReg(process_uni.name,security_sbject);
													
							switch(pInfo->KeyInformationClass)
							{
								case 0: {sprintf(droit, "KeyBasicInformation "); break;}
								case 1: {sprintf(droit, "KeyNodeInformation "); break;}
								case 2: {sprintf(droit, "KeyFullInformation "); break;}
								case 3: {sprintf(droit, "KeyNameInformation "); break;}
								case 4: {sprintf(droit, "KeyCachedInformation "); break;}
								case 5: {sprintf(droit, "KeyFlagsInformation "); break;}
								case 6: {sprintf(droit, "KeyVirtualizationInformation "); break;}
								case 7: {sprintf(droit, "KeyHandleTagsInformation "); break;}
								case 8: {sprintf(droit, "MaxKeyInfoClass "); break;}
								default: break;
							}
							RtlUnicodeStringToAnsiString(&key_ansi, key, TRUE);
							// RtlUnicodeStringToAnsiString(&pathname_ansi, process_uni.pathname, TRUE);
							
							WriteInLog(droit,process_uni.pid, process_uni.name, process_uni.ppid , key_ansi.Buffer ,security_sbject , "system_u:object_r:registry_t", "registry",0,0);
							// bool = 1;
						
							// if(key)
								// ExFreePoolWithTag(key,1);
						}
					}
				}
				__except(EXCEPTION_EXECUTE_HANDLER)
				{
					ntStatus=GetExceptionCode();
					DbgPrint("Exception : %x\n", ntStatus);
				}
				
				break;
			}

		case RegNtPreOpenKeyEx:
			{
				PREG_CREATE_KEY_INFORMATION pInfo = (PREG_CREATE_KEY_INFORMATION) Argument2;
				
				__try{
					process_uni = GetProcessInfo();	
					if(process_uni.pid == 4)
							return STATUS_SUCCESS;
							
					RtlUnicodeStringToAnsiString(&pathname_ansi, process_uni.pathname, TRUE);
				
					GetSecurityContextSubjectReg(process_uni.name,security_sbject);
					GetDroit(droit, pInfo);
					//sprintf(droit, "open_key_function %s", droit_temp);
					RtlUnicodeStringToAnsiString(&key_ansi, pInfo->CompleteName, TRUE);
					// bool = 1;
					WriteInLog(droit,process_uni.pid, process_uni.name, process_uni.ppid , key_ansi.Buffer ,security_sbject , "system_u:object_r:registry_t", "registry",0,0);
					
				}
				__except(EXCEPTION_EXECUTE_HANDLER)
				{
					ntStatus=GetExceptionCode();
					DbgPrint("Exception : %x\n", ntStatus);
				}
				break;
			}	
			
		default:
			{
				break;
			}
	}
	
	if(bool == 1)
	{
		WriteInLog(droit, process.pid, process.pathname, process.ppid , key_ansi.Buffer ,security_sbject , "system_u:object_r:registry_t", "registry", 0,0);
		
	}


	return STATUS_SUCCESS;
}
Exemplo n.º 13
0
NTSTATUS
DrGetDevicePropertyInstallState(
	IN PDEVICE_OBJECT  DeviceObject,
    IN ULONG  BufferLength,
    OUT PVOID  PropertyBuffer,
    OUT PULONG  ResultLength
) {
	NTSTATUS		status;
	HANDLE			devparamRegKey;
	HANDLE			devInstRegKey;
	UNICODE_STRING valueName;
	UCHAR			keyValueBuffer[KVLEN_PARTIAL];
	PKEY_VALUE_PARTIAL_INFORMATION  keyValue;
	ULONG			resultLength;
	PULONG			configFlags;
	DEVICE_INSTALL_STATE deviceInstallState;
	PVOID			Object;
	UCHAR					ObjectNameBuffer[512];
	POBJECT_NAME_INFORMATION ObjectNameInfo;
	OBJECT_ATTRIBUTES		objectAttributes;


	//
	//	init
	//
	devInstRegKey = NULL;
	devparamRegKey = NULL;
	keyValue = (PKEY_VALUE_PARTIAL_INFORMATION)keyValueBuffer;
	if(BufferLength < sizeof(DEVICE_INSTALL_STATE)) {
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	//
	//	open the device registry's parameter key
	//
	status = IoOpenDeviceRegistryKey(
					DeviceObject,
					PLUGPLAY_REGKEY_DEVICE,
					KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS,
					&devparamRegKey
				);
	if(!NT_SUCCESS(status)) {
		devInstRegKey = NULL;
		goto cleanup;
	}
	status = ObReferenceObjectByHandle(
							devparamRegKey,
							GENERIC_READ,
							NULL,
							KernelMode,
							&Object,
							NULL
					);
	if(!NT_SUCCESS(status)) {
		goto cleanup;
	}

	ObjectNameInfo = (POBJECT_NAME_INFORMATION)ObjectNameBuffer;
	status = ObQueryNameString(Object, ObjectNameInfo, sizeof(ObjectNameBuffer), &resultLength );
	ObDereferenceObject(Object);
	if(!NT_SUCCESS(status) || ObjectNameInfo->Name.Buffer == NULL) {
		goto cleanup;
	}
	KDPrint(1, ("Device parameter path: %ws. len=%d\n", ObjectNameInfo->Name.Buffer,ObjectNameInfo->Name.Length));

	ASSERT(ObjectNameInfo->Name.Length < sizeof(ObjectNameBuffer) - 20);
	// trim down to the first parent.
	for(; ObjectNameInfo->Name.Length > 1; ObjectNameInfo->Name.Length-=sizeof(WCHAR) ) {
		if( ObjectNameInfo->Name.Buffer[ObjectNameInfo->Name.Length/sizeof(WCHAR) - 1] == '\\') {
			ObjectNameInfo->Name.Length-=sizeof(WCHAR);
			KDPrint(1, ("Trimed at the index %d\n", ObjectNameInfo->Name.Length));
			break;
		}
	}

	KDPrint(1, ("Device parameter path: %ws. len=%d\n", ObjectNameInfo->Name.Buffer,ObjectNameInfo->Name.Length));
	if(ObjectNameInfo->Name.Length <= 1) {
		goto cleanup;
	}

	//
	//	Open device registry.
	//
	InitializeObjectAttributes(
					&objectAttributes,
					&ObjectNameInfo->Name,
					OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
					NULL,
					NULL
				);
	status = ZwOpenKey(&devInstRegKey, KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &objectAttributes);
	if(!NT_SUCCESS(status)) {
		goto cleanup;
	}

	//
	//	Query the value of CONFIGFLAGS
	//
	RtlInitUnicodeString(&valueName, REGSTR_VAL_CONFIGFLAGS);
	status = ZwQueryValueKey(
			devInstRegKey,
			&valueName,
			KeyValuePartialInformation,
			keyValue,
			KVLEN_PARTIAL,
			&resultLength
		);
	if(!NT_SUCCESS(status)) {
		goto cleanup;
	}
	if(keyValue->Type != REG_DWORD) {
		goto cleanup;
	}
	if(keyValue->DataLength != sizeof(ULONG)) {
		goto cleanup;
	}

	//
	//	determine deviceInstallState
	//
	// TODO: If the device object is root device,
	//			always return InstallStateInstalled.
	//
	configFlags = (PULONG)keyValue->Data;
	if ((*configFlags) & CONFIGFLAG_REINSTALL) {

		deviceInstallState = InstallStateNeedsReinstall;

	} else if ((*configFlags) & CONFIGFLAG_FAILEDINSTALL) {

		deviceInstallState = InstallStateFailedInstall;

	} else if ((*configFlags) & CONFIGFLAG_FINISH_INSTALL) {

		deviceInstallState = InstallStateFinishInstall;
	} else {

		deviceInstallState = InstallStateInstalled;
	}

	//
	//	set the result
	//
	(*(PDEVICE_INSTALL_STATE)PropertyBuffer) = deviceInstallState;
	*ResultLength = sizeof(DEVICE_INSTALL_STATE);

cleanup:
	if(devInstRegKey)
		ZwClose(devInstRegKey);
	if(devparamRegKey)
		ZwClose(devparamRegKey);

	return status;
}
Exemplo n.º 14
0
PUNICODE_STRING
GingkoGetFileName(
    IN PFILE_OBJECT FileObject,
    IN NTSTATUS CreateStatus,
    IN OUT PGET_NAME_CONTROL NameControl
    )
{
    POBJECT_NAME_INFORMATION nameInfo;
    NTSTATUS status;
    ULONG size;
    ULONG bufferSize;
	ULONG InitSize = sizeof(OBJECT_NAME_INFORMATION) + 512 * sizeof(WCHAR);

	if( NameControl == NULL )
	{
		return NULL;
	}

    //
    //  Mark we have not allocated the buffer
    //

    NameControl->AllocatedBuffer = ExAllocatePoolWithTag( NonPagedPool, InitSize, GINGKO_POOL_TAG );

    //
    //  Use the small buffer in the structure (that will handle most cases)
    //  for the name
    //

	if( NameControl->AllocatedBuffer == NULL )
	{
		return NULL;
	}


	RtlZeroMemory( NameControl->AllocatedBuffer, InitSize );
	nameInfo = (POBJECT_NAME_INFORMATION)NameControl->AllocatedBuffer;
    bufferSize = InitSize;
	nameInfo->Name.Length = 0;
	nameInfo->Name.MaximumLength = (USHORT)InitSize - sizeof(OBJECT_NAME_INFORMATION);


    //
    //  If the open succeeded, get the name of the file, if it
    //  failed, get the name of the device.
    //
        
    status = ObQueryNameString(
                  FileObject ,
                  nameInfo,
                  (USHORT)InitSize - sizeof(OBJECT_NAME_INFORMATION),
                  &size );

    //
    //  See if the buffer was to small
    //

    if (status == STATUS_INFO_LENGTH_MISMATCH) {

        //
        //  The buffer was too small, allocate one big enough
        //

		if( NameControl->AllocatedBuffer != NULL )
		{
			ExFreePoolWithTag( NameControl->AllocatedBuffer, GINGKO_POOL_TAG );
		}

        bufferSize = sizeof(OBJECT_NAME_INFORMATION) + size + sizeof(WCHAR);

        NameControl->AllocatedBuffer = ExAllocatePoolWithTag( 
                                            NonPagedPool,
                                            bufferSize,
                                            GINGKO_POOL_TAG );

        if (NULL == NameControl->AllocatedBuffer) {

            //
            //  Failed allocating a buffer, return an empty string for the name
            //
			return NULL;
        }

        //
        //  Set the allocated buffer and get the name again
        //

        nameInfo = (POBJECT_NAME_INFORMATION)NameControl->AllocatedBuffer;
		nameInfo->Name.Length = 0;
		nameInfo->Name.MaximumLength = (USHORT)bufferSize - sizeof(OBJECT_NAME_INFORMATION);

        status = ObQueryNameString(
                      FileObject,
                      nameInfo,
                      (USHORT)bufferSize - sizeof(OBJECT_NAME_INFORMATION),
                      &size );
    }

    return &nameInfo->Name;
}
Exemplo n.º 15
0
VOID
IopErrorLogThread(
    IN PVOID StartContext
    )

/*++

Routine Description:

    This is the main loop for the I/O error log thread which executes in the
    system process context.  This routine is started when the system is
    initialized.

Arguments:

    StartContext - Startup context; not used.

Return Value:

    None.

--*/

{
    PERROR_LOG_ENTRY errorLogEntry;
    UNICODE_STRING nameString;
    PLIST_ENTRY listEntry;
    PIO_ERROR_LOG_MESSAGE errorMessage;
    NTSTATUS status;
    PELF_PORT_MSG portMessage;
    PCHAR objectName;
    ULONG messageLength;
    ULONG driverNameLength;
    ULONG deviceNameLength;
    ULONG objectNameLength;
    ULONG remainingLength;
    ULONG stringLength;
    CHAR nameBuffer[IO_ERROR_NAME_LENGTH+sizeof( OBJECT_NAME_INFORMATION )];
    PDRIVER_OBJECT driverObject;
    POBJECT_NAME_INFORMATION nameInformation;
    PIO_ERROR_LOG_PACKET errorData;
    PWSTR string;

    PAGED_CODE();

    UNREFERENCED_PARAMETER( StartContext );

    //
    // Check to see whether a connection has been made to the error log
    // port.  If the port is not connected return.
    //

    if (!IopErrorLogConnectPort()) {

        //
        // The port could not be connected.  A timer was started that will
        // try again later.
        //

        return;
    }

    //
    // Allocate and zero the port message structure, include space for the
    // name of the device and driver.
    //

    messageLength = IO_ERROR_LOG_MESSAGE_LENGTH;
    portMessage = ExAllocatePool(PagedPool, messageLength);

    if (portMessage == NULL) {

        //
        // The message buffer could not be allocated. Request that
        // the error log thread routine be called again later.
        //

        IopErrorLogQueueRequest();
        return;
    }

    RtlZeroMemory( portMessage, sizeof( *portMessage ) );
    portMessage->MessageType = IO_ERROR_LOG;
    errorMessage = &portMessage->u.IoErrorLogMessage;

    nameInformation = (PVOID) &nameBuffer;

    //
    // Now enter the main loop for this thread.  This thread performs the
    // following operations:
    //
    //   1)  If a connection has been made to the error log port, dequeue a
    //       packet from the queue head and attempt to send it to the port.
    //
    //   2)  If the send works, loop sending packets until there are no more
    //       packets;  otherwise, indicate that the connection has been broken,
    //       cleanup, place the packet back onto the head of the queue and
    //       return.
    //
    //   3)  After all the packets are sent clear the pending variable and
    //       return.
    //

    for (;;) {

        //
        // Loop dequeueing  packets from the queue head and attempt to send
        // each to the port.
        //
        // If the send works, continue looping until there are no more packets.
        // Otherwise, indicate that the connection has been broken, cleanup,
        // place the packet back onto the head of the queue, and start from the
        // top of the loop again.
        //

        if (!(listEntry = IopErrorLogGetEntry())) {
            break;
        }

        errorLogEntry = CONTAINING_RECORD( listEntry,
                                           ERROR_LOG_ENTRY,
                                           ListEntry );

        //
        // The size of errorLogEntry is ERROR_LOG_ENTRY +
        // IO_ERROR_LOG_PACKET + (Extra Dump data).  The size of the
        // initial message length should be IO_ERROR_LOG_MESSAGE +
        // (Extra Dump data), since IO_ERROR_LOG_MESSAGE contains an
        // IO_ERROR_LOG_PACKET. Using the above calculations set the
        // message length.
        //

        messageLength = sizeof( IO_ERROR_LOG_MESSAGE ) -
            sizeof( ERROR_LOG_ENTRY ) - sizeof( IO_ERROR_LOG_PACKET ) +
            errorLogEntry->Size;

        errorData = (PIO_ERROR_LOG_PACKET) (errorLogEntry + 1);

        //
        // Copy the error log packet and the extra data to the message.
        //

        RtlMoveMemory( &errorMessage->EntryData,
                       errorData,
                       errorLogEntry->Size - sizeof( ERROR_LOG_ENTRY ) );

        errorMessage->TimeStamp = errorLogEntry->TimeStamp;
        errorMessage->Type = IO_TYPE_ERROR_MESSAGE;

        //
        // Add the driver and device name string.  These strings go
        // before the error log strings.  Just write over the current
        // strings and they will be recopied later.
        //

        if (errorData->NumberOfStrings != 0) {

            //
            // Start the driver and device strings where the current
            // strings start.
            //

            objectName = (PCHAR) (&errorMessage->EntryData) +
                                 errorData->StringOffset;

        } else {

            //
            // Put the driver and device strings at the end of the
            // data.
            //

            objectName = (PCHAR) errorMessage + messageLength;

        }

        //
        // Make sure the driver offset starts on an even bountry.
        //

        objectName = (PCHAR) ((ULONG_PTR) (objectName + sizeof(WCHAR) - 1) &
            ~(ULONG_PTR)(sizeof(WCHAR) - 1));

        errorMessage->DriverNameOffset = (ULONG)(objectName - (PCHAR) errorMessage);

        remainingLength = (ULONG)((PCHAR) portMessage + IO_ERROR_LOG_MESSAGE_LENGTH
                            - objectName);

        //
        // Calculate the length of the driver name and
        // the device name. If the driver object has a name then get
        // it from there; otherwise try to query the device object.
        //

        driverObject = errorLogEntry->DriverObject;
        driverNameLength = 0;

        if (driverObject != NULL) {
            if (driverObject->DriverName.Buffer != NULL) {

                nameString.Buffer = driverObject->DriverName.Buffer;
                driverNameLength = driverObject->DriverName.Length;
            }

            if (driverNameLength == 0) {

                //
                // Try to query the driver object for a name.
                //

                status = ObQueryNameString( driverObject,
                                            nameInformation,
                                            IO_ERROR_NAME_LENGTH + sizeof( OBJECT_NAME_INFORMATION ),
                                            &objectNameLength );

                if (!NT_SUCCESS( status ) || !nameInformation->Name.Length) {

                    //
                    // No driver name was available.
                    //

                    driverNameLength = 0;

                } else {
                    nameString = nameInformation->Name;
                }

            }

        } else {

            //
            // If no driver object, this message must be from the 
            // kernel.   We need to point the eventlog service to
            // an event message file containing ntstatus messages,
            // ie, ntdll, we do this by claiming this event is an
            // application popup.
            //

            nameString.Buffer = L"Application Popup";
            driverNameLength = wcslen(nameString.Buffer) * sizeof(WCHAR);
        }

        if (driverNameLength != 0 ) {

            //
            // Pick out the module name.
            //

            string = nameString.Buffer +
                (driverNameLength / sizeof(WCHAR));

            driverNameLength = sizeof(WCHAR);
            string--;
            while (*string != L'\\' && string != nameString.Buffer) {
                string--;
                driverNameLength += sizeof(WCHAR);
            }

            if (*string == L'\\') {
                string++;
                driverNameLength -= sizeof(WCHAR);
            }

            //
            // Ensure there is enough room for the driver name.
            // Save space for 3 NULLs one for the driver name,
            // one for the device name and one for strings.
            //

            if (driverNameLength > remainingLength - (3 * sizeof(WCHAR))) {
                driverNameLength = remainingLength - (3 * sizeof(WCHAR));
            }

            RtlMoveMemory(
                objectName,
                string,
                driverNameLength
                );

        }

        //
        // Add a null after the driver name even if there is no
        // driver name.
        //

       *((PWSTR) (objectName + driverNameLength)) = L'\0';
       driverNameLength += sizeof(WCHAR);

        //
        // Determine where the next string goes.
        //

        objectName += driverNameLength;
        remainingLength -= driverNameLength;

        errorMessage->EntryData.StringOffset = (USHORT)(objectName - (PCHAR) errorMessage);

        if (errorLogEntry->DeviceObject != NULL) {

            status = ObQueryNameString( errorLogEntry->DeviceObject,
                                        nameInformation,
                                        IO_ERROR_NAME_LENGTH + sizeof( OBJECT_NAME_INFORMATION ) - driverNameLength,
                                        &objectNameLength );

            if (!NT_SUCCESS( status ) || !nameInformation->Name.Length) {

                //
                // No device name was available. Add a Null string.
                //

                nameInformation->Name.Length = 0;
                nameInformation->Name.Buffer = L"\0";

            }

            //
            // No device name was available. Add a Null string.
            // Always add a device name string so that the
            // insertion string counts are correct.
            //

        } else {

                //
                // No device name was available. Add a Null string.
                // Always add a device name string so that the
                // insertion string counts are correct.
                //

                nameInformation->Name.Length = 0;
                nameInformation->Name.Buffer = L"\0";

        }

        deviceNameLength = nameInformation->Name.Length;

        //
        // Ensure there is enough room for the device name.
        // Save space for a NULL.
        //

        if (deviceNameLength > remainingLength - (2 * sizeof(WCHAR))) {

            deviceNameLength = remainingLength - (2 * sizeof(WCHAR));

        }

        RtlMoveMemory( objectName,
                       nameInformation->Name.Buffer,
                       deviceNameLength );

        //
        // Add a null after the device name even if there is no
        // device name.
        //

        *((PWSTR) (objectName + deviceNameLength)) = L'\0';
        deviceNameLength += sizeof(WCHAR);

        //
        // Update the string count for the device object.
        //

        errorMessage->EntryData.NumberOfStrings++;
        objectName += deviceNameLength;
        remainingLength -= deviceNameLength;

        if (errorData->NumberOfStrings) {

            stringLength = errorLogEntry->Size - sizeof( ERROR_LOG_ENTRY ) -
                            errorData->StringOffset;

            //
            // Ensure there is enough room for the strings.
            // Save space for a NULL.
            //

            if (stringLength > remainingLength - sizeof(WCHAR)) {


                messageLength -= stringLength - remainingLength;
                stringLength = remainingLength - sizeof(WCHAR);

            }

            //
            // Copy the strings to the end of the message.
            //

            RtlMoveMemory( objectName,
                           (PCHAR) errorData + errorData->StringOffset,
                           stringLength );

            //
            // Add a null after the strings
            //
            //

           *((PWSTR) (objectName + stringLength)) = L'\0';

        }

        //
        // Update the message length.
        //

        errorMessage->DriverNameLength = (USHORT) driverNameLength;
        messageLength += deviceNameLength + driverNameLength;
        errorMessage->Size = (USHORT) messageLength;

        messageLength += FIELD_OFFSET ( ELF_PORT_MSG, u ) -
            FIELD_OFFSET (ELF_PORT_MSG, MessageType);

        portMessage->PortMessage.u1.s1.TotalLength = (USHORT)
            (sizeof( PORT_MESSAGE ) + messageLength);
        portMessage->PortMessage.u1.s1.DataLength = (USHORT) (messageLength);
        status = NtRequestPort( ErrorLogPort, (PPORT_MESSAGE) portMessage );

        if (!NT_SUCCESS( status )) {

            //
            // The send failed.  Place the packet back onto the head of
            // the error log queue, forget the current connection since
            // it no longer works, and close the handle to the port.
            // Set a timer up for another attempt later.
            // Finally, exit the loop since there is no connection
            // to do any work on.
            //

            NtClose( ErrorLogPort );

            IopErrorLogRequeueEntry( &errorLogEntry->ListEntry );

            IopErrorLogQueueRequest();

            break;

        } else {

            //
            // The send worked fine.  Free the packet and the update
            // the allocation count.
            //

            ExInterlockedAddUlong( &IopErrorLogAllocation,
                                   (ULONG) ( -errorLogEntry->Size ),
                                   &IopErrorLogAllocationLock );

            //
            // Dereference the object pointers now that the name has been
            // captured.
            //


            if (errorLogEntry->DeviceObject != NULL) {
                ObDereferenceObject( errorLogEntry->DeviceObject );
            }

            if (driverObject != NULL) {
                ObDereferenceObject( errorLogEntry->DriverObject );
            }

            ExFreePool( errorLogEntry );

        } // if

    } // for

    //
    // Finally, free the message buffer and return.
    //

    ExFreePool(portMessage);

}
Exemplo n.º 16
0
VOID
NTAPI
IopLogWorker(IN PVOID Parameter)
{
    PELF_API_MSG Message;
    PIO_ERROR_LOG_MESSAGE ErrorMessage;
    PLIST_ENTRY ListEntry;
    PERROR_LOG_ENTRY LogEntry;
    PIO_ERROR_LOG_PACKET Packet;
    PCHAR StringBuffer;
    ULONG RemainingLength;
    PDRIVER_OBJECT DriverObject;
    ULONG DriverNameLength = 0, DeviceNameLength;
    UNICODE_STRING DriverNameString;
    NTSTATUS Status;
    UCHAR Buffer[256];
    POBJECT_NAME_INFORMATION ObjectNameInfo = (POBJECT_NAME_INFORMATION)&Buffer;
    POBJECT_NAME_INFORMATION PoolObjectNameInfo = NULL;
    ULONG ReturnedLength, MessageLength;
    PWCHAR p;
    ULONG ExtraStringLength;
    PAGED_CODE();

    /* Connect to the port */
    if (!IopConnectLogPort()) return;

    /* Allocate the message */
    Message = ExAllocatePool(PagedPool, IO_ERROR_LOG_MESSAGE_LENGTH);
    if (!Message)
    {
        /* Couldn't allocate, try again */
        IopRestartLogWorker();
        return;
    }

    /* Copy the message */
    RtlZeroMemory(Message, sizeof(ELF_API_MSG));

    /* Get the actual I/O Structure */
    ErrorMessage = &Message->IoErrorMessage;

    /* Start loop */
    while (TRUE)
    {
        /* Get an entry */
        ListEntry = IopGetErrorLogEntry();
        if (!ListEntry) break;
        LogEntry = CONTAINING_RECORD(ListEntry, ERROR_LOG_ENTRY, ListEntry);

        /* Get pointer to the log packet */
        Packet = (PIO_ERROR_LOG_PACKET)((ULONG_PTR)LogEntry +
                                        sizeof(ERROR_LOG_ENTRY));

        /* Calculate the total length of the message only */
        MessageLength = sizeof(IO_ERROR_LOG_MESSAGE) -
                        sizeof(ERROR_LOG_ENTRY) -
                        sizeof(IO_ERROR_LOG_PACKET) +
                        LogEntry->Size;

        /* Copy the packet */
        RtlCopyMemory(&ErrorMessage->EntryData,
                      Packet,
                      LogEntry->Size - sizeof(ERROR_LOG_ENTRY));

        /* Set the timestamp and time */
        ErrorMessage->TimeStamp = LogEntry->TimeStamp;
        ErrorMessage->Type = IO_TYPE_ERROR_MESSAGE;

        /* Check if this message has any strings */
        if (Packet->NumberOfStrings)
        {
            /* String buffer is after the current strings */
            StringBuffer = (PCHAR)&ErrorMessage->EntryData +
                            Packet->StringOffset;
        }
        else
        {
            /* Otherwise, string buffer is at the end */
            StringBuffer = (PCHAR)ErrorMessage + MessageLength;
        }

        /* Align the buffer */
        StringBuffer = ALIGN_UP_POINTER(StringBuffer, WCHAR);

        /* Set the offset for the driver's name to the current buffer */
        ErrorMessage->DriverNameOffset = (ULONG)(StringBuffer -
                                                (PCHAR)ErrorMessage);

        /* Check how much space we have left for the device string */
        RemainingLength = (ULONG)((ULONG_PTR)Message +
                                  IO_ERROR_LOG_MESSAGE_LENGTH -
                                  (ULONG_PTR)StringBuffer);

        /* Now check if there is a driver object */
        DriverObject = LogEntry->DriverObject;
        if (DriverObject)
        {
            /* Check if the driver has a name */
            if (DriverObject->DriverName.Buffer)
            {
                /* Use its name */
                DriverNameString.Buffer = DriverObject->DriverName.Buffer;
                DriverNameLength = DriverObject->DriverName.Length;
            }
            else
                DriverNameString.Buffer = NULL;

            /* Check if there isn't a valid name*/
            if (!DriverNameLength)
            {
                /* Query the name directly */
                Status = ObQueryNameString(DriverObject,
                                           ObjectNameInfo,
                                           sizeof(Buffer),
                                           &ReturnedLength);
                if (!(NT_SUCCESS(Status)) || !(ObjectNameInfo->Name.Length))
                {
                    /* We don't have a name */
                    DriverNameLength = 0;
                }
            }
        }
        else
        {
            /* Use default name */
            DriverNameString.Buffer = L"Application Popup";
            DriverNameLength = (ULONG)wcslen(DriverNameString.Buffer) * sizeof(WCHAR);
        }

        /* Check if we have a driver name by here */
        if (DriverNameLength)
        {
            /* Skip to the end of the driver's name */
            p = &DriverNameString.Buffer[DriverNameLength / sizeof(WCHAR)];

            /* Now we'll walk backwards and assume the minimum size */
            DriverNameLength = sizeof(WCHAR);
            p--;
            while ((*p != L'\\') && (p != DriverNameString.Buffer))
            {
                /* No backslash found, keep going */
                p--;
                DriverNameLength += sizeof(WCHAR);
            }

            /* Now we probably hit the backslash itself, skip past it */
            if (*p == L'\\')
            {
                p++;
                DriverNameLength -= sizeof(WCHAR);
            }

            /*
             * Now make sure that the driver name fits in our buffer, minus 3
             * NULL chars, and copy the name in our string buffer
             */
            DriverNameLength = min(DriverNameLength,
                                   RemainingLength - 3 * sizeof(UNICODE_NULL));
            RtlCopyMemory(StringBuffer, p, DriverNameLength);
        }

        /* Null-terminate the driver name */
        *((PWSTR)(StringBuffer + DriverNameLength)) = L'\0';
        DriverNameLength += sizeof(WCHAR);

        /* Go to the next string buffer position */
        StringBuffer += DriverNameLength;
        RemainingLength -= DriverNameLength;

        /* Update the string offset and check if we have a device object */
        ErrorMessage->EntryData.StringOffset = (USHORT)
                                               ((ULONG_PTR)StringBuffer -
                                               (ULONG_PTR)ErrorMessage);
        if (LogEntry->DeviceObject)
        {
            /* We do, query its name */
            Status = ObQueryNameString(LogEntry->DeviceObject,
                                       ObjectNameInfo,
                                       sizeof(Buffer),
                                       &ReturnedLength);
            if (!NT_SUCCESS(Status) || (ObjectNameInfo->Name.Length == 0))
            {
                /* Setup an empty name */
                ObjectNameInfo->Name.Length = 0;
                ObjectNameInfo->Name.Buffer = L"";

                /* Check if we failed because our buffer wasn't large enough */
                if (Status == STATUS_INFO_LENGTH_MISMATCH)
                {
                    /* Then we'll allocate one... we really want this name! */
                    PoolObjectNameInfo = ExAllocatePoolWithTag(PagedPool,
                                                               ReturnedLength,
                                                               TAG_IO);
                    if (PoolObjectNameInfo)
                    {
                        /* Query it again */
                        ObjectNameInfo = PoolObjectNameInfo;
                        Status = ObQueryNameString(LogEntry->DeviceObject,
                                                   ObjectNameInfo,
                                                   ReturnedLength,
                                                   &ReturnedLength);
                        if (NT_SUCCESS(Status))
                        {
                            /* Success, update the information */
                            ObjectNameInfo->Name.Length =
                                100 - (USHORT)DriverNameLength;
                        }
                    }
                }
            }
        }
        else
        {
            /* No device object, setup an empty name */
            ObjectNameInfo->Name.Length = 0;
            ObjectNameInfo->Name.Buffer = L"";
        }

        /*
         * Now make sure that the device name fits in our buffer, minus 2
         * NULL chars, and copy the name in our string buffer
         */
        DeviceNameLength = min(ObjectNameInfo->Name.Length,
                               RemainingLength - 2 * sizeof(UNICODE_NULL));
        RtlCopyMemory(StringBuffer,
                      ObjectNameInfo->Name.Buffer,
                      DeviceNameLength);

        /* Null-terminate the device name */
        *((PWSTR)(StringBuffer + DeviceNameLength)) = L'\0';
        DeviceNameLength += sizeof(WCHAR);

        /* Free the buffer if we had one */
        if (PoolObjectNameInfo)
        {
            ExFreePool(PoolObjectNameInfo);
            PoolObjectNameInfo = NULL;
            ObjectNameInfo = (POBJECT_NAME_INFORMATION)&Buffer;
        }

        /* Go to the next string buffer position */
        ErrorMessage->EntryData.NumberOfStrings++;
        StringBuffer += DeviceNameLength;
        RemainingLength -= DeviceNameLength;

        /* Check if we have any extra strings */
        if (Packet->NumberOfStrings)
        {
            /* Find out the size of the extra strings */
            ExtraStringLength = LogEntry->Size -
                                sizeof(ERROR_LOG_ENTRY) -
                                Packet->StringOffset;

            /* Make sure that the extra strings fit in our buffer */
            if (ExtraStringLength > (RemainingLength - sizeof(UNICODE_NULL)))
            {
                /* They wouldn't, so set normalize the length */
                MessageLength -= ExtraStringLength - RemainingLength;
                ExtraStringLength = RemainingLength - sizeof(UNICODE_NULL);
            }

            /* Now copy the extra strings */
            RtlCopyMemory(StringBuffer,
                          (PCHAR)Packet + Packet->StringOffset,
                          ExtraStringLength);

            /* Null-terminate them */
            *((PWSTR)(StringBuffer + ExtraStringLength)) = L'\0';
        }

        /* Set the driver name length */
        ErrorMessage->DriverNameLength = (USHORT)DriverNameLength;

        /* Update the message length to include the device and driver names */
        MessageLength += DeviceNameLength + DriverNameLength;
        ErrorMessage->Size = (USHORT)MessageLength;

        /* Now update it again, internally, for the size of the actual LPC */
        MessageLength += (FIELD_OFFSET(ELF_API_MSG, IoErrorMessage) -
                          FIELD_OFFSET(ELF_API_MSG, Unknown[0]));

        /* Set the total and data lengths */
        Message->h.u1.s1.TotalLength = (USHORT)(sizeof(PORT_MESSAGE) +
                                                MessageLength);
        Message->h.u1.s1.DataLength = (USHORT)(MessageLength);

        /* Send the message */
        Status = NtRequestPort(IopLogPort, (PPORT_MESSAGE)Message);
        if (!NT_SUCCESS(Status))
        {
            /* Requeue log message and restart the worker */
            ExInterlockedInsertTailList(&IopErrorLogListHead,
                                        &LogEntry->ListEntry,
                                        &IopLogListLock);
            IopLogWorkerRunning = FALSE;
            IopRestartLogWorker();
            break;
        }

        /* Dereference the device object */
        if (LogEntry->DeviceObject) ObDereferenceObject(LogEntry->DeviceObject);
        if (DriverObject) ObDereferenceObject(LogEntry->DriverObject);

        /* Update size */
        InterlockedExchangeAdd(&IopTotalLogSize,
                               -(LONG)(LogEntry->Size -
                                       sizeof(ERROR_LOG_ENTRY)));
    }

    /* Free the LPC Message */
    ExFreePool(Message);
}
Exemplo n.º 17
0
NTSTATUS NewNtDeviceIoControlFile(
  __in       HANDLE FileHandle,
  __in_opt   HANDLE Event,
  __in_opt   PIO_APC_ROUTINE ApcRoutine,
  __in_opt   PVOID ApcContext,
  __out      PIO_STATUS_BLOCK IoStatusBlock,
  __in       ULONG IoControlCode,
  __in_opt   PVOID InputBuffer,
  __in       ULONG InputBufferLength,
  __out_opt  PVOID OutputBuffer,
  __in       ULONG OutputBufferLength
)
{

	NTSTATUS retour,ntStatus;
	PFILE_OBJECT fileObject = NULL;
	ULONG retLen, ret;
    UNICODE_STRING        *path_str = NULL;
	UNICODE_STRING			afd;//=NULL;
	WCHAR                  deviceafd[]  = L"\\Device\\Afd"; 
	PAFD_SEND_INFO		pAfdTcpInfo			= InputBuffer;
	PAFD_SEND_INFO_UDP	pAfdUdpSendtoInfo	= InputBuffer;
	PAFD_RECV_INFO_UDP	pAfdUdpRecvFromInfo = InputBuffer;
	ULONG	dwLen = 0;
	PCHAR	pBuf = NULL;
	int i=0, pid=0;
	ProcessInformation process;
	char buffer_net[2000];
	char prot[10];
	IO_STATUS_BLOCK iostatus;
	LARGE_INTEGER time;
	ULONG ppid = 0;
	PCHAR toto;
	UCHAR *name;
	PUNICODE_STRING temp_unicode, addr=NULL;
	ANSI_STRING ansi;
	PEPROCESS pep;
	TDI_REQUEST_QUERY_INFORMATION Request;
	char Address[128];
	//Request = TDI_QUERY_ADDRESS_INFO;
	
	KeQuerySystemTime(&time);
	
	RtlZeroMemory(&buffer_net, sizeof(buffer_net));
	RtlZeroMemory(&prot, sizeof(prot));
	// NTDEVICEIOCONTROLFILE NtDeviceIoControlFile = Zdicf.NtFunc;
	
	RtlInitUnicodeString (&afd, deviceafd);

	retour = ((NTDEVICEIOCONTROLFILE) (OldNtDeviceIoControlFile)) (FileHandle,
															Event,
															ApcRoutine,
															ApcContext,
															IoStatusBlock,
															IoControlCode,
															InputBuffer,
															InputBufferLength,
															OutputBuffer,
															OutputBufferLength);
	
	if(IoControlCode != AFD_SEND && IoControlCode != AFD_RECV && IoControlCode != AFD_SENDTO && IoControlCode != AFD_RECVFROM)
		return retour;
	
	// ZwDeviceIoControlFile(FileHandle,
							// NULL,NULL, NULL,
							// &iostatus,
							// IOCTL_TDI_QUERY_INFORMATION,
							// TDI_QUERY_ADDRESS_INFO, 0,//sizeof(TDI_QUERY_ADDRESS_INFO),
							// &Address, sizeof(Address));
	
	
	pid = (LONG)PsGetCurrentProcessId();
	if(pid == (int)UserLandID)
		return retour;
	PsLookupProcessByProcessId((HANDLE)pid,&pep);
	toto = (PCHAR) pep;
	ppid = *((ULONG*)(toto+0x140));
	// On recupere les 16 premiers bits du nom du process
	name = PsGetProcessImageFileName(pep);				
	if(ExGetPreviousMode() == UserMode)
	{
		if(FileHandle != NULL)
		{
			ObReferenceObjectByHandle(FileHandle, 0, 0, KernelMode, &fileObject, NULL);
			if (fileObject)
			{
				ntStatus = ObQueryNameString(fileObject, (POBJECT_NAME_INFORMATION)path_str, 0, &retLen);
				path_str = (PUNICODE_STRING)ExAllocatePoolWithTag(NonPagedPool, retLen, 0);

				if (ntStatus == STATUS_INFO_LENGTH_MISMATCH)
				{
					if (path_str)
					{
						ntStatus = ObQueryNameString(fileObject, (POBJECT_NAME_INFORMATION)path_str, retLen, &retLen);
						
						if(RtlCompareUnicodeString(path_str,&afd,TRUE) == 0)
						{
							trace_net++;
							switch(IoControlCode)
							{
								case AFD_SEND:
									sprintf(prot,"tcp");
									break;
								case AFD_RECV:
									sprintf(prot,"tcp");
									break;
								case AFD_SENDTO:
									sprintf(prot,"udp");
									break;
								case AFD_RECVFROM:
									sprintf(prot,"udp");
									break;
								default:
									sprintf(prot,"not");
							}
							
							// if(strcmp(prot, "udp") == 0)
							// {
								// DbgPrint("Taiele de l'address  : %i \n", pAfdUdpSendtoInfo->SizeOfRemoteAddress);
								// temp_unicode = (PUNICODE_STRING)ExAllocatePoolWithTag(NonPagedPool,  pAfdUdpSendtoInfo->SizeOfRemoteAddress, 0);
								// temp_unicode = (PUNICODE_STRING) pAfdUdpSendtoInfo->RemoteAddress;
								

								// DbgPrint("address : %wZ \n", &temp_unicode);
								
								//RtlCopyUnicodeString( addr, temp_unicode);
								//DbgPrint("addr 1 :%wZ\n" , addr);
							// }
							if(InputBufferLength > 0)
								sprintf(buffer_net, "audit(%I64d,%i) pid=%i name=%s ppid=%i { send } size=%i prot=%s return=%x endoftrace", time.QuadPart, trace_net,pid, name,ppid, InputBufferLength, prot, retour);
							if(OutputBufferLength > 0)
								sprintf(buffer_net, "audit(%I64d,%i) pid=%i name=%s ppid=%i { recv } size=%i prot=%s return=%x endoftrace", time.QuadPart, trace_net,pid, name, ppid, OutputBufferLength, prot, retour);
		
							
							//DbgPrint("%wZ \n", path_str);
							
							ZwWriteFile(handlenet, NULL, NULL, NULL, &iostatus, buffer_net, strlen(buffer_net), 0, NULL);		
							ZwFlushBuffersFile(handlenet, &iostatus);

						}
						if(path_str)
							ExFreePoolWithTag(path_str, 0);
					}
				}
				
				ObDereferenceObject(fileObject);
			}
			
		}
	}
	
	// if(fileObject != NULL)
		// ObDereferenceObject(fileObject);


	return retour;
}
Exemplo n.º 18
0
NTSTATUS DiskDevDispatch(IN PDEVICE_OBJECT HookDevice,IN PIRP Irp)
{
PIO_STACK_LOCATION		currentIrpStack=IoGetCurrentIrpStackLocation(Irp);
ULONG						ioControlCode;
VERDICT						Verdict;
NTSTATUS					ntStatus = STATUS_SUCCESS;
PDISK_DEV_LIST				DevEntry;
ULONG						Function;
ANSI_STRING					fullPathName;
BOOLEAN						FPNAllocated=FALSE;
ULONG						actualLen;
PCHAR						Action;
ULONG						ParamVal = 0;
LARGE_INTEGER				ByteOffset;
POBJECT_NAME_INFORMATION	DevName=NULL;
KIRQL						CurrIrql;

BOOLEAN bInvisible;

ULONG SectorSize = 0;
ULONG DataLength = 0;

ULONG ReqDataSize;
PVOID RequestData;
PSINGLE_PARAM pSingleParam;
PFILTER_EVENT_PARAM pParam;

	ByteOffset.LowPart = 0;
	ByteOffset.HighPart = 0;

	fullPathName.Buffer=NULL;
	CurrIrql = KeGetCurrentIrql();
	if (CurrIrql < DISPATCH_LEVEL) {
			
		ReqDataSize = sizeof(FILTER_EVENT_PARAM) + sizeof(SINGLE_PARAM) + MAXPATHLEN + 1 + sizeof(SINGLE_PARAM) + 
			sizeof(ULONG) + sizeof(SINGLE_PARAM) + sizeof(LARGE_INTEGER);
		
		ReqDataSize += sizeof (SINGLE_PARAM) + __SID_LENGTH;
		RequestData = ExAllocatePoolWithTag(NonPagedPool, ReqDataSize, 'RboS');
		
		pParam = (PFILTER_EVENT_PARAM)RequestData;
		if (pParam == NULL) {
			DbPrint(DC_DISK,DL_ERROR, ("Allocate buffer in DiskDevDispatch for RequestData failed\n"));
		} else {

			FILTER_PARAM_COMMONINIT(pParam, FLTTYPE_DISK, 0, 0, PreProcessing, 3);

			pSingleParam = (PSINGLE_PARAM) pParam->Params;
			
		//	pParam->ProcName[0] = 0;
		//	GetProcName(pParam->ProcName,NULL);//Irp????

			if(CurrIrql<DISPATCH_LEVEL) {
				if(HookDevice->Flags & DO_DEVICE_HAS_NAME)
				{
					if(DevName = ExAllocatePoolWithTag(NonPagedPool,MAXPATHLEN*sizeof(WCHAR),'DSeB'))
					{
						if(NT_SUCCESS(ObQueryNameString(HookDevice,DevName,MAXPATHLEN*sizeof(WCHAR),&actualLen)))
						{
							if(fullPathName.Buffer = ExAllocatePoolWithTag(NonPagedPool,MAXPATHLEN,'DSeB'))
							{
								FPNAllocated=TRUE;
								fullPathName.Length=0;
								fullPathName.MaximumLength=MAXPATHLEN;
								RtlUnicodeStringToAnsiString(&fullPathName,&DevName->Name,FALSE);
							}
						}
					}
				}
				else 
				{
					if(fullPathName.Buffer=ExAllocatePoolWithTag(NonPagedPool,MAXPATHLEN,'DSeB'))
					{
						FPNAllocated=TRUE;
						fullPathName.Length=10;
						fullPathName.MaximumLength=MAXPATHLEN;
						sprintf(fullPathName.Buffer,">%08x<",HookDevice);
					}
				}
			}

			pParam->FunctionMj = currentIrpStack->MajorFunction;
			if(currentIrpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL || 
				currentIrpStack->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL)
			{
				ioControlCode = IoGetFunctionCodeFromCtlCode(currentIrpStack->Parameters.DeviceIoControl.IoControlCode);//(currentIrpStack->Parameters.DeviceIoControl.IoControlCode & 0x1ffc)>>2;
				if(ioControlCode > sizeof(NTDiskDeviceIOCTLName)/sizeof(PVOID))
				{
					DbPrint(DC_DISK,DL_SPAM, ("!!! Disk_IOCTL 0x%x(0x%x) %s\n",
						currentIrpStack->Parameters.DeviceIoControl.IoControlCode, ioControlCode, 
						fullPathName.Buffer == NULL ? UnknownStr : fullPathName.Buffer));
					ioControlCode=0;
				}
				pParam->FunctionMi = ioControlCode;
			}
			else if(currentIrpStack->MajorFunction==IRP_MJ_READ || currentIrpStack->MajorFunction==IRP_MJ_WRITE)
			{
				SectorSize = currentIrpStack->DeviceObject->SectorSize == 0 ? 512 : currentIrpStack->DeviceObject->SectorSize;

				ParamVal=(ULONG)(*(__int64*)(&currentIrpStack->Parameters.Read.ByteOffset)/SectorSize);
				ByteOffset = currentIrpStack->Parameters.Read.ByteOffset;
				DataLength = currentIrpStack->Parameters.Read.Length;
				DbPrint(DC_DISK,DL_SPAM, ("%s %s Sec=%u Len=%u\n", NTMajorFunctionName[currentIrpStack->MajorFunction], 
					fullPathName.Buffer == NULL ? UnknownStr : fullPathName.Buffer, ParamVal, DataLength));
				
				pParam->FunctionMi = currentIrpStack->MinorFunction;
			} else 
				pParam->FunctionMi = currentIrpStack->MinorFunction;
		#ifdef __DBG__
				Action=ExAllocatePoolWithTag(NonPagedPool,MY_PAGE_SIZE,'DSeB');
				if(Action) {
					DbPrint(DC_DISK,DL_INFO, ("%s %s (IRQL=%d)\n",
						NTGetFunctionStr(Action, pParam->HookID, pParam->FunctionMj, pParam->FunctionMi), 
						fullPathName.Buffer == NULL ? UnknownStr : fullPathName.Buffer, CurrIrql));
					ExFreePool(Action);
				}
		#endif //__DBG__

		#ifdef __DBG__
		//		if(IoIsOperationSynchronous(Irp)==FALSE)
		//			DbPrint(DC_DISK,DL_NOTIFY,("^^^^^^^^^  Async operation !!!!!!!!!\n"));
		#endif //__DBG__

			if (IsNeedFilterEventAsyncChk(pParam->HookID, pParam->FunctionMj, pParam->FunctionMi,Irp, &bInvisible) == TRUE) {
				SINGLE_PARAM_INIT_NONE(pSingleParam, _PARAM_OBJECT_URL);
				sprintf(pSingleParam->ParamValue, "%s", fullPathName.Buffer);	//сюда имя девайса
				pSingleParam->ParamSize = strlen(pSingleParam->ParamValue) + 1;
				
				SINGLE_PARAM_SHIFT(pSingleParam);
				SINGLE_PARAM_INIT_LARGEINTEGER(pSingleParam, _PARAM_OBJECT_BYTEOFFSET, ByteOffset);

				//+ ----------------------------------------------------------------------------------------
				SINGLE_PARAM_SHIFT(pSingleParam);
				SINGLE_PARAM_INIT_ULONG(pSingleParam, _PARAM_OBJECT_DATALEN, DataLength);
				
				// -----------------------------------------------------------------------------------------
				// reserve place for sid
				SINGLE_PARAM_SHIFT(pSingleParam);
				SINGLE_PARAM_INIT_SID(pSingleParam);
				pParam->ParamsCount++;
				// end reserve place for sid
				// -----------------------------------------------------------------------------------------
				
				Verdict = FilterEvent(pParam, NULL);
				if(!_PASS_VERDICT(Verdict)) {
					if(Verdict == Verdict_Kill) {
						DbPrint(DC_DISK,DL_NOTIFY, ("Kill %s\n", pParam->ProcName));
						KillCurrentProcess();
					} else if(Verdict == Verdict_Discard) {
						DbPrint(DC_DISK,DL_NOTIFY, ("Discard disk operation\n"/*, pSingleParam->ParamValue*/));
					}
					ntStatus = STATUS_ACCESS_DENIED;
				}
			}
			ExFreePool(RequestData);
		}
	}

	if (ntStatus != STATUS_ACCESS_DENIED)
	{
		DevEntry=DiskDevList;
		while(DevEntry) {
			if(DevEntry->Drv==HookDevice->DriverObject)
				break;
			DevEntry=DevEntry->Next;
		}
		
		if(DevEntry)
			ntStatus=(DevEntry->DiskDevDispArray[currentIrpStack->MajorFunction])(HookDevice,Irp);
		else {
			DbPrint(DC_DISK,DL_WARNING, ("!!! DiskDevDispatch. Device 0x%x (Drv=0x%x) not found in hooked list\n",HookDevice,HookDevice->DriverObject));
			ntStatus=Irp->IoStatus.Status=STATUS_NO_SUCH_DEVICE;
			Irp->IoStatus.Information=0;
			IoCompleteRequest(Irp,IO_NO_INCREMENT);
		}
	}
	if (DevName != NULL)
		ExFreePool(DevName);
	if (fullPathName.Buffer != NULL)
		ExFreePool(fullPathName.Buffer);
	
	return ntStatus;
}
Exemplo n.º 19
0
/*++
 * @name IoRegisterDeviceInterface
 * @implemented
 *
 * Registers a device interface class, if it has not been previously registered,
 * and creates a new instance of the interface class, which a driver can
 * subsequently enable for use by applications or other system components.
 * Documented in WDK.
 *
 * @param PhysicalDeviceObject
 *        Points to an optional PDO that narrows the search to only the
 *        device interfaces of the device represented by the PDO
 *
 * @param InterfaceClassGuid
 *        Points to a class GUID specifying the device interface class
 *
 * @param ReferenceString
 *        Optional parameter, pointing to a unicode string. For a full
 *        description of this rather rarely used param (usually drivers
 *        pass NULL here) see WDK
 *
 * @param SymbolicLinkName
 *        Pointer to the resulting unicode string
 *
 * @return Usual NTSTATUS
 *
 * @remarks Must be called at IRQL = PASSIVE_LEVEL in the context of a
 *          system thread
 *
 *--*/
NTSTATUS
NTAPI
IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject,
                          IN CONST GUID *InterfaceClassGuid,
                          IN PUNICODE_STRING ReferenceString OPTIONAL,
                          OUT PUNICODE_STRING SymbolicLinkName)
{
    PUNICODE_STRING InstancePath;
    UNICODE_STRING GuidString;
    UNICODE_STRING SubKeyName;
    UNICODE_STRING InterfaceKeyName;
    UNICODE_STRING BaseKeyName;
    UCHAR PdoNameInfoBuffer[sizeof(OBJECT_NAME_INFORMATION) + (256 * sizeof(WCHAR))];
    POBJECT_NAME_INFORMATION PdoNameInfo = (POBJECT_NAME_INFORMATION)PdoNameInfoBuffer;
    UNICODE_STRING DeviceInstance = RTL_CONSTANT_STRING(L"DeviceInstance");
    UNICODE_STRING SymbolicLink = RTL_CONSTANT_STRING(L"SymbolicLink");
    HANDLE ClassKey;
    HANDLE InterfaceKey;
    HANDLE SubKey;
    ULONG StartIndex;
    OBJECT_ATTRIBUTES ObjectAttributes;
    ULONG i;
    NTSTATUS Status, SymLinkStatus;
    PEXTENDED_DEVOBJ_EXTENSION DeviceObjectExtension;

    ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    DPRINT("IoRegisterDeviceInterface(): PDO %p, RefString: %wZ\n",
        PhysicalDeviceObject, ReferenceString);

    /* Parameters must pass three border of checks */
    DeviceObjectExtension = (PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension;

    /* 1st level: Presence of a Device Node */
    if (DeviceObjectExtension->DeviceNode == NULL)
    {
        DPRINT("PhysicalDeviceObject 0x%p doesn't have a DeviceNode\n", PhysicalDeviceObject);
        return STATUS_INVALID_DEVICE_REQUEST;
    }

    /* 2nd level: Presence of an non-zero length InstancePath */
    if (DeviceObjectExtension->DeviceNode->InstancePath.Length == 0)
    {
        DPRINT("PhysicalDeviceObject 0x%p's DOE has zero-length InstancePath\n", PhysicalDeviceObject);
        return STATUS_INVALID_DEVICE_REQUEST;
    }

    /* 3rd level: Optional, based on WDK documentation */
    if (ReferenceString != NULL)
    {
        /* Reference string must not contain path-separator symbols */
        for (i = 0; i < ReferenceString->Length / sizeof(WCHAR); i++)
        {
            if ((ReferenceString->Buffer[i] == '\\') ||
                (ReferenceString->Buffer[i] == '/'))
                return STATUS_INVALID_DEVICE_REQUEST;
        }
    }

    Status = RtlStringFromGUID(InterfaceClassGuid, &GuidString);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("RtlStringFromGUID() failed with status 0x%08lx\n", Status);
        return Status;
    }

    /* Create Pdo name: \Device\xxxxxxxx (unnamed device) */
    Status = ObQueryNameString(
        PhysicalDeviceObject,
        PdoNameInfo,
        sizeof(PdoNameInfoBuffer),
        &i);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("ObQueryNameString() failed with status 0x%08lx\n", Status);
        return Status;
    }
    ASSERT(PdoNameInfo->Name.Length);

    /* Create base key name for this interface: HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses\{GUID} */
    ASSERT(((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode);
    InstancePath = &((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode->InstancePath;
    BaseKeyName.Length = (USHORT)wcslen(BaseKeyString) * sizeof(WCHAR);
    BaseKeyName.MaximumLength = BaseKeyName.Length
        + GuidString.Length;
    BaseKeyName.Buffer = ExAllocatePool(
        PagedPool,
        BaseKeyName.MaximumLength);
    if (!BaseKeyName.Buffer)
    {
        DPRINT("ExAllocatePool() failed\n");
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    wcscpy(BaseKeyName.Buffer, BaseKeyString);
    RtlAppendUnicodeStringToString(&BaseKeyName, &GuidString);

    /* Create BaseKeyName key in registry */
    InitializeObjectAttributes(
        &ObjectAttributes,
        &BaseKeyName,
        OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE | OBJ_OPENIF,
        NULL, /* RootDirectory */
        NULL); /* SecurityDescriptor */

    Status = ZwCreateKey(
        &ClassKey,
        KEY_WRITE,
        &ObjectAttributes,
        0, /* TileIndex */
        NULL, /* Class */
        REG_OPTION_VOLATILE,
        NULL); /* Disposition */

    if (!NT_SUCCESS(Status))
    {
        DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
        ExFreePool(BaseKeyName.Buffer);
        return Status;
    }

    /* Create key name for this interface: ##?#ACPI#PNP0501#1#{GUID} */
    InterfaceKeyName.Length = 0;
    InterfaceKeyName.MaximumLength =
        4 * sizeof(WCHAR) + /* 4  = size of ##?# */
        InstancePath->Length +
        sizeof(WCHAR) +     /* 1  = size of # */
        GuidString.Length;
    InterfaceKeyName.Buffer = ExAllocatePool(
        PagedPool,
        InterfaceKeyName.MaximumLength);
    if (!InterfaceKeyName.Buffer)
    {
        DPRINT("ExAllocatePool() failed\n");
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlAppendUnicodeToString(&InterfaceKeyName, L"##?#");
    StartIndex = InterfaceKeyName.Length / sizeof(WCHAR);
    RtlAppendUnicodeStringToString(&InterfaceKeyName, InstancePath);
    for (i = 0; i < InstancePath->Length / sizeof(WCHAR); i++)
    {
        if (InterfaceKeyName.Buffer[StartIndex + i] == '\\')
            InterfaceKeyName.Buffer[StartIndex + i] = '#';
    }
    RtlAppendUnicodeToString(&InterfaceKeyName, L"#");
    RtlAppendUnicodeStringToString(&InterfaceKeyName, &GuidString);

    /* Create the interface key in registry */
    InitializeObjectAttributes(
        &ObjectAttributes,
        &InterfaceKeyName,
        OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE | OBJ_OPENIF,
        ClassKey,
        NULL); /* SecurityDescriptor */

    Status = ZwCreateKey(
        &InterfaceKey,
        KEY_WRITE,
        &ObjectAttributes,
        0, /* TileIndex */
        NULL, /* Class */
        REG_OPTION_VOLATILE,
        NULL); /* Disposition */

    if (!NT_SUCCESS(Status))
    {
        DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
        ZwClose(ClassKey);
        ExFreePool(BaseKeyName.Buffer);
        return Status;
    }

    /* Write DeviceInstance entry. Value is InstancePath */
    Status = ZwSetValueKey(
        InterfaceKey,
        &DeviceInstance,
        0, /* TileIndex */
        REG_SZ,
        InstancePath->Buffer,
        InstancePath->Length);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
        ZwClose(InterfaceKey);
        ZwClose(ClassKey);
        ExFreePool(InterfaceKeyName.Buffer);
        ExFreePool(BaseKeyName.Buffer);
        return Status;
    }

    /* Create subkey. Name is #ReferenceString */
    SubKeyName.Length = 0;
    SubKeyName.MaximumLength = sizeof(WCHAR);
    if (ReferenceString && ReferenceString->Length)
        SubKeyName.MaximumLength += ReferenceString->Length;
    SubKeyName.Buffer = ExAllocatePool(
        PagedPool,
        SubKeyName.MaximumLength);
    if (!SubKeyName.Buffer)
    {
        DPRINT("ExAllocatePool() failed\n");
        ZwClose(InterfaceKey);
        ZwClose(ClassKey);
        ExFreePool(InterfaceKeyName.Buffer);
        ExFreePool(BaseKeyName.Buffer);
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    RtlAppendUnicodeToString(&SubKeyName, L"#");
    if (ReferenceString && ReferenceString->Length)
        RtlAppendUnicodeStringToString(&SubKeyName, ReferenceString);

    /* Create SubKeyName key in registry */
    InitializeObjectAttributes(
        &ObjectAttributes,
        &SubKeyName,
        OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
        InterfaceKey, /* RootDirectory */
        NULL); /* SecurityDescriptor */

    Status = ZwCreateKey(
        &SubKey,
        KEY_WRITE,
        &ObjectAttributes,
        0, /* TileIndex */
        NULL, /* Class */
        REG_OPTION_VOLATILE,
        NULL); /* Disposition */

    if (!NT_SUCCESS(Status))
    {
        DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
        ZwClose(InterfaceKey);
        ZwClose(ClassKey);
        ExFreePool(InterfaceKeyName.Buffer);
        ExFreePool(BaseKeyName.Buffer);
        return Status;
    }

    /* Create symbolic link name: \??\ACPI#PNP0501#1#{GUID}\ReferenceString */
    SymbolicLinkName->Length = 0;
    SymbolicLinkName->MaximumLength = SymbolicLinkName->Length
        + 4 * sizeof(WCHAR) /* 4 = size of \??\ */
        + InstancePath->Length
        + sizeof(WCHAR)     /* 1  = size of # */
        + GuidString.Length
        + sizeof(WCHAR);    /* final NULL */
    if (ReferenceString && ReferenceString->Length)
        SymbolicLinkName->MaximumLength += sizeof(WCHAR) + ReferenceString->Length;
    SymbolicLinkName->Buffer = ExAllocatePool(
        PagedPool,
        SymbolicLinkName->MaximumLength);
    if (!SymbolicLinkName->Buffer)
    {
        DPRINT("ExAllocatePool() failed\n");
        ZwClose(SubKey);
        ZwClose(InterfaceKey);
        ZwClose(ClassKey);
        ExFreePool(InterfaceKeyName.Buffer);
        ExFreePool(SubKeyName.Buffer);
        ExFreePool(BaseKeyName.Buffer);
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    RtlAppendUnicodeToString(SymbolicLinkName, L"\\??\\");
    StartIndex = SymbolicLinkName->Length / sizeof(WCHAR);
    RtlAppendUnicodeStringToString(SymbolicLinkName, InstancePath);
    for (i = 0; i < InstancePath->Length / sizeof(WCHAR); i++)
    {
        if (SymbolicLinkName->Buffer[StartIndex + i] == '\\')
            SymbolicLinkName->Buffer[StartIndex + i] = '#';
    }
    RtlAppendUnicodeToString(SymbolicLinkName, L"#");
    RtlAppendUnicodeStringToString(SymbolicLinkName, &GuidString);
    SymbolicLinkName->Buffer[SymbolicLinkName->Length/sizeof(WCHAR)] = L'\0';

    /* Create symbolic link */
    DPRINT("IoRegisterDeviceInterface(): creating symbolic link %wZ -> %wZ\n", SymbolicLinkName, &PdoNameInfo->Name);
    SymLinkStatus = IoCreateSymbolicLink(SymbolicLinkName, &PdoNameInfo->Name);

    /* If the symbolic link already exists, return an informational success status */
    if (SymLinkStatus == STATUS_OBJECT_NAME_COLLISION)
    {
        /* HACK: Delete the existing symbolic link and update it to the new PDO name */
        IoDeleteSymbolicLink(SymbolicLinkName);
        IoCreateSymbolicLink(SymbolicLinkName, &PdoNameInfo->Name);
        SymLinkStatus = STATUS_OBJECT_NAME_EXISTS;
    }

    if (!NT_SUCCESS(SymLinkStatus))
    {
        DPRINT1("IoCreateSymbolicLink() failed with status 0x%08lx\n", SymLinkStatus);
        ZwClose(SubKey);
        ZwClose(InterfaceKey);
        ZwClose(ClassKey);
        ExFreePool(SubKeyName.Buffer);
        ExFreePool(InterfaceKeyName.Buffer);
        ExFreePool(BaseKeyName.Buffer);
        ExFreePool(SymbolicLinkName->Buffer);
        return SymLinkStatus;
    }

    if (ReferenceString && ReferenceString->Length)
    {
        RtlAppendUnicodeToString(SymbolicLinkName, L"\\");
        RtlAppendUnicodeStringToString(SymbolicLinkName, ReferenceString);
    }
    SymbolicLinkName->Buffer[SymbolicLinkName->Length/sizeof(WCHAR)] = L'\0';

    /* Write symbolic link name in registry */
    SymbolicLinkName->Buffer[1] = '\\';
    Status = ZwSetValueKey(
        SubKey,
        &SymbolicLink,
        0, /* TileIndex */
        REG_SZ,
        SymbolicLinkName->Buffer,
        SymbolicLinkName->Length);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("ZwSetValueKey() failed with status 0x%08lx\n", Status);
        ExFreePool(SymbolicLinkName->Buffer);
    }
    else
    {
        SymbolicLinkName->Buffer[1] = '?';
    }

    ZwClose(SubKey);
    ZwClose(InterfaceKey);
    ZwClose(ClassKey);
    ExFreePool(SubKeyName.Buffer);
    ExFreePool(InterfaceKeyName.Buffer);
    ExFreePool(BaseKeyName.Buffer);

    return NT_SUCCESS(Status) ? SymLinkStatus : Status;
}
Exemplo n.º 20
0
Arquivo: util.c Projeto: Endt4sk/sebek
/*
 * Retrieve the full pathname (including files and registry keys) for a
 * given handle. This method is from "Undocumented Windows NT".
 */
BOOLEAN PathFromHandle (HANDLE hKey, PUNICODE_STRING lpszSubKeyVal, PCHAR fullname)
{
	PVOID			pKey = NULL;
	ANSI_STRING		keyname;
	PCHAR			tmpname;
	PUNICODE_STRING		fullUniName;
	ULONG			actualLen;

	if(!fullname)
		return FALSE;

	/* Allocate a temporary buffer */
	tmpname = ExAllocatePoolWithTag (PagedPool, MAXPATHLEN, HELPER_POOL_TAG);
	if (tmpname == NULL)
		/* Not enough memory */
		return FALSE;

	*fullname = *tmpname = '\0';

	/*
	 * Translate the hKey into a pointer to check whether it is a valid
	 * handle.
	 */
	if (NT_SUCCESS (ObReferenceObjectByHandle (hKey, 0, NULL, KernelMode, 
		&pKey, NULL)) && pKey != NULL) {

		fullUniName = ExAllocatePoolWithTag (PagedPool, MAXPATHLEN * 2 + 
			2 * sizeof(ULONG), 
			HELPER_POOL_TAG);
		if (fullUniName == NULL) {
			/* Not enough memory */
			ObDereferenceObject (pKey);
			ExFreePool (tmpname);
			return FALSE;
		}

		fullUniName->MaximumLength = MAXPATHLEN*2;
		if (NT_SUCCESS (ObQueryNameString (pKey, fullUniName, 
			MAXPATHLEN, &actualLen ))) {
			if (NT_SUCCESS (RtlUnicodeStringToAnsiString (
				&keyname, fullUniName, TRUE))) { 
				if(*keyname.Buffer != '\0') {
					if (*keyname.Buffer != '\\')
						strcpy (tmpname, "\\");
					else
						strcpy (tmpname, "");
					strncat (tmpname, keyname.Buffer, 
						min( keyname.Length, 
						MAXPATHLEN - 2 ));
				}
				RtlFreeAnsiString (&keyname);
			}
		}

		ObDereferenceObject (pKey);
		ExFreePool (fullUniName);
	}

	/* Append subkey and value if they are there */
	if (lpszSubKeyVal != NULL) {
		keyname.Buffer = NULL;
		if (NT_SUCCESS (RtlUnicodeStringToAnsiString (&keyname, 
			lpszSubKeyVal, TRUE))) {
			if (*keyname.Buffer != '\0') {
				size_t iLen = MAXPATHLEN - (strlen(tmpname) - 1);
				strcat(tmpname, "\\");
				strncat(tmpname, keyname.Buffer,	min(keyname.Length, iLen));
			}
			RtlFreeAnsiString (&keyname);
		}
	}

	strcpy (fullname, tmpname);
	ExFreePool (tmpname);

return TRUE;
}
Exemplo n.º 21
0
ULONG  
GetRegFullPath( HANDLE hKey, PVOID pRootObject, PUNICODE_STRING pSubKey, PNAME_BUFFER pRegBuffer )
{	
	NTSTATUS                  Status      = STATUS_SUCCESS;
	PVOID                     pKey        = NULL;
	POBJECT_NAME_INFORMATION  pObjectName = NULL; 
	ULONG                     ulTempLen=0, ulRet=0, ulLength=0;
    
	if(KeGetCurrentIrql() >= DISPATCH_LEVEL) 
	{
		return 0;
	}
	if(!pRegBuffer || !pRegBuffer->pBuffer) 
	{
		return 0;
	}

	if(hKey) 
	{
		if(((ULONG_PTR)hKey>0) || (ExGetPreviousMode() == KernelMode))  
		{
			ObReferenceObjectByHandle( hKey, 0, NULL, KernelMode, &pKey, NULL);
		}
	}
	else if(pRootObject)
	{
		pKey = pRootObject;
		ObReferenceObject( pKey ); 
	}
	else
	{
		return 0;
	}
	if(!pKey) return 0;

	KeEnterCriticalRegion();
	
	pObjectName = (POBJECT_NAME_INFORMATION)ExAllocatePoolWithTag( NonPagedPool, MAX_POOL_LEN, MALWFIND_NAME_TAG );
	if(!pObjectName) 
	{
		KeLeaveCriticalRegion();
		return 0;
	}
		
	RtlZeroMemory( pObjectName, MAX_POOL_LEN );
	pObjectName->Name.Length        = 0;
	pObjectName->Name.MaximumLength = (MAX_POOL_LEN >> 1);

	Status = ObQueryNameString( pKey, pObjectName, MAX_POOL_LEN, &ulRet );
	if(!NT_SUCCESS( Status ))
	{
		if(pObjectName) 
		{
			ExFreePoolWithTag( pObjectName, MALWFIND_NAME_TAG );
			pObjectName = NULL;
		}
		KeLeaveCriticalRegion();
		return 0;
	}
	ObDereferenceObject( pKey ); 
		
	ulLength += pObjectName->Name.Length;
	Status = RtlStringCchCatNW( pRegBuffer->pBuffer, pRegBuffer->ulMaxLength, pObjectName->Name.Buffer, pObjectName->Name.Length );  
	if(!NT_SUCCESS( Status ))
	{
		if(pObjectName) 
		{
			ExFreePoolWithTag( pObjectName, MALWFIND_NAME_TAG );
			pObjectName = NULL;
		}
		KeLeaveCriticalRegion();
		return 0;
	}
				
	if(pSubKey && pSubKey->Buffer && pSubKey->Length)
	{
		ulLength += sizeof(WCHAR);
		ulTempLen = sizeof(WCHAR);
		Status = RtlStringCchCatNW( pRegBuffer->pBuffer, pRegBuffer->ulMaxLength, L"\\", ulTempLen );

		ulLength += pSubKey->Length;
		Status = RtlStringCchCatNW( pRegBuffer->pBuffer, pRegBuffer->ulMaxLength, pSubKey->Buffer, pSubKey->Length );
	}
		
	if(pObjectName)
	{
		ExFreePoolWithTag( pObjectName, MALWFIND_NAME_TAG );
		pObjectName = NULL;
	}

	KeLeaveCriticalRegion();
	return ulLength;
		
}
Exemplo n.º 22
0
NTSTATUS
GetAllDiskObjects()
/*++

Routine Description:

   Enumeration all disk devices

Arguments:

   None

Return Value:

    None

--*/
{
    NTSTATUS		Status;
    PDRIVER_OBJECT	pDiskObject;
    PDEVICE_OBJECT	pDeviceObjectTemp;
    UNICODE_STRING	DestinationString;
    DWORD			dwDeviceNumber;
    DWORD			dwRetLength;
    POBJECT_NAME_INFORMATION pNameBuffer;
    WCHAR			*pNameTemp;
	PDISK_OBJ		pDisk;
	PDISK_GEOMETRY	pDiskGeometry;
	BOOLEAN			bIsFound = FALSE;
	PDEVICE_EXTENSION	pDevExtn = (PDEVICE_EXTENSION)gp_DevObj->DeviceExtension;

    /* All Disk Objects are created by disk.sys driver*/
	RtlInitUnicodeString(&DestinationString, L"\\Driver\\Disk");
    
	// Not a documented function in DDK, see import definition in sector.h
	if (ObReferenceObjectByName(&DestinationString, 64, 0, 0,
								*IoDriverObjectType, KernelMode, 0,
								&pDiskObject) >= 0) 
	{
        pDeviceObjectTemp = pDiskObject->DeviceObject;
        dwDeviceNumber = 0;
        
		if (pDeviceObjectTemp)
        {
			pDiskGeometry = ExAllocatePool(NonPagedPool, sizeof(DISK_GEOMETRY));
            
			if (!pDiskGeometry) 
			{
                       return STATUS_INSUFFICIENT_RESOURCES;
            }

            do
            {
				//Each time memset the geometry structure to zero
				memset(pDiskGeometry, 0x00, sizeof(DISK_GEOMETRY));

                // DeviceType 7 corresponds to FILE_DISK_DEVICE Type Device Object and
				// It should have name too that's why Flags is check for 0x40 (DO_DEVICE_HAS_NAME )
				//DbgPrint("DeviceType: %d", pDeviceObjectTemp->DeviceType);
				if (pDeviceObjectTemp->DeviceType == 7
                        && (pDeviceObjectTemp->Flags & 0x40))
                {
                   ObQueryNameString(pDeviceObjectTemp, NULL, 0, &dwRetLength);

                   pNameBuffer = (POBJECT_NAME_INFORMATION)
									ExAllocatePoolWithTag(PagedPool, dwRetLength, ' sFI');
                   
				   if (!pNameBuffer)
                   {
					   ExFreePool(pDiskGeometry);
                       return STATUS_INSUFFICIENT_RESOURCES;
                   }
                   
				   if (ObQueryNameString(pDeviceObjectTemp, pNameBuffer,
										 dwRetLength, &dwRetLength) == STATUS_SUCCESS 
										 && pNameBuffer->Name.Buffer)
                   {
					   //DbgPrint("pNameBuffer->Name.Buffer: %ws", pNameBuffer->Name.Buffer);
						pDisk  = ExAllocatePool(PagedPool, sizeof(DISK_OBJ));
						
						if (!pDisk) 
						{
									ExFreePool(pDiskGeometry);
									ExFreePool(pNameBuffer);
									return STATUS_INSUFFICIENT_RESOURCES;
						}
                       
						for (pNameTemp = pNameBuffer->Name.Buffer +
							 wcslen(pNameBuffer->Name.Buffer); 
							 pNameTemp > pNameBuffer->Name.Buffer; pNameTemp--) 
						{
							//DbgPrint("pNameTemp: %ws", pNameTemp);
									if (!_wcsnicmp(pNameTemp, L"\\DR", 3)) 
									{
										pDisk->bIsRawDiskObj = TRUE;
										bIsFound = TRUE;
										break;
									}
									else if (!_wcsnicmp(pNameTemp, L"\\DP(", 4)) 
									{
										pDisk->bIsRawDiskObj = FALSE;
										bIsFound = TRUE;
										break;
									}
						}
						if (bIsFound) 
						{
							pDisk->dwDiskOrdinal = (USHORT)pNameBuffer->
													Name.Buffer[wcslen(pNameBuffer->Name.Buffer)-1] 
													- (USHORT) L'0';
							pDisk->pDiskDevObj	= pDeviceObjectTemp;

							ExInterlockedInsertTailList(&pDevExtn->list_head, &pDisk->list, &pDevExtn->list_lock);
							
							Status = GetGeometry(pDisk->pDiskDevObj, pDiskGeometry);

							if (!NT_SUCCESS(Status)) 
							{
								pDisk->bGeometryFound = FALSE;
							} 
							else 
							{
								pDisk->bGeometryFound = TRUE;
								pDisk->ulSectorSize = pDiskGeometry->BytesPerSector;
							}
			
						} //end of if (bIsFound) 
                   }//end of if (ObQueryNameString ...)
                   ExFreePoolWithTag(pNameBuffer, 0);

                }//end of if (pDeviceObjectTemp->DeviceType == 7 ...)
                pDeviceObjectTemp = pDeviceObjectTemp->NextDevice;
            } while (pDeviceObjectTemp); // end of while
			ExFreePool(pDiskGeometry); //Free pDiskGeometry
        }
    }
	return STATUS_SUCCESS;
}
Exemplo n.º 23
0
NTSTATUS
RegistryCallback(
_In_ PVOID CallbackContext,
_In_opt_ PVOID Argument1,
_In_opt_ PVOID Argument2
)
{

	REG_NOTIFY_CLASS Operation = (REG_NOTIFY_CLASS)(ULONG_PTR)Argument1;
	ULONG_PTR arg2= (ULONG_PTR)Argument2;
	switch (Operation)
	{
	case RegNtPreCreateKeyEx:
	{
								PREG_CREATE_KEY_INFORMATION CallbackData = (PREG_CREATE_KEY_INFORMATION)arg2;
								if (CallbackData->CompleteName->Length == 0 || *CallbackData->CompleteName->Buffer != OBJ_NAME_PATH_SEPARATOR)
								{
									SendRegistryOperationToUserland(REG_PRE_CREATE, CallbackData->CompleteName);
									DbgPrint("RegNtPreCreateKeyEx %wZ", CallbackData->CompleteName);
								}
	}
		break;
	case RegNtPreOpenKeyEx:
		break;
	{
							  PREG_OPEN_KEY_INFORMATION CallbackData = (PREG_OPEN_KEY_INFORMATION)arg2;
							  if (CallbackData->CompleteName->Length == 0 || *CallbackData->CompleteName->Buffer != OBJ_NAME_PATH_SEPARATOR)
							  { 
								  //Get the name of the rootObject where the stuff is done.
								  ULONG allocatedSTRSize = 1024 * sizeof(UNICODE_STRING);
								  PUNICODE_STRING root_name = ExAllocatePoolWithTag(NonPagedPool, 1024 * sizeof(UNICODE_STRING), SPY_TAG);
								  ULONG returnedLength;
								  //CAll obQueryNAmeString.
								  NTSTATUS obQueryStatus = ObQueryNameString(CallbackData->RootObject
									  , (POBJECT_NAME_INFORMATION)root_name
									  , allocatedSTRSize
									  , &returnedLength);

								  if (obQueryStatus == STATUS_SUCCESS)
								  {
									  if (root_name != NULL)
									  {
										  ULONG newSize = CallbackData->CompleteName->Length + root_name->Length + 1/*bonus for the backslash*/;
										  if (newSize < allocatedSTRSize)
										  {
											  //Add the backslash
											  RtlUnicodeStringCat(root_name, "\\");
											  //Add at the end of the stuff the complete name.
											  RtlUnicodeStringCat(root_name, CallbackData->CompleteName);
										  }
										  SendRegistryOperationToUserland(REG_PRE_OPEN, root_name);
										  DbgPrint("RegNtPreOpenKeyEx: %wZ", root_name);
									  }
									  else
										  DbgPrint("RegNtPreOpenKeyEx NAME %wZ || ROOT NOT PRESENT!", CallbackData->CompleteName, root_name);
								  }
								  else
								  {
									  DbgPrint("RegNtPreOpenKeyEx -> Unable to recover the object name.");
								  }
								  //Free the AllocatedPool
								  if (root_name != NULL)
									  ExFreePoolWithTag(root_name, SPY_TAG);
							  }
	}
		break;
	case RegNtDeleteKey:
	{
						   PREG_DELETE_KEY_INFORMATION CallbackData = (PREG_DELETE_KEY_INFORMATION)arg2;
						   //In this case use the ObQueryNameString
						   //TODO -> Determine if Paged should work here.
						   ULONG allocatedSTRSize = 1024 * sizeof(UNICODE_STRING);
						   PUNICODE_STRING object_name = ExAllocatePoolWithTag(NonPagedPool, 1024 * sizeof(UNICODE_STRING), SPY_TAG);
						   ULONG returnedLength;
						   //CAll obQueryNAmeString.
						   NTSTATUS obQueryStatus = ObQueryNameString(CallbackData->Object
							   , (POBJECT_NAME_INFORMATION)object_name
							   , allocatedSTRSize
							   , &returnedLength);

						   if (obQueryStatus == STATUS_SUCCESS)
						   {
							   DbgPrint("RegNtDeleteKey -> %wZ", object_name);
							   SendRegistryOperationToUserland(REG_DELETE_KEY, object_name);
						   }
						   else
						   {
							   DbgPrint("RegNtDeleteKey -> Unable to recover the object name.");
						   }
						   //Free the AllocatedPool
						   if (object_name != NULL)
							   ExFreePoolWithTag(object_name, SPY_TAG);
	}
		break;
	case RegNtDeleteValueKey:
	{
								PREG_DELETE_VALUE_KEY_INFORMATION CallbackData = (PREG_DELETE_VALUE_KEY_INFORMATION)arg2;
								//In this case use the ObQueryNameString
								//TODO -> Determine if Paged should work here.
								ULONG allocatedSTRSize = 1024 * sizeof(UNICODE_STRING);
								PUNICODE_STRING object_name = ExAllocatePoolWithTag(NonPagedPool, 1024 * sizeof(UNICODE_STRING), SPY_TAG);
								ULONG returnedLength;
								//CAll obQueryNAmeString.
								NTSTATUS obQueryStatus = ObQueryNameString(CallbackData->Object
									, (POBJECT_NAME_INFORMATION)object_name
									, allocatedSTRSize
									, &returnedLength);

								if (obQueryStatus == STATUS_SUCCESS)
								{
									DbgPrint("RegNtDeleteValueKey -> %wZ", object_name);
									SendRegistryOperationToUserland(REG_DELETE_VALUE, object_name);
								}
								else
								{
									DbgPrint("RegNtDeleteValueKey -> Unable to recover the object name.");
								}
								//Free the AllocatedPool
								if (object_name != NULL)
									ExFreePoolWithTag(object_name, SPY_TAG);

	}
		break;
	case RegNtSetValueKey:
	{

							 PREG_SET_VALUE_KEY_INFORMATION CallbackData = (PREG_SET_VALUE_KEY_INFORMATION)arg2;
							 //In this case use the ObQueryNameString
							 //TODO -> Determine if Paged should work here.
							 ULONG allocatedSTRSize = 1024 * sizeof(UNICODE_STRING);
							 PUNICODE_STRING root_name = ExAllocatePoolWithTag(NonPagedPool, 1024 * sizeof(UNICODE_STRING), SPY_TAG);
							 ULONG returnedLength;
							 //CAll obQueryNAmeString.
							 NTSTATUS obQueryStatus = ObQueryNameString(CallbackData->Object
								 , (POBJECT_NAME_INFORMATION)root_name
								 , allocatedSTRSize
								 , &returnedLength);

							 if (obQueryStatus == STATUS_SUCCESS)
							 {								 
								 ULONG newSize = CallbackData->ValueName->Length + root_name->Length + 1;
								 if (newSize < allocatedSTRSize)
								 {
									 RtlUnicodeStringCat(root_name, "\\");
									 RtlUnicodeStringCat(root_name, CallbackData->ValueName);
									 //Use CallbackData->Data and DataSize to detect wich is the new data to modify
									 SendRegistryOperationToUserland(REG_SET_VALUE, root_name);
									 DbgPrint("RegNtSetValueKey -> %wZ", root_name);
								 }
							 }
							 else
							 {
								 DbgPrint("RegNtSetValueKey -> Unable to recover the object name.");
							 }
							 //Free the AllocatedPool
							 if (root_name != NULL)
								 ExFreePoolWithTag(root_name, SPY_TAG);


	}
		break;
	}
	return STATUS_SUCCESS;
}
Exemplo n.º 24
0
NTSTATUS
NTAPI
SeInitializeProcessAuditName(IN PFILE_OBJECT FileObject,
                             IN BOOLEAN DoAudit,
                             OUT POBJECT_NAME_INFORMATION *AuditInfo)
{
    OBJECT_NAME_INFORMATION LocalNameInfo;
    POBJECT_NAME_INFORMATION ObjectNameInfo = NULL;
    ULONG ReturnLength = 8;
    NTSTATUS Status;

    PAGED_CODE();
    ASSERT(AuditInfo);

    /* Check if we should do auditing */
    if (DoAudit)
    {
        /* FIXME: TODO */
    }

    /* Now query the name */
    Status = ObQueryNameString(FileObject,
                               &LocalNameInfo,
                               sizeof(LocalNameInfo),
                               &ReturnLength);
    if (((Status == STATUS_BUFFER_OVERFLOW) ||
            (Status == STATUS_BUFFER_TOO_SMALL) ||
            (Status == STATUS_INFO_LENGTH_MISMATCH)) &&
            (ReturnLength != sizeof(LocalNameInfo)))
    {
        /* Allocate required size */
        ObjectNameInfo = ExAllocatePoolWithTag(NonPagedPool,
                                               ReturnLength,
                                               TAG_SEPA);
        if (ObjectNameInfo)
        {
            /* Query the name again */
            Status = ObQueryNameString(FileObject,
                                       ObjectNameInfo,
                                       ReturnLength,
                                       &ReturnLength);
        }
    }

    /* Check if we got here due to failure */
    if ((ObjectNameInfo) &&
            (!(NT_SUCCESS(Status)) || (ReturnLength == sizeof(LocalNameInfo))))
    {
        /* First, free any buffer we might've allocated */
        ASSERT(FALSE);
        if (ObjectNameInfo) ExFreePool(ObjectNameInfo);

        /* Now allocate a temporary one */
        ReturnLength = sizeof(OBJECT_NAME_INFORMATION);
        ObjectNameInfo = ExAllocatePoolWithTag(NonPagedPool,
                                               sizeof(OBJECT_NAME_INFORMATION),
                                               TAG_SEPA);
        if (ObjectNameInfo)
        {
            /* Clear it */
            RtlZeroMemory(ObjectNameInfo, ReturnLength);
            Status = STATUS_SUCCESS;
        }
    }

    /* Check if memory allocation failed */
    if (!ObjectNameInfo) Status = STATUS_NO_MEMORY;

    /* Return the audit name */
    *AuditInfo = ObjectNameInfo;

    /* Return status */
    return Status;
}
Exemplo n.º 25
0
BOOLEAN GetRegistryObjectCompleteName(
	PUNICODE_STRING pRegistryPath, 
	PUNICODE_STRING pPartialRegistryPath, 
	PVOID pRegistryObject
)
{
	NTSTATUS		status;
	BOOLEAN			bFoundCompleteName = FALSE;
	ULONG			ulReturLength;
	PUNICODE_STRING	pObjectName = NULL;

	if ((!MmIsAddressValid(pRegistryObject)) || (pRegistryObject == NULL))
	{
		return FALSE;
	}

	/* 如果 pPartialRegistryPath 不为 NULL,且符合绝对路径规则,则直接返回给外部使用*/
	if (pPartialRegistryPath != NULL && pPartialRegistryPath->Length >= 4)
	{
		if ((((pPartialRegistryPath->Buffer[0] == '\\') || (pPartialRegistryPath->Buffer[0] == '%')) ||
			((pPartialRegistryPath->Buffer[0] == 'T') && (pPartialRegistryPath->Buffer[1] == 'R') &&
			(pPartialRegistryPath->Buffer[2] == 'Y') && (pPartialRegistryPath->Buffer[3] == '\\'))))
		{
			RtlCopyUnicodeString(pRegistryPath, pPartialRegistryPath);
			bFoundCompleteName = TRUE;
		}
	}

	/* 如果不符合绝对路径规则,则查询 pRegistryObject 对应的注册表对象和 pPartialRegistryPath 拼接 */
	if (!bFoundCompleteName)
	{
		status = ObQueryNameString(pRegistryObject, NULL, 0, &ulReturLength);
		if (status == STATUS_INFO_LENGTH_MISMATCH)
		{
			pObjectName = ExAllocatePoolWithTag(NonPagedPool, ulReturLength, MEM_TAG);
			status = ObQueryNameString(pRegistryObject, (POBJECT_NAME_INFORMATION)pObjectName, ulReturLength, &ulReturLength);
			if (NT_SUCCESS(status))
			{
				/* 将查询到的注册表对象拷贝到传出参数中 */
				RtlCopyUnicodeString(pRegistryPath, pObjectName);

				/* 如果 pPartialRegistryPath 不为 NULL,则是新建的项名 */
				/* 如果为 NULL,则是删除项名,不用拷贝到路径后面。*/
				if (NULL != pPartialRegistryPath)
				{
					status = RtlUnicodeStringCatString(pRegistryPath, L"\\");
					if (!NT_SUCCESS(status))
					{
						KdPrint(("Failed to call RtlUnicodeStringCatString, error code = 0x%08X\r\n", status));
					}
					RtlUnicodeStringCat(pRegistryPath, pPartialRegistryPath);
					if (!NT_SUCCESS(status))
					{
						KdPrint(("Failed to call RtlUnicodeStringCat, error code = 0x%08X\r\n", status));
					}
				}
				bFoundCompleteName = TRUE;
			}
			ExFreePoolWithTag(pObjectName, MEM_TAG);
		}
	}

	return bFoundCompleteName;
}
Exemplo n.º 26
0
int handle_fobject(PFILE_OBJECT fobject, PUCHAR obuffer) 
{
  ULONG length;
  ANSI_STRING astring;
  PUCHAR fname, cur_pointer;
  PFILE_OBJECT related_fobject;
  UCHAR status;

  fname=obuffer+12;
  status=0;
	
  if(fobject->DeviceObject!=NULL) 
  {
    if(NT_SUCCESS(ObQueryNameString(fobject->DeviceObject, 
                  (POBJECT_NAME_INFORMATION)fname,out_size-20,&length))) 
    {
      if(NT_SUCCESS(RtlUnicodeStringToAnsiString(&astring,
                                                 (PUNICODE_STRING)fname,TRUE))) 
      {
        *fname='\0';
        strncpy(fname, astring.Buffer, astring.Length+1);
        status=1;

        fname+=astring.Length;
        *fname='\0';

        RtlFreeAnsiString(&astring);
      }
    }
  }

  if((length=fobject->FileName.Length>>1)||(fobject->RelatedFileObject!=NULL)) 
  {
    related_fobject=fobject->RelatedFileObject;
    if(length&&(fobject->FileName.Buffer[0]!='\\')) 
      while(related_fobject!=NULL) 
      {
        length+=related_fobject->FileName.Length>>1;
        related_fobject=related_fobject->RelatedFileObject;
      }

    if(length) 
    {
      RtlUnicodeStringToAnsiString(&astring,&(fobject->FileName),TRUE);
      strncpy(cur_pointer=fname+(length-(fobject->FileName.Length>>1)),
              astring.Buffer,astring.Length+1);
      status=1;
      RtlFreeAnsiString(&astring);

      related_fobject=fobject->RelatedFileObject;

      if(fobject->FileName.Buffer[0]!='\\') 
        while(related_fobject!=NULL) 
        {
          *(cur_pointer-1)='\\';
          cur_pointer-=(related_fobject->FileName.Length>>1);//+1; 

          RtlUnicodeStringToAnsiString(&astring,&(related_fobject->FileName), 
                                       TRUE);
          strncpy(cur_pointer, astring.Buffer, astring.Length+1);
          status=1;      
          RtlFreeAnsiString(&astring);

          related_fobject=related_fobject->RelatedFileObject;
        }
    }
  }	
  return(status?(fname-obuffer)+length:0);
}
Exemplo n.º 27
0
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Description :
//		Registry callback. Logs any registry interaction performed by monitored processes.
//	Parameters :
//		See http://msdn.microsoft.com/en-us/library/windows/hardware/ff560903(v=vs.85).aspx
//	Return value :
//		See http://msdn.microsoft.com/en-us/library/windows/hardware/ff560903(v=vs.85).aspx
//	Process :
//		Checks the operation and logs the associated data.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS regCallback (PVOID CallbackContext, PVOID Argument1, PVOID Argument2)
{
	NTSTATUS status, tmpCall;
	UNICODE_STRING full_data, test;
	PUNICODE_STRING tmp = NULL;
	PUNICODE_STRING valueName = NULL;
	PREG_SET_VALUE_KEY_INFORMATION arg = NULL;
	ULONG returnedLength = 0;
	PWCHAR pwBuf = NULL;
	PWCHAR tmp_data = NULL;
	ULONG pid = (ULONG)PsGetCurrentProcessId();
	DWORD i = 0;
	
	if(!isProcessMonitoredByPid(pid) || ExGetPreviousMode() == KernelMode)
		return STATUS_SUCCESS;
	
	pwBuf = ExAllocatePoolWithTag(NonPagedPool, (MAXSIZE+1)*sizeof(WCHAR), BUFFER_TAG);
	if(pwBuf == NULL)
		return STATUS_SUCCESS;
	
	tmp = ExAllocatePoolWithTag(NonPagedPool, MAXSIZE*sizeof(WCHAR), TEMP_TAG);
	if(tmp == NULL)
	{
		ExFreePool(tmp);
		return STATUS_SUCCESS;
	}
	
	switch((REG_NOTIFY_CLASS)Argument1)
	{	
		case RegNtPreDeleteKey:
			status = ObQueryNameString(((PREG_DELETE_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call DeleteKey() \n");
				#endif
				
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", tmp)))
					sendLogs(pid, L"REGISTRY_DELETE_KEY", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_DELETE_KEY", L"1,0,s,SubKey->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_DELETE_KEY", L"0,-1,s,SubKey->ERROR");
		break;
		
		case RegNtPreSetValueKey: 
			arg = (PREG_SET_VALUE_KEY_INFORMATION)Argument2; 
			status = ObQueryNameString(arg->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call SetValueKey() \n");
				#endif
				
				switch(arg->Type)
				{
					case REG_SZ:
						tmpCall = RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,sss,SubKey->%wZ,ValueName->%wZ,Data->%ws", tmp, arg->ValueName, ((PWCHAR)arg->Data));
					break;
					default :					
						tmp_data = ExAllocatePoolWithTag(NonPagedPool, MAXSIZE, 'gnaA');
						full_data.MaximumLength = MAXSIZE;
						full_data.Buffer = ExAllocatePoolWithTag(NonPagedPool, full_data.MaximumLength, 'baaH');
						RtlZeroMemory(full_data.Buffer, full_data.MaximumLength);
						for(i=0; i<arg->DataSize; i++)
						{
							if(i==100)
								break;
							RtlStringCchPrintfW(tmp_data, MAXSIZE, L"\\x%02x", *((PWCHAR)arg->Data+i));
							if(i==0)
							{
								RtlInitUnicodeString(&test, tmp_data);
								RtlCopyUnicodeString(&full_data, &test);
							}
							if(NT_SUCCESS(RtlAppendUnicodeToString(&full_data, tmp_data)))
								RtlZeroMemory(tmp_data, MAXSIZE);
						}
						tmpCall = RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,sss,SubKey->%wZ,ValueName->%wZ,Data->%wZ", tmp, arg->ValueName, &full_data);
						ExFreePool(full_data.Buffer);
						ExFreePool(tmp_data);
					break;	
				}
				if(NT_SUCCESS(tmpCall))
					sendLogs(pid, L"REGISTRY_VALUE_KEY_SET", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_VALUE_KEY_SET", L"1,0,sss,SubKey->ERROR,ValueName->ERROR,Data->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_VALUE_KEY_SET", L"1,0,sss,SubKey->ERROR,ValueName->ERROR,Data->ERROR");
		break;
		
		case RegNtPreDeleteValueKey:
			status = ObQueryNameString(((PREG_DELETE_VALUE_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call DeleteValueKey() !\n");
				#endif
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,ss,SubKey->%wZ,ValueName->%wZ", tmp, ((PREG_DELETE_VALUE_KEY_INFORMATION)Argument2)->ValueName)))
					sendLogs(pid, L"REGISTRY_VALUE_KEY_DELETE", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_VALUE_KEY_DELETE", L"1,0,ss,SubKey->ERROR,ValueName->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_VALUE_KEY_DELETE", L"1,0,ss,SubKey->ERROR,ValueName->ERROR");
		break;

		case RegNtPreRenameKey:
			status = ObQueryNameString(((PREG_RENAME_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call RenameKey() !\n");
				#endif
				
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,ss,SubKey->%wZ,NewName->%wZ", tmp, ((PREG_RENAME_KEY_INFORMATION)Argument2)->NewName)))
					sendLogs(pid, L"REGISTRY_KEY_RENAME", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_KEY_RENAME", L"1,0,ss,SubKey->ERROR,NewName->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_KEY_RENAME", L"1,0,ss,SubKey->ERROR,NewName->ERROR");
		break;
		
		case RegNtPreEnumerateKey:
			status = ObQueryNameString(((PREG_ENUMERATE_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call EnumerateKey() !\n");
				#endif
				
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", tmp)))
					sendLogs(pid, L"REGISTRY_ENUMERATE_KEY", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_ENUMERATE_KEY", L"1,0,s,SubKey->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_ENUMERATE_KEY", L"1,0,s,SubKey->ERROR");
		break;
		
		case RegNtPreEnumerateValueKey:
			status = ObQueryNameString(((PREG_ENUMERATE_VALUE_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call EnumerateValueKey() !\n");
				#endif
				
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", tmp)))
					sendLogs(pid, L"REGISTRY_ENUMERATE_VALUE_KEY", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_ENUMERATE_VALUE_KEY", L"1,0,s,SubKey->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_ENUMERATE_VALUE_KEY", L"1,0,s,SubKey->ERROR");
		break;
		
		case RegNtPreQueryKey:
			status = ObQueryNameString(((PREG_QUERY_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call QueryKey()! \n");
				#endif
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", tmp)))
					sendLogs(pid, L"REGISTRY_QUERY_KEY", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_QUERY_KEY", L"1,0,s,SubKey->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_QUERY_KEY", L"1,0,s,SubKey->ERROR");
		break;
		
		case RegNtPreQueryValueKey:
			status = ObQueryNameString(((PREG_QUERY_VALUE_KEY_INFORMATION)Argument2)->Object, (POBJECT_NAME_INFORMATION)tmp, MAXSIZE, &returnedLength);
			if(NT_SUCCESS(status))
			{
				#ifdef DEBUG
				DbgPrint("call QueryValueKey() !\n");
				#endif
				
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,ss,SubKey->%wZ,ValueName->%wZ", tmp, ((PREG_QUERY_VALUE_KEY_INFORMATION)Argument2)->ValueName)))
					sendLogs(pid, L"REGISTRY_QUERY_VALUE_KEY", pwBuf);	
				else
					sendLogs(pid, L"REGISTRY_QUERY_VALUE_KEY", L"1,0,ss,SubKey->ERROR,ValueName->ERROR");
			}
			else
				sendLogs(pid, L"REGISTRY_QUERY_VALUE_KEY", L"1,0,ss,SubKey->ERROR,ValueName->ERROR");
		break;
		
		case RegNtPreCreateKey:
			#ifdef DEBUG
			DbgPrint("call CreateKey() !\n");
			#endif
			if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", ((PREG_PRE_CREATE_KEY_INFORMATION)Argument2)->CompleteName)))
				sendLogs(pid,L"REGISTRY_CREATE_KEY", pwBuf);
			else
				sendLogs(pid, L"REGISTRY_CREATE_KEY", L"1,0,s,SubKey->ERROR");
		break;
		
		case RegNtPreCreateKeyEx:
			#ifdef DEBUG
			DbgPrint("call CreateKeyEx() !\n");
			#endif
			if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", ((PREG_PRE_CREATE_KEY_INFORMATION)Argument2)->CompleteName)))
				sendLogs(pid,L"REGISTRY_CREATE_KEY", pwBuf);
			else
				sendLogs(pid, L"REGISTRY_CREATE_KEY", L"1,0,s,SubKey->ERROR");
		break;
		
		case RegNtPreOpenKey:
			#ifdef DEBUG
			DbgPrint("call OpenKey() !\n");
			#endif
			
			if(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer != NULL)
			{
				if(!_wcsicmp(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer, L"SOFTWARE\\Oracle\\VirtualBox Guest Additions") || !_wcsicmp(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer, L"SOFTWARE\\VMware, Inc.\\VMware Tools"))
				{
					if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"0,0,s,SubKey->%wZ", ((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName)))
						sendLogs(pid,L"REGISTRY_OPEN_KEY", pwBuf);
					return STATUS_OBJECT_NAME_NOT_FOUND;
				}
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", ((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName)))
					sendLogs(pid,L"REGISTRY_OPEN_KEY", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_OPEN_KEY", L"1,0,s,SubKey->ERROR");	
			}
			else
				sendLogs(pid, L"REGISTRY_OPEN_KEY", L"1,0,s,SubKey->ERROR");
		break;
		
		case RegNtPreOpenKeyEx:
			#ifdef DEBUG
			DbgPrint("call OpenKeyEx() !\n");
			#endif
			
			if(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer != NULL)
			{
				if(!_wcsicmp(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer, L"SOFTWARE\\Oracle\\VirtualBox Guest Additions") || !_wcsicmp(((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName->Buffer, L"SOFTWARE\\VMware, Inc.\\VMware Tools"))
				{
					if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"0,0,s,SubKey->%wZ", ((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName)))
						sendLogs(pid,L"REGISTRY_OPEN_KEY", pwBuf);
					return STATUS_OBJECT_NAME_NOT_FOUND;
				}
				if(NT_SUCCESS(RtlStringCchPrintfW(pwBuf, MAXSIZE, L"1,0,s,SubKey->%wZ", ((PREG_OPEN_KEY_INFORMATION)Argument2)->CompleteName)))
					sendLogs(pid,L"REGISTRY_OPEN_KEY", pwBuf);
				else
					sendLogs(pid, L"REGISTRY_OPEN_KEY", L"1,0,s,SubKey->ERROR");	
			}
			else
				sendLogs(pid, L"REGISTRY_OPEN_KEY", L"1,0,s,SubKey->ERROR");
		break;

		default:
		break;
	}
	
	ExFreePool(tmp);
	ExFreePool(pwBuf);
		
	return STATUS_SUCCESS;
 }
Exemplo n.º 28
0
VOID
drbdlockCallbackFunc(
	IN PVOID Context,
	IN PVOID Argument1,
	IN PVOID Argument2
	)
/*++

Routine Description:

	This routine is called whenever other driver notifies drbdlock's callback object.

Arguments:

	Context - not used.
	Argument1 - Pointer to the DRBDLOCK_VOLUME_CONTROL data structure containing volume information to be (un)blocked.
	Argument2 - not used.

Return Value:

	None.

--*/
{
	UNREFERENCED_PARAMETER(Context);
	UNREFERENCED_PARAMETER(Argument2);

	PDRBDLOCK_VOLUME_CONTROL pVolumeControl = (PDRBDLOCK_VOLUME_CONTROL)Argument1;
	PDEVICE_OBJECT pVolObj = NULL;
	NTSTATUS status = STATUS_UNSUCCESSFUL;
	ULONG ulSize = 0;
	POBJECT_NAME_INFORMATION pNameInfo = NULL;

	if (pVolumeControl == NULL)
	{
		// invalid parameter.
		drbdlock_print_log("pVolumeControl is NULL\n");
		return;
	}
	
	status = ConvertVolume(&pVolumeControl->volume, &pVolObj);
	if (!NT_SUCCESS(status))
	{
		drbdlock_print_log("ConvertVolume failed, status : 0x%x\n", status);
		return;
	}

	if (STATUS_INFO_LENGTH_MISMATCH == ObQueryNameString(pVolObj, NULL, 0, &ulSize))
	{
		pNameInfo = (POBJECT_NAME_INFORMATION)ExAllocatePool(NonPagedPool, ulSize);		
		if (pNameInfo)
		{
			status = ObQueryNameString(pVolObj, pNameInfo, ulSize, &ulSize);
			if (!NT_SUCCESS(status))
			{
				ulSize = 0;
			}
		}
	}	

	if (pVolumeControl->bBlock)
	{
		if (AddProtectedVolume(pVolObj))
		{			
			drbdlock_print_log("volume(%ws) has been added as protected\n", ulSize? pNameInfo->Name.Buffer : L"NULL");
		}
		else
		{
			drbdlock_print_log("volume(%ws) add failed\n", ulSize ? pNameInfo->Name.Buffer : L"NULL");
		}
	}
	else
	{
		if (DeleteProtectedVolume(pVolObj))
		{
			drbdlock_print_log("volume(%ws) has been deleted from protected volume list\n", ulSize ? pNameInfo->Name.Buffer : L"NULL");
		}
		else
		{
			drbdlock_print_log("volume(%ws) delete failed\n", ulSize ? pNameInfo->Name.Buffer : L"NULL");
		}
	}


}