Example #1
0
        private ResultCode MapCodeMemoryInProcess(KProcess process, ulong baseAddress, ulong size, out ulong targetAddress)
        {
            KPageTableBase memMgr = process.MemoryManager;

            targetAddress = 0;

            int retryCount;

            ulong addressSpacePageLimit = (memMgr.GetAddrSpaceSize() - size) >> 12;

            for (retryCount = 0; retryCount < MaxMapRetries; retryCount++)
            {
                while (true)
                {
                    ulong randomOffset = (ulong)(uint)_random.Next(0, (int)addressSpacePageLimit) << 12;

                    targetAddress = memMgr.GetAddrSpaceBaseAddr() + randomOffset;

                    if (memMgr.InsideAddrSpace(targetAddress, size) && !memMgr.InsideHeapRegion(targetAddress, size) && !memMgr.InsideAliasRegion(targetAddress, size))
                    {
                        break;
                    }
                }

                KernelResult result = memMgr.MapProcessCodeMemory(targetAddress, baseAddress, size);

                if (result == KernelResult.InvalidMemState)
                {
                    continue;
                }
                else if (result != KernelResult.Success)
                {
                    return((ResultCode)result);
                }

                if (!CanAddGuardRegionsInProcess(process, targetAddress, size))
                {
                    continue;
                }

                return(ResultCode.Success);
            }

            if (retryCount == MaxMapRetries)
            {
                return(ResultCode.InsufficientAddressSpace);
            }

            return(ResultCode.Success);
        }
Example #2
0
        private ResultCode MapNro(KProcess process, NroInfo info, out ulong nroMappedAddress)
        {
            KPageTableBase memMgr = process.MemoryManager;

            int retryCount = 0;

            nroMappedAddress = 0;

            while (retryCount++ < MaxMapRetries)
            {
                ResultCode result = MapCodeMemoryInProcess(process, info.NroAddress, info.NroSize, out nroMappedAddress);

                if (result != ResultCode.Success)
                {
                    return(result);
                }

                if (info.BssSize > 0)
                {
                    KernelResult bssMappingResult = memMgr.MapProcessCodeMemory(nroMappedAddress + info.NroSize, info.BssAddress, info.BssSize);

                    if (bssMappingResult == KernelResult.InvalidMemState)
                    {
                        memMgr.UnmapProcessCodeMemory(nroMappedAddress + info.NroSize, info.BssAddress, info.BssSize);
                        memMgr.UnmapProcessCodeMemory(nroMappedAddress, info.NroAddress, info.NroSize);

                        continue;
                    }
                    else if (bssMappingResult != KernelResult.Success)
                    {
                        memMgr.UnmapProcessCodeMemory(nroMappedAddress + info.NroSize, info.BssAddress, info.BssSize);
                        memMgr.UnmapProcessCodeMemory(nroMappedAddress, info.NroAddress, info.NroSize);

                        return((ResultCode)bssMappingResult);
                    }
                }

                if (CanAddGuardRegionsInProcess(process, nroMappedAddress, info.TotalSize))
                {
                    return(ResultCode.Success);
                }
            }

            return(ResultCode.InsufficientAddressSpace);
        }