private KernelResult ParseProcessInfo(ProcessCreationInfo creationInfo) { // Ensure that the current kernel version is equal or above to the minimum required. uint requiredKernelVersionMajor = (uint)Capabilities.KernelReleaseVersion >> 19; uint requiredKernelVersionMinor = ((uint)Capabilities.KernelReleaseVersion >> 15) & 0xf; if (System.EnableVersionChecks) { if (requiredKernelVersionMajor > KernelVersionMajor) { return(KernelResult.InvalidCombination); } if (requiredKernelVersionMajor != KernelVersionMajor && requiredKernelVersionMajor < 3) { return(KernelResult.InvalidCombination); } if (requiredKernelVersionMinor > KernelVersionMinor) { return(KernelResult.InvalidCombination); } } KernelResult result = AllocateThreadLocalStorage(out ulong userExceptionContextAddress); if (result != KernelResult.Success) { return(result); } UserExceptionContextAddress = userExceptionContextAddress; MemoryHelper.FillWithZeros(CpuMemory, (long)userExceptionContextAddress, KTlsPageInfo.TlsEntrySize); Name = creationInfo.Name; _state = ProcessState.Created; _creationTimestamp = PerformanceCounter.ElapsedMilliseconds; MmuFlags = creationInfo.MmuFlags; _category = creationInfo.Category; TitleId = creationInfo.TitleId; _entrypoint = creationInfo.CodeAddress; _imageSize = (ulong)creationInfo.CodePagesCount * KMemoryManager.PageSize; _useSystemMemBlocks = ((MmuFlags >> 6) & 1) != 0; switch ((AddressSpaceType)((MmuFlags >> 1) & 7)) { case AddressSpaceType.Addr32Bits: case AddressSpaceType.Addr36Bits: case AddressSpaceType.Addr39Bits: _memoryUsageCapacity = MemoryManager.HeapRegionEnd - MemoryManager.HeapRegionStart; break; case AddressSpaceType.Addr32BitsNoMap: _memoryUsageCapacity = MemoryManager.HeapRegionEnd - MemoryManager.HeapRegionStart + MemoryManager.AliasRegionEnd - MemoryManager.AliasRegionStart; break; default: throw new InvalidOperationException($"Invalid MMU flags value 0x{MmuFlags:x2}."); } GenerateRandomEntropy(); return(KernelResult.Success); }
public KernelResult Initialize( ProcessCreationInfo creationInfo, int[] caps, KResourceLimit resourceLimit, MemoryRegion memRegion) { ResourceLimit = resourceLimit; _memRegion = memRegion; ulong personalMmHeapSize = GetPersonalMmHeapSize((ulong)creationInfo.PersonalMmHeapPagesCount, memRegion); ulong codePagesCount = (ulong)creationInfo.CodePagesCount; ulong neededSizeForProcess = personalMmHeapSize + codePagesCount * KMemoryManager.PageSize; if (neededSizeForProcess != 0 && resourceLimit != null) { if (!resourceLimit.Reserve(LimitableResource.Memory, neededSizeForProcess)) { return(KernelResult.ResLimitExceeded); } } void CleanUpForError() { if (neededSizeForProcess != 0 && resourceLimit != null) { resourceLimit.Release(LimitableResource.Memory, neededSizeForProcess); } } PersonalMmHeapPagesCount = (ulong)creationInfo.PersonalMmHeapPagesCount; KMemoryBlockAllocator memoryBlockAllocator; if (PersonalMmHeapPagesCount != 0) { memoryBlockAllocator = new KMemoryBlockAllocator(PersonalMmHeapPagesCount * KMemoryManager.PageSize); } else { memoryBlockAllocator = (MmuFlags & 0x40) != 0 ? System.LargeMemoryBlockAllocator : System.SmallMemoryBlockAllocator; } AddressSpaceType addrSpaceType = (AddressSpaceType)((creationInfo.MmuFlags >> 1) & 7); InitializeMemoryManager(addrSpaceType, memRegion); bool aslrEnabled = ((creationInfo.MmuFlags >> 5) & 1) != 0; ulong codeAddress = creationInfo.CodeAddress; ulong codeSize = codePagesCount * KMemoryManager.PageSize; KernelResult result = MemoryManager.InitializeForProcess( addrSpaceType, aslrEnabled, !aslrEnabled, memRegion, codeAddress, codeSize, memoryBlockAllocator); if (result != KernelResult.Success) { CleanUpForError(); return(result); } if (!ValidateCodeAddressAndSize(codeAddress, codeSize)) { CleanUpForError(); return(KernelResult.InvalidMemRange); } result = MemoryManager.MapNewProcessCode( codeAddress, codePagesCount, MemoryState.CodeStatic, MemoryPermission.None); if (result != KernelResult.Success) { CleanUpForError(); return(result); } result = Capabilities.InitializeForUser(caps, MemoryManager); if (result != KernelResult.Success) { CleanUpForError(); return(result); } Pid = System.GetProcessId(); if (Pid == -1 || (ulong)Pid < Horizon.InitialProcessId) { throw new InvalidOperationException($"Invalid Process Id {Pid}."); } result = ParseProcessInfo(creationInfo); if (result != KernelResult.Success) { CleanUpForError(); } return(result); }
public KernelResult InitializeKip( ProcessCreationInfo creationInfo, int[] caps, KPageList pageList, KResourceLimit resourceLimit, MemoryRegion memRegion) { ResourceLimit = resourceLimit; _memRegion = memRegion; AddressSpaceType addrSpaceType = (AddressSpaceType)((creationInfo.MmuFlags >> 1) & 7); InitializeMemoryManager(addrSpaceType, memRegion); bool aslrEnabled = ((creationInfo.MmuFlags >> 5) & 1) != 0; ulong codeAddress = creationInfo.CodeAddress; ulong codeSize = (ulong)creationInfo.CodePagesCount * KMemoryManager.PageSize; KMemoryBlockAllocator memoryBlockAllocator = (MmuFlags & 0x40) != 0 ? System.LargeMemoryBlockAllocator : System.SmallMemoryBlockAllocator; KernelResult result = MemoryManager.InitializeForProcess( addrSpaceType, aslrEnabled, !aslrEnabled, memRegion, codeAddress, codeSize, memoryBlockAllocator); if (result != KernelResult.Success) { return(result); } if (!ValidateCodeAddressAndSize(codeAddress, codeSize)) { return(KernelResult.InvalidMemRange); } result = MemoryManager.MapPages( codeAddress, pageList, MemoryState.CodeStatic, MemoryPermission.None); if (result != KernelResult.Success) { return(result); } result = Capabilities.InitializeForKernel(caps, MemoryManager); if (result != KernelResult.Success) { return(result); } Pid = System.GetKipId(); if (Pid == 0 || (ulong)Pid >= Horizon.InitialProcessId) { throw new InvalidOperationException($"Invalid KIP Id {Pid}."); } result = ParseProcessInfo(creationInfo); return(result); }
public KernelResult Initialize( ProcessCreationInfo creationInfo, ReadOnlySpan <int> capabilities, KResourceLimit resourceLimit, MemoryRegion memRegion, IProcessContextFactory contextFactory, ThreadStart customThreadStart = null) { ResourceLimit = resourceLimit; _memRegion = memRegion; _contextFactory = contextFactory ?? new ProcessContextFactory(); _customThreadStart = customThreadStart; ulong personalMmHeapSize = GetPersonalMmHeapSize((ulong)creationInfo.SystemResourcePagesCount, memRegion); ulong codePagesCount = (ulong)creationInfo.CodePagesCount; ulong neededSizeForProcess = personalMmHeapSize + codePagesCount * KMemoryManager.PageSize; if (neededSizeForProcess != 0 && resourceLimit != null) { if (!resourceLimit.Reserve(LimitableResource.Memory, neededSizeForProcess)) { return(KernelResult.ResLimitExceeded); } } void CleanUpForError() { if (neededSizeForProcess != 0 && resourceLimit != null) { resourceLimit.Release(LimitableResource.Memory, neededSizeForProcess); } } PersonalMmHeapPagesCount = (ulong)creationInfo.SystemResourcePagesCount; KMemoryBlockAllocator memoryBlockAllocator; if (PersonalMmHeapPagesCount != 0) { memoryBlockAllocator = new KMemoryBlockAllocator(PersonalMmHeapPagesCount * KMemoryManager.PageSize); } else { memoryBlockAllocator = creationInfo.Flags.HasFlag(ProcessCreationFlags.IsApplication) ? KernelContext.LargeMemoryBlockAllocator : KernelContext.SmallMemoryBlockAllocator; } AddressSpaceType addrSpaceType = (AddressSpaceType)((int)(creationInfo.Flags & ProcessCreationFlags.AddressSpaceMask) >> (int)ProcessCreationFlags.AddressSpaceShift); InitializeMemoryManager(creationInfo.Flags); bool aslrEnabled = creationInfo.Flags.HasFlag(ProcessCreationFlags.EnableAslr); ulong codeAddress = creationInfo.CodeAddress; ulong codeSize = codePagesCount * KMemoryManager.PageSize; KernelResult result = MemoryManager.InitializeForProcess( addrSpaceType, aslrEnabled, !aslrEnabled, memRegion, codeAddress, codeSize, memoryBlockAllocator); if (result != KernelResult.Success) { CleanUpForError(); return(result); } if (!MemoryManager.CanContain(codeAddress, codeSize, MemoryState.CodeStatic)) { CleanUpForError(); return(KernelResult.InvalidMemRange); } result = MemoryManager.MapNewProcessCode( codeAddress, codePagesCount, MemoryState.CodeStatic, KMemoryPermission.None); if (result != KernelResult.Success) { CleanUpForError(); return(result); } result = Capabilities.InitializeForUser(capabilities, MemoryManager); if (result != KernelResult.Success) { CleanUpForError(); return(result); } Pid = KernelContext.NewProcessId(); if (Pid == -1 || (ulong)Pid < KernelConstants.InitialProcessId) { throw new InvalidOperationException($"Invalid Process Id {Pid}."); } result = ParseProcessInfo(creationInfo); if (result != KernelResult.Success) { CleanUpForError(); } return(result); }
public KernelResult InitializeKip( ProcessCreationInfo creationInfo, ReadOnlySpan <int> capabilities, KPageList pageList, KResourceLimit resourceLimit, MemoryRegion memRegion, IProcessContextFactory contextFactory, ThreadStart customThreadStart = null) { ResourceLimit = resourceLimit; _memRegion = memRegion; _contextFactory = contextFactory ?? new ProcessContextFactory(); _customThreadStart = customThreadStart; AddressSpaceType addrSpaceType = (AddressSpaceType)((int)(creationInfo.Flags & ProcessCreationFlags.AddressSpaceMask) >> (int)ProcessCreationFlags.AddressSpaceShift); InitializeMemoryManager(creationInfo.Flags); bool aslrEnabled = creationInfo.Flags.HasFlag(ProcessCreationFlags.EnableAslr); ulong codeAddress = creationInfo.CodeAddress; ulong codeSize = (ulong)creationInfo.CodePagesCount * KMemoryManager.PageSize; KMemoryBlockAllocator memoryBlockAllocator = creationInfo.Flags.HasFlag(ProcessCreationFlags.IsApplication) ? KernelContext.LargeMemoryBlockAllocator : KernelContext.SmallMemoryBlockAllocator; KernelResult result = MemoryManager.InitializeForProcess( addrSpaceType, aslrEnabled, !aslrEnabled, memRegion, codeAddress, codeSize, memoryBlockAllocator); if (result != KernelResult.Success) { return(result); } if (!MemoryManager.CanContain(codeAddress, codeSize, MemoryState.CodeStatic)) { return(KernelResult.InvalidMemRange); } result = MemoryManager.MapPages( codeAddress, pageList, MemoryState.CodeStatic, KMemoryPermission.None); if (result != KernelResult.Success) { return(result); } result = Capabilities.InitializeForKernel(capabilities, MemoryManager); if (result != KernelResult.Success) { return(result); } Pid = KernelContext.NewKipId(); if (Pid == 0 || (ulong)Pid >= KernelConstants.InitialProcessId) { throw new InvalidOperationException($"Invalid KIP Id {Pid}."); } return(ParseProcessInfo(creationInfo)); }
private KernelResult ParseProcessInfo(ProcessCreationInfo creationInfo) { // Ensure that the current kernel version is equal or above to the minimum required. uint requiredKernelVersionMajor = (uint)Capabilities.KernelReleaseVersion >> 19; uint requiredKernelVersionMinor = ((uint)Capabilities.KernelReleaseVersion >> 15) & 0xf; if (KernelContext.EnableVersionChecks) { if (requiredKernelVersionMajor > KernelVersionMajor) { return(KernelResult.InvalidCombination); } if (requiredKernelVersionMajor != KernelVersionMajor && requiredKernelVersionMajor < 3) { return(KernelResult.InvalidCombination); } if (requiredKernelVersionMinor > KernelVersionMinor) { return(KernelResult.InvalidCombination); } } KernelResult result = AllocateThreadLocalStorage(out ulong userExceptionContextAddress); if (result != KernelResult.Success) { return(result); } UserExceptionContextAddress = userExceptionContextAddress; MemoryHelper.FillWithZeros(CpuMemory, userExceptionContextAddress, KTlsPageInfo.TlsEntrySize); Name = creationInfo.Name; State = ProcessState.Created; _creationTimestamp = PerformanceCounter.ElapsedMilliseconds; Flags = creationInfo.Flags; _version = creationInfo.Version; TitleId = creationInfo.TitleId; _entrypoint = creationInfo.CodeAddress; _imageSize = (ulong)creationInfo.CodePagesCount * KPageTableBase.PageSize; switch (Flags & ProcessCreationFlags.AddressSpaceMask) { case ProcessCreationFlags.AddressSpace32Bit: case ProcessCreationFlags.AddressSpace64BitDeprecated: case ProcessCreationFlags.AddressSpace64Bit: _memoryUsageCapacity = MemoryManager.HeapRegionEnd - MemoryManager.HeapRegionStart; break; case ProcessCreationFlags.AddressSpace32BitWithoutAlias: _memoryUsageCapacity = MemoryManager.HeapRegionEnd - MemoryManager.HeapRegionStart + MemoryManager.AliasRegionEnd - MemoryManager.AliasRegionStart; break; default: throw new InvalidOperationException($"Invalid MMU flags value 0x{Flags:x2}."); } GenerateRandomEntropy(); return(KernelResult.Success); }