Пример #1
0
        private nint AllocateSinglePageNearAddress(nint targetAddr)
        {
            var sysInfo = new NativeImport.NativeStructs.SYSTEM_INFO();

            NativeImport.GetSystemInfo(ref sysInfo);

            nuint pageSize = sysInfo.dwPageSize;

            nuint startAddr = ((nuint)targetAddr & ~(pageSize - 1));
            nuint minAddr   = (nuint)Math.Min((long)(startAddr - 0x7FFFFF00), sysInfo.lpMinimumApplicationAddress.ToInt64());
            nuint maxAddr   = (nuint)Math.Min((long)(startAddr - 0x7FFFFF00), sysInfo.lpMaximumApplicationAddress.ToInt64());

            nuint startPage = (startAddr - (startAddr % pageSize));

            nuint pageOffset = 1;

            while (true)
            {
                nuint byteOffset = pageOffset * pageSize;
                nuint highAddr   = startPage + byteOffset;
                nuint lowAddr    = (startPage > byteOffset) ? startPage - byteOffset : 0;

                bool needsExit = highAddr > maxAddr && lowAddr < minAddr;

                if (highAddr < maxAddr)
                {
                    IntPtr outAddr = NativeImport.VirtualAlloc((nint)highAddr, pageSize, NativeImport.NativeStructs.AllocationType.Commit | NativeImport.NativeStructs.AllocationType.Reserve,
                                                               NativeImport.NativeStructs.MemoryProtection.ExecuteReadWrite);
                    if (outAddr != IntPtr.Zero)
                    {
                        return(outAddr);
                    }
                }

                if (lowAddr > minAddr)
                {
                    IntPtr outAddr = NativeImport.VirtualAlloc((nint)lowAddr, pageSize, NativeImport.NativeStructs.AllocationType.Commit | NativeImport.NativeStructs.AllocationType.Reserve,
                                                               NativeImport.NativeStructs.MemoryProtection.ExecuteReadWrite);
                    if (outAddr != IntPtr.Zero)
                    {
                        return(outAddr);
                    }
                }

                pageOffset++;

                if (needsExit)
                {
                    break;
                }
            }

            return(0);
        }