예제 #1
0
파일: Reader.cs 프로젝트: jjoesten/Falcon
        private static long GetMaxMemFileSize(IntPtr pmemAreaBaseAddr)
        {
            var mbi = new NativeMethods.MEMORY_BASIC_INFORMATION();

            NativeMethods.VirtualQuery(ref pmemAreaBaseAddr, ref mbi, new IntPtr(Marshal.SizeOf(mbi)));
            return(mbi.RegionSize.ToInt64());
        }
예제 #2
0
        private bool FindNeedleInMemory(List <NativeMethods.MEMORY_BASIC_INFORMATION> areas, int alignmentHint, Needle memoryNeedle, out long relativeByteOffset, out NativeMethods.MEMORY_BASIC_INFORMATION memoryPage, StatusUpdate.ProcessType updateType)
        {
            byte[] needle = new byte[] { (byte)memoryNeedle, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x3D, 0x00 };

            currentStatus.Report(new StatusUpdate {
                CurrentProcess = updateType, ProcessPercentage = 0.0f
            });

            for (int i = 0; i < areas.Count; i++)
            {
                currentStatus.Report(new StatusUpdate {
                    CurrentProcess = updateType, ProcessPercentage = i / (float)areas.Count
                });
                var    area      = areas[i];
                byte[] buffer    = new byte[area.RegionSize.ToInt64()];
                int    bytesRead = 0;
                if (NativeMethods.ReadProcessMemory(processHandle, area.BaseAddress, buffer, area.RegionSize, ref bytesRead) == false)
                {
                    int errorCode = Marshal.GetLastWin32Error();
                    if (errorCode == 299)
                    {
                        Trace.WriteLine("Couldn't read entire memory...");
                    }
                    else
                    {
                        Marshal.ThrowExceptionForHR(errorCode);
                    }
                }

                long startOffset = 0;
                while (startOffset != -1)
                {
                    startOffset = SearchBytes(buffer, needle, startOffset, alignmentHint);
                    if (startOffset != -1)
                    {
                        if (buffer[startOffset - 24] == 0x02)
                        {
                            relativeByteOffset = startOffset;
                            memoryPage         = area;
                            currentStatus.Report(new StatusUpdate {
                                CurrentProcess = StatusUpdate.ProcessType.Done, ProcessPercentage = 1.0f, ReadyToWatch = true
                            });
                            return(true);
                        }
                        ++startOffset;
                    }
                }
            }
            relativeByteOffset = -1;
            memoryPage         = new NativeMethods.MEMORY_BASIC_INFORMATION();

            currentStatus.Report(new StatusUpdate {
                CurrentProcess = StatusUpdate.ProcessType.Done, ProcessPercentage = 1.0f
            });
            return(false);
        }
예제 #3
0
        private static bool HasReadAccess(IntPtr hProcess, IntPtr address, out int size)
        {
            size = 0;

            var    memInfo = new NativeMethods.MEMORY_BASIC_INFORMATION();
            IntPtr result  = NativeMethods.VirtualQueryEx(
                hProcess,
                address,
                ref memInfo,
                (IntPtr)Marshal.SizeOf(memInfo));

            if (result == IntPtr.Zero)
            {
                return(false);
            }

            if (memInfo.Protect == NativeMethods.PAGE_NOACCESS || memInfo.Protect == NativeMethods.PAGE_EXECUTE)
            {
                return(false);
            }

            try
            {
                size = Convert.ToInt32(memInfo.RegionSize.ToInt64() - (address.ToInt64() - memInfo.BaseAddress.ToInt64()));
            }
            catch (OverflowException)
            {
                return(false);
            }

            if (size <= 0)
            {
                return(false);
            }

            return(true);
        }
예제 #4
0
 private long GetMaxMemFileSize(IntPtr pMemAreaBaseAddr)
 {
     NativeMethods.MEMORY_BASIC_INFORMATION mbi = new NativeMethods.MEMORY_BASIC_INFORMATION();
     NativeMethods.VirtualQuery(ref pMemAreaBaseAddr, ref mbi, new IntPtr(Marshal.SizeOf(mbi)));
     return mbi.RegionSize.ToInt64();
 }
예제 #5
0
        private List <NativeMethods.MEMORY_BASIC_INFORMATION> FetchMemoryPages()
        {
            currentStatus.Report(new StatusUpdate {
                CurrentProcess = StatusUpdate.ProcessType.ReadingMemory, ProcessPercentage = 0f
            });

            List <NativeMethods.MEMORY_BASIC_INFORMATION> areas = new List <NativeMethods.MEMORY_BASIC_INFORMATION>();

            NativeMethods.SYSTEM_INFO sys_info = new NativeMethods.SYSTEM_INFO();
            NativeMethods.GetSystemInfo(out sys_info);

            IntPtr proc_min_address = sys_info.minimumApplicationAddress;
            IntPtr proc_max_address = sys_info.maximumApplicationAddress;

            long proc_min_address_l = proc_min_address.ToInt64();
            long proc_max_address_l = proc_max_address.ToInt64();

            // this will store any information we get from VirtualQueryEx()
            NativeMethods.MEMORY_BASIC_INFORMATION mem_basic_info = new NativeMethods.MEMORY_BASIC_INFORMATION();

            long startAt = proc_min_address_l;

            while (proc_min_address_l < proc_max_address_l)
            {
                currentStatus.Report(new StatusUpdate {
                    CurrentProcess = StatusUpdate.ProcessType.ReadingMemory, ProcessPercentage = 1 - (proc_max_address_l - proc_min_address_l) / (float)(proc_max_address_l - startAt)
                });
                // 28 = sizeof(NativeMethods.MEMORY_BASIC_INFORMATION)
                NativeMethods.VirtualQueryEx(processHandle, proc_min_address, out mem_basic_info, new UIntPtr(48));
                int errorCode = Marshal.GetLastWin32Error();
                switch (errorCode)
                {
                case 0:
                    // intentionally void
                    break;

                case 299:
                    Trace.WriteLine("Couldn't read entire memory...");
                    break;

                default:
                    Marshal.ThrowExceptionForHR(errorCode);
                    break;
                }

                // if this memory chunk is accessible
                long regionSize = mem_basic_info.RegionSize.ToInt64();
                if (mem_basic_info.Protect == NativeMethods.AllocationProtectEnum.PAGE_READWRITE && mem_basic_info.State == NativeMethods.StateEnum.MEM_COMMIT)
                {
                    // memory area containing our byte usually are more than 100kb big
                    if (mem_basic_info.RegionSize.ToInt64() >= 0x10000)
                    {
                        areas.Add(mem_basic_info);
                    }
                }

                // move to the next memory chunk
                proc_min_address_l += regionSize;
                proc_min_address    = new IntPtr(proc_min_address_l);
            }

            currentStatus.Report(new StatusUpdate {
                CurrentProcess = StatusUpdate.ProcessType.ReadingMemory, ProcessPercentage = 1.0f
            });

            return(areas);
        }
예제 #6
0
        private static bool HasReadAccess(IntPtr hProcess, IntPtr address, out int size)
        {
            size = 0;

            var memInfo = new NativeMethods.MEMORY_BASIC_INFORMATION();
            IntPtr result = NativeMethods.VirtualQueryEx(
                hProcess,
                address,
                ref memInfo,
                (IntPtr)Marshal.SizeOf(memInfo));

            if (result == IntPtr.Zero)
            {
                return false;
            }

            if (memInfo.Protect == NativeMethods.PAGE_NOACCESS || memInfo.Protect == NativeMethods.PAGE_EXECUTE)
            {
                return false;
            }

            try
            {
                size = Convert.ToInt32(memInfo.RegionSize.ToInt64() - (address.ToInt64() - memInfo.BaseAddress.ToInt64()));
            }
            catch (OverflowException)
            {
                return false;
            }

            if (size <= 0)
            {
                return false;
            }

            return true;
        }