Пример #1
0
 internal VirtualAllocSubRegion(MEMORY_BASIC_INFORMATION64 info, bool is32bit, ColorString detail)
     : base(new Address(info.BaseAddress, is32bit), info.RegionSize,
            new ColorString($"MEM_{info.State} PAGE_{(info.Protect == 0 ? PAGE.NOACCESS : info.Protect)} ").Append(detail))
 {
     State   = info.State;
     Protect = info.Protect;
 }
Пример #2
0
        public UIntPtr VirtualQueryEx(IntPtr hProcess, UIntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer)
        {
            UIntPtr retVal;

            // TODO: Need to change this to only check once.
            if (mProc.Is64Bit || IntPtr.Size == 8)
            {
                // 64 bit
                MEMORY_BASIC_INFORMATION64 tmp64 = new MEMORY_BASIC_INFORMATION64();
                retVal = Native_VirtualQueryEx(hProcess, lpAddress, out tmp64, new UIntPtr((uint)Marshal.SizeOf(tmp64)));

                lpBuffer.BaseAddress       = tmp64.BaseAddress;
                lpBuffer.AllocationBase    = tmp64.AllocationBase;
                lpBuffer.AllocationProtect = tmp64.AllocationProtect;
                lpBuffer.RegionSize        = (long)tmp64.RegionSize;
                lpBuffer.State             = tmp64.State;
                lpBuffer.Protect           = tmp64.Protect;
                lpBuffer.Type = tmp64.Type;

                return(retVal);
            }
            MEMORY_BASIC_INFORMATION32 tmp32 = new MEMORY_BASIC_INFORMATION32();

            retVal = Native_VirtualQueryEx(hProcess, lpAddress, out tmp32, new UIntPtr((uint)Marshal.SizeOf(tmp32)));

            lpBuffer.BaseAddress       = tmp32.BaseAddress;
            lpBuffer.AllocationBase    = tmp32.AllocationBase;
            lpBuffer.AllocationProtect = tmp32.AllocationProtect;
            lpBuffer.RegionSize        = tmp32.RegionSize;
            lpBuffer.State             = tmp32.State;
            lpBuffer.Protect           = tmp32.Protect;
            lpBuffer.Type = tmp32.Type;

            return(retVal);
        }
Пример #3
0
        public byte[] GetByteArrayAt(long offset, int size, bool verify = false)
        {
            byte[] returnValue = new byte[size];

            if (verify)
            {
                MEMORY_BASIC_INFORMATION64 memBasicInfo = new MEMORY_BASIC_INFORMATION64();
                VirtualQueryEx(ProcessHandle, new IntPtr(offset), out memBasicInfo, new IntPtr(48));
                bool hasAnyRead = memBasicInfo.Protect.HasFlag(AllocationProtect.PAGE_READONLY) || memBasicInfo.Protect.HasFlag(AllocationProtect.PAGE_READWRITE) || memBasicInfo.Protect.HasFlag(AllocationProtect.PAGE_EXECUTE_READ) || memBasicInfo.Protect.HasFlag(AllocationProtect.PAGE_EXECUTE_READWRITE) || memBasicInfo.Protect.HasFlag(AllocationProtect.PAGE_WRITECOPY); // WRITECOPY also works?
                if (!(hasAnyRead && memBasicInfo.State.HasFlag(MemoryFlags.MEM_COMMIT)))
                {
                    return(returnValue);
                }
            }

            IntPtr bytesRead = IntPtr.Zero;

            if (!ReadProcessMemory(ProcessHandle, offset, returnValue, size, out bytesRead))
            {
                int win32Error = Marshal.GetLastWin32Error();
                throw new Win32Exception(win32Error, ((Win32Error)win32Error).ToString());
            }

            return(returnValue);
        }
Пример #4
0
        public IEnumerable <MEMORY_BASIC_INFORMATION64> MemoryRegions()
        {
            // getting minimum & maximum address

            SYSTEM_INFO sys_info = new SYSTEM_INFO();

            GetSystemInfo(out sys_info);

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

            // saving the values as long ints so I won't have to do a lot of casts later
            ulong proc_min_address_l = (ulong)proc_min_address;
            ulong proc_max_address_l = (ulong)proc_max_address;

            MEMORY_BASIC_INFORMATION64 mem_basic_info = new MEMORY_BASIC_INFORMATION64();

            ulong current = proc_min_address_l;

            while (current < proc_max_address_l)
            {
                var informationSize = VirtualQueryEx(processHandle, (IntPtr)current, out mem_basic_info, (uint)Marshal.SizeOf(mem_basic_info));
                if (informationSize == 0)
                {
                    throw new Win32Exception();
                }

                if (mem_basic_info.RegionSize < ChunkSize)
                {
                    yield return(mem_basic_info);
                }
                else
                {
                    Int64  remaining   = mem_basic_info.RegionSize;
                    UInt64 currentBase = unchecked ((UInt64)(Int64)mem_basic_info.BaseAddress);
                    while (remaining >= ChunkSize)
                    {
                        MEMORY_BASIC_INFORMATION64 chunk = mem_basic_info;
                        chunk.BaseAddress = (IntPtr)(long)currentBase;
                        chunk.RegionSize  = ChunkSize;
                        yield return(chunk);

                        remaining  -= ChunkSize;
                        currentBase = checked (currentBase + ChunkSize);
                    }

                    if (remaining > 0)
                    {
                        MEMORY_BASIC_INFORMATION64 chunk = mem_basic_info;
                        chunk.BaseAddress = (IntPtr)(long)currentBase;
                        chunk.RegionSize  = ChunkSize;
                        yield return(chunk);
                    }
                }

                // move to the next memory chunk
                current += (ulong)mem_basic_info.RegionSize;
            }
        }
Пример #5
0
        public static MEMORY_BASIC_INFORMATION64 GetMemInfo64(IntPtr ProcessHandle, IntPtr MinAddress)
        {
            var MemInfo     = new MEMORY_BASIC_INFORMATION64();
            int QueryResult = VirtualQueryEx(ProcessHandle, MinAddress, out MemInfo, (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION64)));

            if (QueryResult == 0)
            {
                Debug.WriteLine("Error on VirtualQueryEx, returned 0!");
            }
            return(MemInfo);
        }
Пример #6
0
        internal int QueryVirtual(ulong addr, out MEMORY_BASIC_INFORMATION64 mem)
        {
            if (_spaces2 == null)
            {
                mem = new MEMORY_BASIC_INFORMATION64();
                return(-1);
            }

            SetClientInstance();
            return(_spaces2.QueryVirtual(addr, out mem));
        }
Пример #7
0
        private static MEMORY_BASIC_INFORMATION64 MapMemInfo(MEMORY_BASIC_INFORMATION32 memInfo)
        {
            MEMORY_BASIC_INFORMATION64 result = new MEMORY_BASIC_INFORMATION64();

            result.AllocationBase    = (ulong)memInfo.AllocationBase;
            result.AllocationProtect = (uint)memInfo.AllocationProtect;
            result.BaseAddress       = (ulong)memInfo.BaseAddress;
            result.Protect           = (uint)memInfo.Protect;
            result.RegionSize        = (ulong)memInfo.RegionSize;
            result.State             = (uint)memInfo.State;
            result.Type = (uint)memInfo.Type;
            return(result);
        }
        /// <summary>
        /// Search the system's memory space for memory allocated to a target process and retrieve its sections via ReadProcessMemory
        /// </summary>
        /// <param name="hProcess"></param>
        /// <returns>A byte[] containing process's accessible memory</returns>
        static byte[] GetProcessMemoryBytes(IntPtr hProcess)
        {
            // Get lowest and highest addresses where memory can be allocated for user-mode applications
            SYSTEM_INFO systemInfo;

            GetSystemInfo(out systemInfo);

            IntPtr minimumAddress = systemInfo.minimumApplicationAddress;
            IntPtr maximumAddress = systemInfo.maximumApplicationAddress;

            MEMORY_BASIC_INFORMATION64 memBasicInfo = new MEMORY_BASIC_INFORMATION64();
            int bytesRead = 0;

            // Initialise MemoryStream to store all found chunks of memory
            MemoryStream processMemory = new MemoryStream();

            // Iterate over all addressable memory searching for memory blocks belonging to the target process
            while (minimumAddress.ToInt64() < maximumAddress.ToInt64())
            {
                // Check for memory belonging to target process
                VirtualQueryEx(hProcess, minimumAddress, out memBasicInfo, (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION64)));

                /* Check for sections of memory that are RWX or RW. Remove protection checks to dump all committed pages.
                 *  Shouldn't have access issues if running as admin and handle to process was obtained using ProcessAccessFlags.All.
                 *  Removing protection checks will significantly increase size of memory stream.
                 */
                if ((memBasicInfo.Protect == MemoryBasicInformationProtection.PAGE_READWRITE || memBasicInfo.Protect == MemoryBasicInformationProtection.PAGE_EXECUTE_READWRITE) &&
                    memBasicInfo.State == MemoryBasicInformationState.MEM_COMMIT)
                {
                    // Write chunk of memory to buffer
                    byte[] buffer = new byte[(int)memBasicInfo.RegionSize];
                    ReadProcessMemory(hProcess, (IntPtr)memBasicInfo.BaseAddress, buffer, (int)memBasicInfo.RegionSize, ref bytesRead);

                    // Append chunk of memory to MemoryStream
                    processMemory.Write(buffer, 0, buffer.Length);
                }

                // Move to the next section of memory
                try
                {
                    minimumAddress = new IntPtr(minimumAddress.ToInt64() + (Int64)memBasicInfo.RegionSize);
                }
                catch (OverflowException)
                {
                    break;
                }
            }

            return(processMemory.ToArray());
        }
Пример #9
0
        public int SetByteArrayAt(long offset, byte[] data)
        {
            MEMORY_BASIC_INFORMATION64 memBasicInfo = new MEMORY_BASIC_INFORMATION64();
            IntPtr bytesWritten = IntPtr.Zero;

            VirtualQueryEx(ProcessHandle, new IntPtr(offset), out memBasicInfo, new IntPtr(48));

            bool hasAnyRead = memBasicInfo.Protect.HasFlag(AllocationProtect.PAGE_READONLY) || memBasicInfo.Protect.HasFlag(AllocationProtect.PAGE_READWRITE) || memBasicInfo.Protect.HasFlag(AllocationProtect.PAGE_EXECUTE_READ) || memBasicInfo.Protect.HasFlag(AllocationProtect.PAGE_EXECUTE_READWRITE);

            if (hasAnyRead && memBasicInfo.State.HasFlag(MemoryFlags.MEM_COMMIT))
            {
                if (!WriteProcessMemory(ProcessHandle, offset, data, data.Length, out bytesWritten))
                {
                    int win32Error = Marshal.GetLastWin32Error();
                    throw new Win32Exception(win32Error, ((Win32Error)win32Error).ToString());
                }
            }

            return(bytesWritten.ToInt32());
        }
            public bool VirtualQuery(ulong addr, out VirtualQueryData vq)
            {
                _CheckClosed();
                using (new DbgEngContextSaver(m_umd, m_target.Context))
                {
                    vq = new VirtualQueryData();

                    try
                    {
                        MEMORY_BASIC_INFORMATION64 mem = m_umd.QueryVirtual(addr);
                        vq.BaseAddress = mem.BaseAddress;
                        vq.Size        = mem.RegionSize;
                        return(true);
                    }
                    catch (DbgProviderException dpe)
                    {
                        LogManager.Trace("DbgShellDebugClientDataReader.VirtualQuery: ignoring \"{0}\".",
                                         Util.GetExceptionMessages(dpe));
                        return(false);
                    }
                }
            } // end VirtualQuery()
        private string GetMemoryProtectFlags(IntPtr offset)
        {
            try
            {
                System.Text.StringBuilder sb = new System.Text.StringBuilder();
#if x64
                MEMORY_BASIC_INFORMATION64 memBasicInfo = new MEMORY_BASIC_INFORMATION64();
                VirtualQueryEx(ProcessHandle, offset, out memBasicInfo, memoryBasicInfoSize);

                sb.AppendLine("[MEMORY_BASIC_INFORMATION64]");
                sb.AppendFormat("BaseAddress: {0}\r\n", memBasicInfo.BaseAddress);
                sb.AppendFormat("AllocationBase: {0}\r\n", memBasicInfo.AllocationBase);
                sb.AppendFormat("AllocationProtect: {0}\r\n", memBasicInfo.AllocationProtect);
                sb.AppendFormat("__alignment1: {0}\r\n", memBasicInfo.__alignment1);
                sb.AppendFormat("RegionSize: {0}\r\n", memBasicInfo.RegionSize);
                sb.AppendFormat("State: {0}\r\n", memBasicInfo.State);
                sb.AppendFormat("Protect: {0}\r\n", memBasicInfo.Protect);
                sb.AppendFormat("Type: {0}\r\n", memBasicInfo.Type);
                sb.AppendFormat("__alignment2: {0}\r\n", memBasicInfo.__alignment2);
#else
                MEMORY_BASIC_INFORMATION32 memBasicInfo = new MEMORY_BASIC_INFORMATION32();
                VirtualQueryEx(ProcessHandle, offset, out memBasicInfo, memoryBasicInfoSize);

                sb.AppendLine("[MEMORY_BASIC_INFORMATION32]");
                sb.AppendFormat("BaseAddress: {0}\r\n", memBasicInfo.BaseAddress);
                sb.AppendFormat("AllocationBase: {0}\r\n", memBasicInfo.AllocationBase);
                sb.AppendFormat("AllocationProtect: {0}\r\n", memBasicInfo.AllocationProtect);
                sb.AppendFormat("RegionSize: {0}\r\n", memBasicInfo.RegionSize);
                sb.AppendFormat("State: {0}\r\n", memBasicInfo.State);
                sb.AppendFormat("Protect: {0}\r\n", memBasicInfo.Protect);
                sb.AppendFormat("Type: {0}\r\n", memBasicInfo.Type);
#endif
                return(sb.ToString());
            }
            catch (Exception ex)
            {
                return(string.Format("[GetMemoryProtectFlags EXCEPTION: {0}]", ex.ToString()));
            }
        }
Пример #12
0
        public Task <HashSet <long> > ScanMemoryAsync(byte[] searchValue, CancellationToken cancelToken)
        {
            return(Task.Factory.StartNew(() =>
            {
                HashSet <long> returnValue = new HashSet <long>();

                long procMinAddress = sysInfo.minimumApplicationAddress.ToInt64();
                long procMaxAddress = sysInfo.maximumApplicationAddress.ToInt64();

                MEMORY_BASIC_INFORMATION64 memBasicInfo = new MEMORY_BASIC_INFORMATION64();
                IntPtr bytesRead = IntPtr.Zero;

                byte[] buffer = null;
                while (procMinAddress < procMaxAddress)
                {
                    VirtualQueryEx(ProcessHandle, new IntPtr(procMinAddress), out memBasicInfo, new IntPtr(48));

                    bool hasAnyRead = memBasicInfo.Protect.HasFlag(AllocationProtect.PAGE_READONLY) || memBasicInfo.Protect.HasFlag(AllocationProtect.PAGE_READWRITE) || memBasicInfo.Protect.HasFlag(AllocationProtect.PAGE_EXECUTE_READ) || memBasicInfo.Protect.HasFlag(AllocationProtect.PAGE_EXECUTE_READWRITE);
                    if (hasAnyRead && memBasicInfo.State.HasFlag(MemoryFlags.MEM_COMMIT))
                    {
                        buffer = new byte[memBasicInfo.RegionSize.ToInt64()];
                        ReadProcessMemory(ProcessHandle, memBasicInfo.BaseAddress.ToInt64(), buffer, (int)memBasicInfo.RegionSize, out bytesRead);

                        foreach (int offset in FindIndexesOf(buffer, 0, searchValue))
                        {
                            returnValue.Add(memBasicInfo.BaseAddress.ToInt64() + (long)offset);
                        }

                        buffer = null;
                        GC.Collect();
                    }

                    procMinAddress += memBasicInfo.RegionSize.ToInt64();
                }

                return returnValue;
            }, cancelToken, taskOpts, taskSched));
        }
Пример #13
0
        public static UIntPtr VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress,
                                             out MEMORY_BASIC_INFORMATION lpBuffer, bool x64)
        {
            UIntPtr retVal;

            if (x64)
            {
                // 64 bit
                var tmp64 = new MEMORY_BASIC_INFORMATION64();
                retVal = Native_VirtualQueryEx(hProcess, lpAddress, out tmp64,
                                               new UIntPtr((uint)Marshal.SizeOf(tmp64)));

                lpBuffer.BaseAddress       = tmp64.BaseAddress;
                lpBuffer.AllocationBase    = tmp64.AllocationBase;
                lpBuffer.AllocationProtect = tmp64.AllocationProtect;
                lpBuffer.RegionSize        = (long)tmp64.RegionSize;
                lpBuffer.State             = tmp64.State;
                lpBuffer.Protect           = tmp64.Protect;
                lpBuffer.Type = tmp64.Type;

                return(retVal);
            }

            var tmp32 = new MEMORY_BASIC_INFORMATION32();

            retVal = Native_VirtualQueryEx(hProcess, lpAddress, out tmp32, new UIntPtr((uint)Marshal.SizeOf(tmp32)));

            lpBuffer.BaseAddress       = tmp32.BaseAddress;
            lpBuffer.AllocationBase    = tmp32.AllocationBase;
            lpBuffer.AllocationProtect = tmp32.AllocationProtect;
            lpBuffer.RegionSize        = tmp32.RegionSize;
            lpBuffer.State             = tmp32.State;
            lpBuffer.Protect           = tmp32.Protect;
            lpBuffer.Type = tmp32.Type;

            return(retVal);
        }
Пример #14
0
        public IEnumerable <byte[]> DumpMemory()
        {
            long procMinAddress = sysInfo.minimumApplicationAddress.ToInt64();
            long procMaxAddress = sysInfo.maximumApplicationAddress.ToInt64();

            MEMORY_BASIC_INFORMATION64 memBasicInfo = new MEMORY_BASIC_INFORMATION64();
            IntPtr bytesRead = IntPtr.Zero;

            while (procMinAddress < procMaxAddress)
            {
                VirtualQueryEx(ProcessHandle, new IntPtr(procMinAddress), out memBasicInfo, new IntPtr(48));

                bool hasAnyRead = memBasicInfo.Protect.HasFlag(AllocationProtect.PAGE_READONLY) || memBasicInfo.Protect.HasFlag(AllocationProtect.PAGE_READWRITE) || memBasicInfo.Protect.HasFlag(AllocationProtect.PAGE_EXECUTE_READ) || memBasicInfo.Protect.HasFlag(AllocationProtect.PAGE_EXECUTE_READWRITE);
                if (hasAnyRead && memBasicInfo.State.HasFlag(MemoryFlags.MEM_COMMIT))
                {
                    byte[] buffer = new byte[memBasicInfo.RegionSize.ToInt64()];
                    ReadProcessMemory(ProcessHandle, memBasicInfo.BaseAddress.ToInt64(), buffer, (int)memBasicInfo.RegionSize, out bytesRead);

                    yield return(buffer);
                }

                procMinAddress += memBasicInfo.RegionSize.ToInt64();
            }
        }
Пример #15
0
 public static extern Int32 VirtualQueryEx64(IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION64 lpBuffer, UInt32 dwLength);
Пример #16
0
 static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION64 lpBuffer, uint dwLength);
Пример #17
0
        // Function that checks the Access protection level of a memory location
        public static void MemInfo()
        {
            int    pid;
            string pidString;
            uint   pageSize = 0x1000;
            string memAddrStr;

            // Prompt fo user input of the pid of the process that contains the loaded module that the user wants protection info for
            Console.WriteLine("\nInput the Process Id for the module you want the protection information for:");

            // Get user input for the pid
            pidString = Console.ReadLine();

            // ensure the input is an integer
            try
            {
                pid = Convert.ToInt32(pidString);
            }

            // If not, go back to the menu and alert the usre
            catch (Exception ex)
            {
                Console.WriteLine("Input not an integer.  Please try again");
                menu();
                pid = 0;
            }

            // Ensure the pid is to a running process
            try
            {
                Process proc = Process.GetProcessById(pid);
            }
            // If not return to the menu an dinform the user
            catch (Exception ex)
            {
                Console.WriteLine("Not a valid process. \nError: {0}", ex);
                menu();
            }

            // Prompt user for memory address in hex of the module the user wants protection info for
            Console.WriteLine("\nInput the module base memory address in hex format (0x7ff...) to list protection Information:");

            // get user input address
            memAddrStr = Console.ReadLine();

            // ensure that the user entered a hex address
            try
            {
                Convert.ToInt64(memAddrStr, 16);
            }
            // If not alert the user and returnt o the menu
            catch (Exception ex)
            {
                Console.WriteLine("Invalid Memory address format.  Must be in hex, 0x... format.  Error: {0}", ex);
                menu();
            }

            // Create a new pointer from converting the user input string to a 64 bit integer
            IntPtr base_mem_address = new IntPtr(Convert.ToInt64(memAddrStr, 16));


            try
            {
                // Create a new basic memory information instancefrom the struct created belwo
                MEMORY_BASIC_INFORMATION64 mem_basic_info = new MEMORY_BASIC_INFORMATION64();

                // Winsows APOI function callopening the process with desired access level and saving the handle to the process
                IntPtr pHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_WM_READ, false, pid);

                // Windows API funciton call to query the process memory information and save the information in the basic information struct instance created above
                VirtualQueryEx(pHandle, base_mem_address, out mem_basic_info, pageSize);

                // Call the get Memory Constant String funciton and save it a s a string
                string memProtectConstStr = getMemProtectConstStr(mem_basic_info.Protect);

                // Write the Memory protection information string to the console
                Console.WriteLine("\nProtection Information: {0}", memProtectConstStr);
            }
            // Or else return to the menu and alert the user of the failure
            catch (Exception ex)
            {
                Console.WriteLine("\nFailed to Open memory location.  \nError: {0}", ex);
                menu();
            }

            // Return to the menu
            menu();
        }
 public void TestGetMemInfo()
 {
     MEMORY_BASIC_INFORMATION64 Info = SystemInfoHelper.GetMemInfo32(Process.GetProcessesByName("ditto").FirstOrDefault().Handle, SystemInfoHelper.GetSysInfo().MinimumApplicationAddress);
 }
Пример #19
0
 internal VirtualAllocRegion(MEMORY_BASIC_INFORMATION64 info, DbgEngDebugger debugger)
     : this(info, debugger, GetInfoDetails(info, debugger))
 {
 }
Пример #20
0
 public static extern uint VirtualQueryEx(IntPtr hProcess, IntPtr basePtr, out MEMORY_BASIC_INFORMATION64 lpBuffer, uint dwLength);
Пример #21
0
 public static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION64 lpBuffer, uint dwLength);
Пример #22
0
 private static extern Int64 VirtualQueryEx(HandleRef hProcess, Int64 lpAddress, out MEMORY_BASIC_INFORMATION64 lpBuffer, Int64 dwLength);
Пример #23
0
        public ulong RvaToOffset(ulong Rva)
        {
            var  sectionId = SectionStart;
            uint sections  = 0;
            MEMORY_BASIC_INFORMATION64 mbi = new MEMORY_BASIC_INFORMATION64();

            mbi = DebugApi.AddressType(BaseAddress);
            if (!DebugApi.IsIDNA && mbi.Protect == PAGE.NOACCESS)
            {
                DebugApi.WriteLine("Unable to read memory at %p", BaseAddress);
                return(0);
            }

            bool bIsImage = (DebugApi.IsIDNA || mbi.Type == MEM.IMAGE || mbi.Type == MEM.PRIVATE);

            if (FileImageType == ImageType.Pe32bit)
            {
                sections   = NTHeader32.FileHeader.NumberOfSections;
                sectionId += (ulong)Marshal.OffsetOf(typeof(IMAGE_NT_HEADERS32), "OptionalHeader") +
                             NTHeader32.FileHeader.SizeOfOptionalHeader;
            }
            if (FileImageType == ImageType.Pe64bit)
            {
                sections   = NTHeader.FileHeader.NumberOfSections;
                sectionId += (ulong)Marshal.OffsetOf(typeof(IMAGE_NT_HEADERS64), "OptionalHeader") +
                             NTHeader.FileHeader.SizeOfOptionalHeader;
            }
            for (int i = 0; i < sections; i++)
            {
                IMAGE_SECTION_HEADER section = new IMAGE_SECTION_HEADER();
                if (!DebugApi.ReadMemory <IMAGE_SECTION_HEADER>(sectionId, out section))
                {
                    Debug.WriteLine("[RVA] Unable to read IMAGE_SECTION_HEADER");
                    return(0);
                }

                if ((Rva >= section.VirtualAddress) &&
                    (Rva < (section.VirtualAddress + section.SizeOfRawData)))
                {
                    // RVA is in this section, we can now resolve it.

                    ulong start = 0;
                    if (bIsImage)
                    {
                        start = section.VirtualAddress;
                    }
                    else
                    {
                        start = section.PointerToRawData;
                    }

                    ulong address = BaseAddress + (ulong)Rva - (ulong)section.VirtualAddress + start; // (ulong)section.PointerToRawData;


                    return(address);
                }

                // Next section
                sectionId += (uint)Marshal.SizeOf(typeof(IMAGE_SECTION_HEADER));
            }

            // RVA could not be found
            return(0);
        }
Пример #24
0
 private VirtualAllocRegion(MEMORY_BASIC_INFORMATION64 info, DbgEngDebugger debugger, (ulong size, List <VirtualAllocSubRegion> subRegions) details)
Пример #25
0
        public bool SaveToStream(Stream ModuleStream)
        {
            MEMORY_BASIC_INFORMATION64 mbi = new MEMORY_BASIC_INFORMATION64();

            mbi = DebugApi.AddressType(BaseAddress);
            if (mbi.Protect == PAGE.NOACCESS && !DebugApi.IsIDNA)
            {
                DebugApi.WriteLine("Unable to read memory at %p", BaseAddress);
                return(false);
            }

            bool bIsImage = DebugApi.IsIDNA || (mbi.Type == MEM.IMAGE || mbi.Type == MEM.PRIVATE);

            IMAGE_DOS_HEADER dosHeader = DOSHeader;


            if (!dosHeader.isValid)
            {
                return(false);
            }

            // NT PE Headers
            ulong dwAddr = BaseAddress;
            ulong dwEnd  = 0;
            uint  nRead;

            IMAGE_SECTION_HEADER section = new IMAGE_SECTION_HEADER();
            ulong sectionAddr            = 0;
            int   nSection = 0;

            if (FileImageType == ImageType.Pe64bit)
            {
                sectionAddr = BaseAddress + (ulong)dosHeader.e_lfanew +
                              (ulong)Marshal.OffsetOf(typeof(IMAGE_NT_HEADERS64), "OptionalHeader") +
                              NTHeader.FileHeader.SizeOfOptionalHeader;
                nSection = NTHeader.FileHeader.NumberOfSections;
                dwEnd    = BaseAddress + NTHeader.OptionalHeader.SizeOfHeaders;
            }

            if (FileImageType == ImageType.Pe32bit)
            {
                sectionAddr = BaseAddress + (ulong)dosHeader.e_lfanew +
                              (ulong)Marshal.OffsetOf(typeof(IMAGE_NT_HEADERS32), "OptionalHeader") +
                              NTHeader32.FileHeader.SizeOfOptionalHeader;
                nSection = NTHeader32.FileHeader.NumberOfSections;
                dwEnd    = BaseAddress + NTHeader32.OptionalHeader.SizeOfHeaders;
            }


            MemLocation[] memLoc = new MemLocation[nSection];

            int indxSec = -1;
            int slot;

            for (int n = 0; n < nSection; n++)
            {
                if (!DebugApi.ReadMemory <IMAGE_SECTION_HEADER>(sectionAddr, out section))
                {
                    DebugApi.WriteLine("[IMAGE_SECTION_HEADER] Fail to read PE section info at %p\n", sectionAddr);
                    return(false);
                }


                for (slot = 0; slot <= indxSec; slot++)
                {
                    if ((ulong)section.PointerToRawData < (ulong)memLoc[slot].FileAddr)
                    {
                        break;
                    }
                }
                for (int k = indxSec; k >= slot; k--)
                {
                    memLoc[k + 1] = memLoc[k];
                }

                memLoc[slot].VAAddr   = (IntPtr)section.VirtualAddress;
                memLoc[slot].VASize   = (IntPtr)section.VirtualSize;
                memLoc[slot].FileAddr = (IntPtr)section.PointerToRawData;
                memLoc[slot].FileSize = (IntPtr)section.SizeOfRawData;

                indxSec++;
                sectionAddr += (ulong)Marshal.SizeOf(section);
            }

            uint pageSize;

            DebugApi.Control.GetPageSize(out pageSize);

            byte[] buffer = new byte[pageSize];



            IDebugDataSpaces3 data = (IDebugDataSpaces3)DebugApi.Client;

            while (dwAddr < dwEnd)
            {
                nRead = pageSize;
                if (dwEnd - dwAddr < nRead)
                {
                    nRead = (uint)(dwEnd - dwAddr);
                }

                if (data.ReadVirtual(dwAddr, buffer, nRead, out nRead) == (int)HRESULT.S_OK)
                {
                    ModuleStream.Write(buffer, 0, (int)nRead);
                }
                else
                {
                    DebugApi.WriteLine("Fail to read memory\n");
                    return(false);
                }

                dwAddr += nRead;
            }


            for (slot = 0; slot <= indxSec; slot++)
            {
                //if (!DebugApi.IsTaget64Bits)
                //{
                if (bIsImage)
                {
                    dwAddr = BaseAddress + (ulong)memLoc[slot].VAAddr;
                }
                else
                {
                    dwAddr = BaseAddress + (ulong)memLoc[slot].FileAddr;
                }
                //}
                //else
                //    dwAddr = BaseAddress + (ulong)memLoc[slot].FileAddr;
                dwEnd = (ulong)memLoc[slot].FileSize + dwAddr - 1;

                while (dwAddr <= dwEnd)
                {
                    nRead = pageSize;
                    if (dwEnd - dwAddr + 1 < pageSize)
                    {
                        nRead = (uint)(dwEnd - dwAddr + 1);
                    }

                    if (data.ReadVirtual(dwAddr, buffer, nRead, out nRead) == (int)HRESULT.S_OK)
                    {
                        ModuleStream.Write(buffer, 0, (int)nRead);
                    }
                    else
                    {
                        DebugApi.WriteLine("Fail to read memory\n");
                        return(false);
                    }

                    dwAddr += pageSize;
                }
            }


            return(true);
        }
        public static List <InjectedThread> InjectedThreads()
        {
            // Check if running as administrator first? Or at least check if SeDebugPrivilege enabled?
            if (IsUserAnAdmin() == false)
            {
                Console.WriteLine("Program is not running as Administrator. Exiting...");
                System.Environment.Exit(1);
            }

            List <InjectedThread> injectedThreads = new List <InjectedThread>();

            // Create array of Process objects for each running process
            Process[] runningProcesses = Process.GetProcesses();

            // Iterate over each process and get all threads by ID
            foreach (Process process in runningProcesses)
            {
                // PID 0 and PID 4 aren't valid targets for injection
                if (process.Id != 0 && process.Id != 4)
                {
                    IntPtr hProcess;

                    try
                    {
                        // Get handle to the process
                        hProcess = OpenProcess(ProcessAccessFlags.All, false, process.Id);
                    }
                    catch (System.ComponentModel.Win32Exception)
                    {
                        Console.WriteLine($"Couldn't get handle to process: {process.Id} - System.ComponentModel.Win32Exception - Access Is Denied");
                        continue;
                    }
                    catch (System.InvalidOperationException)
                    {
                        Console.WriteLine($"Couldn't get handle to process {process.Id} - System.InvalidOperationException - Process has Exited");
                        continue;
                    }

                    // Get all threads under running process
                    ProcessThreadCollection threadCollection = process.Threads;

                    // Iterate over each thread under the process
                    foreach (ProcessThread thread in threadCollection)
                    {
                        // Get handle to the thread
                        IntPtr hThread = OpenThread(ThreadAccess.AllAccess, false, thread.Id);

                        // Create buffer to store pointer to the thread's base address - NTQueryInformationThread writes to this buffer
                        IntPtr buf = Marshal.AllocHGlobal(IntPtr.Size);

                        // Retrieve thread's Win32StartAddress - Different to thread.StartAddress
                        Int32 result = NtQueryInformationThread(hThread, ThreadInfoClass.ThreadQuerySetWin32StartAddress, buf, IntPtr.Size, IntPtr.Zero);

                        if (result == 0)
                        {
                            // Need to Marshal Win32 type pointer from CLR type IntPtr to access the thread's base address via pointer
                            IntPtr threadBaseAddress = Marshal.ReadIntPtr(buf);

                            // Retrieve MEMORY_BASIC_INFORMATION struct for each thread - assumes 64bit processes, otherwise need to use MEMORY_BASIC_INFORMATION32
                            MEMORY_BASIC_INFORMATION64 memBasicInfo = new MEMORY_BASIC_INFORMATION64();
                            VirtualQueryEx(hProcess, threadBaseAddress, out memBasicInfo, (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION64)));

                            // Check the State and Type fields for the thread's MEMORY_BASIC_INFORMATION
                            // Resolve to false suggests code running from this thread does not have a corresponding image file on disk, likely code injection
                            if (memBasicInfo.State == MemoryBasicInformationState.MEM_COMMIT && memBasicInfo.Type != MemoryBasicInformationType.MEM_IMAGE)
                            {
                                // Create new InjectedThread object and set initial variables
                                InjectedThread injectedThread = new InjectedThread()
                                {
                                    ProcessName               = process.ProcessName,
                                    ProcessID                 = process.Id,
                                    ThreadId                  = thread.Id,
                                    BaseAddress               = threadBaseAddress,
                                    Path                      = process.MainModule.FileName,
                                    Size                      = (int)memBasicInfo.RegionSize,
                                    CommandLine               = GetProcessCommandLine(process),
                                    MemoryState               = Enum.GetName(typeof(MemoryBasicInformationState), memBasicInfo.State),
                                    MemoryType                = Enum.GetName(typeof(MemoryBasicInformationType), memBasicInfo.Type),
                                    MemoryProtection          = Enum.GetName(typeof(MemoryBasicInformationProtection), memBasicInfo.Protect),
                                    AllocatedMemoryProtection = Enum.GetName(typeof(MemoryBasicInformationProtection), memBasicInfo.AllocationProtect),
                                    BasePriority              = thread.BasePriority,
                                    ThreadStartTime           = thread.StartTime
                                };

                                // Get handle to thread token. If Impersonation is not being used, thread will use Process access token
                                // Try OpenThreadToken() - if it fails, use OpenProcessToken()
                                if (OpenThreadToken(hThread, TokenAccessFlags.TOKEN_QUERY, false, out IntPtr hToken) == false)
                                {
                                    // Thread doesn't have a unique token
                                    injectedThread.IsUniqueThreadToken = false;

                                    // Open process token instead
                                    if (OpenProcessToken(hProcess, TokenAccessFlags.TOKEN_QUERY, out hToken) == false)
                                    {
                                        Console.WriteLine($"Error opening thread and process token: {Marshal.GetLastWin32Error()}\nProcess ID {process.Id}");
                                    }
                                }
                                else
                                {
                                    injectedThread.IsUniqueThreadToken = true;
                                }

                                // Query process or thread token information
                                injectedThread.SecurityIdentifier = QueryToken(hToken, TOKEN_INFORMATION_CLASS.TokenUser);
                                injectedThread.Privileges         = QueryToken(hToken, TOKEN_INFORMATION_CLASS.TokenPrivileges);
                                injectedThread.Integrity          = QueryToken(hToken, TOKEN_INFORMATION_CLASS.TokenIntegrityLevel);
                                injectedThread.LogonId            = QueryToken(hToken, TOKEN_INFORMATION_CLASS.TokenOrigin);
                                injectedThread.Username           = GetProcessOwner(process.Id);

                                // Get logon session information and add it to the InjectedThread object
                                if (!string.IsNullOrEmpty(injectedThread.LogonId))
                                {
                                    GetLogonSessionData(hToken, injectedThread);
                                }

                                // Get thread's allocated memory via ReadProcessMemory
                                injectedThread.ThreadBytes = GetThreadMemoryBytes(hProcess, threadBaseAddress, injectedThread.Size);

                                // Read the full process memory ;
                                injectedThread.ProcessBytes = GetProcessMemoryBytes(hProcess);

                                // Read full name of executable image for the process
                                int           capacity      = 1024;
                                StringBuilder stringBuilder = new StringBuilder(capacity);
                                QueryFullProcessImageName(hProcess, 0, stringBuilder, ref capacity);
                                injectedThread.KernelPath = stringBuilder.ToString(0, capacity);

                                // Check whether the kernel image path matches Process.MainModule.Filename
                                if (injectedThread.Path.ToLower() != injectedThread.KernelPath.ToLower())
                                {
                                    injectedThread.PathMismatch = true;
                                }

                                injectedThreads.Add(injectedThread);
                                CloseHandle(hToken);
                            }

                            CloseHandle(hThread);
                        }
                    }

                    CloseHandle(hProcess);
                }
            }

            return(injectedThreads);
        }
Пример #27
0
 public static extern UIntPtr Native_VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress,
                                                    out MEMORY_BASIC_INFORMATION64 lpBuffer, UIntPtr dwLength);
Пример #28
0
        private void SystemSearch()
        {
            SYSTEM_INFO sys_info = new SYSTEM_INFO();

            UnsafeNativeMethods.GetSystemInfo(out sys_info);
            MEMORY_BASIC_INFORMATION64        mem_basic_info = new MEMORY_BASIC_INFORMATION64();
            List <MEMORY_BASIC_INFORMATION64> MemReg         = new List <MEMORY_BASIC_INFORMATION64>();
            long bip = ProcessModel.GetProcessBaseAddress(process);

            foreach (Signature sig in Signatures.Resolve(true))
            {
                if (sig.Heap)
                {
                    IntPtr hModuleSnapshot = new IntPtr();

                    hModuleSnapshot = UnsafeNativeHeap.CreateToolhelp32Snapshot(UnsafeNativeHeap.TH32CS_SNAPHEAPLIST | UnsafeNativeHeap.TH32CS_SNAPMODULE32, (uint)process.Id);

                    if ((int)hModuleSnapshot == UnsafeNativeHeap.INVALID_HANDLE_VALUE)
                    {
                        System.Windows.Forms.MessageBox.Show("Not Heap Access. " + Marshal.GetLastWin32Error().ToString());
                        return;
                    }
                    UnsafeNativeHeap.HEAPENTRY64 pe64     = new UnsafeNativeHeap.HEAPENTRY64();
                    UnsafeNativeHeap.HEAPLIST64  heaplist = new UnsafeNativeHeap.HEAPLIST64();
                    heaplist.dwSize = (uint)Marshal.SizeOf(heaplist);
                    UnsafeNativeHeap.PROCESS_HEAP_ENTRY64 phe64 = new UnsafeNativeHeap.PROCESS_HEAP_ENTRY64();

                    System.Threading.Thread.Sleep(10);
                    bool r = UnsafeNativeHeap.Heap32ListFirst(hModuleSnapshot, ref heaplist);
                    r = UnsafeNativeHeap.Heap32ListNext(hModuleSnapshot, ref heaplist);
                    bool r2;
                    while (r)
                    {
                        phe64.lpData = IntPtr.Zero;

                        int a = Marshal.SizeOf(phe64);          //28 (32)
                        a = Marshal.SizeOf(phe64.lpData);       //4
                        a = Marshal.SizeOf(phe64.cbData);       //4
                        a = Marshal.SizeOf(phe64.cbOverhead);   //2
                        a = Marshal.SizeOf(phe64.iRegionIndex); //2
                        a = Marshal.SizeOf(phe64.wFlags);       //2


                        r2 = UnsafeNativeHeap.HeapWalk((IntPtr)heaplist.th32HeapID, ref phe64);
                        System.Windows.Forms.MessageBox.Show("Not Heap Access. " + Marshal.GetLastWin32Error().ToString());
                        int cc = 0;

                        //System.Windows.Forms.MessageBox.Show("Not Heap Access. " + Marshal.GetLastWin32Error().ToString());
                        while (r2 && cc < 100)
                        {
                            if (pe64.dwBlockSize == 883)
                            {
                                int t = 1;
                            }
                            r2 = UnsafeNativeHeap.Heap32Next(ref pe64);
                            cc++;
                        }

                        r = UnsafeNativeHeap.Heap32ListNext(hModuleSnapshot, ref heaplist);
                    }


                    System.Windows.Forms.MessageBox.Show(Marshal.GetLastWin32Error().ToString());
                    UnsafeNativeHeap.CloseHandle(hModuleSnapshot);
                    continue;

                    //この方法もダメ
                    sig.BaseAddress    = (long)MemoryLib.ReadPointer((IntPtr)sig.PointerAddress);
                    Locations[sig.Key] = sig;
                    continue;

                    ulong proc_min_address = (ulong)sys_info.minimumApplicationAddress;
                    ulong proc_max_address = (ulong)sys_info.maximumApplicationAddress;
                    // saving the values as long ints so I won't have to do a lot of casts later
                    ulong proc_min_address_l = (ulong)proc_min_address;
                    ulong proc_max_address_l = (ulong)proc_max_address;
                    bool  exitFg             = true;
                    while (proc_min_address_l < proc_max_address_l && exitFg)
                    {
                        VirtualQueryEx(processHandle, (IntPtr)proc_min_address, out mem_basic_info, (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION64)));
                        // if this memory chunk is accessible
                        if (mem_basic_info.Protect == MemoryLib.PAGE_READWRITE && mem_basic_info.State == MemoryLib.MEM_COMMIT)
                        {
/*
 *
 *                              if (sig.Key == "PARTYCOUNT")
 *                              {
 *                                  //check Mmeory PalyerNmae
 *                                  ReadPlayerInfo();
 *                                  byte[] pattan = new byte[PlayerInfo.d.Name.Length];
 *                                  byte[] pattan0 = new byte[PlayerInfo.d.Name.Length+1];
 *
 *                                  pattan = System.Text.Encoding.ASCII.GetBytes(PlayerInfo.d.Name);
 *                                  pattan.CopyTo(pattan0,1);
 *                                  pattan0[0] = 1;
 *                                  // read everything in the buffer above
 *                                  int hp = (int)processHandle;
 *                                  int readSize = (int)mem_basic_info.RegionSize;// < 64*1024 ? (int)mem_basic_info.RegionSize : 64 * 1024;
 *                                  byte[] buffer = new byte[readSize];
 *                                  int bytesRead = 0;
 *                                  UnsafeNativeMethods.ReadProcessMemory(hp, (Int64)mem_basic_info.BaseAddress, buffer, readSize, ref bytesRead);
 *                                  int pickup = MemoryLib.FindSuperSig(buffer, pattan0);
 *                                  if (pickup == -1)
 *                                  {
 *                                      proc_min_address_l += mem_basic_info.RegionSize;
 *                                      proc_min_address = proc_min_address_l;
 *                                      continue;
 *                                  }else
 *                                  {
 *                                      sig.BaseAddress = (Int64)mem_basic_info.BaseAddress;
 *                                      sig.Offset = pickup - (0x10 * 24) - 1;
 *                                      Locations[sig.Key] = sig;
 *                                      exitFg = false;
 *                                  }
 *                              }
 */
                        }
                        proc_min_address_l += mem_basic_info.RegionSize;
                        proc_min_address    = proc_min_address_l;
                    }
                }
                else
                {
                    if (sig.Value == "")
                    {
                        sig.BaseAddress    = bip;
                        Locations[sig.Key] = sig;
                        continue;
                    }
                    else
                    {
                        Signature retrnSig = MemoryLib.FindExtendedSignatures(sig);                    //toDo Active Search...
                        sig.BaseAddress    = retrnSig.BaseAddress;
                        Locations[sig.Key] = sig;
                    }
                }
            }
        }