// https://stackoverflow.com/questions/36431220/getting-a-list-of-dlls-currently-loaded-in-a-process-c-sharp
        private static ModuleInfo GetMonoModule(ProcessFacade process)
        {
            var modulePointers = Native.GetProcessModulePointers(process);

            // Collect modules from the process
            var modules = new List <ModuleInfo>();

            foreach (var modulePointer in modulePointers)
            {
                var moduleFilePath = new StringBuilder(1024);
                var errorCode      = Native.GetModuleFileNameEx(
                    process.Process.Handle,
                    modulePointer,
                    moduleFilePath,
                    (uint)moduleFilePath.Capacity);

                if (errorCode == 0)
                {
                    throw new COMException("Failed to get module file name.", Marshal.GetLastWin32Error());
                }

                var moduleName = Path.GetFileName(moduleFilePath.ToString());
                Native.GetModuleInformation(
                    process.Process.Handle,
                    modulePointer,
                    out var moduleInformation,
                    (uint)(IntPtr.Size * modulePointers.Length));

                // Convert to a normalized module and add it to our list
                var module = new ModuleInfo(moduleName, moduleInformation.BaseOfDll, moduleInformation.SizeInBytes);
                modules.Add(module);
            }

            return(modules.FirstOrDefault(module => module.ModuleName == "mono.dll"));
        }
        private static AssemblyImage GetAssemblyImage(ProcessFacade process, string name, int rootDomainFunctionAddress)
        {
            var domainAddress = process.ReadPtr((uint)rootDomainFunctionAddress + 1);
            //// pointer to struct of type _MonoDomain
            var domain = process.ReadPtr(domainAddress);

            //// pointer to array of structs of type _MonoAssembly
            var assemblyArrayAddress = process.ReadPtr(domain + MonoLibraryOffsets.ReferencedAssemblies);

            for (var assemblyAddress = assemblyArrayAddress;
                 assemblyAddress != Constants.NullPtr;
                 assemblyAddress = process.ReadPtr(assemblyAddress + 0x4))
            {
                var assembly            = process.ReadPtr(assemblyAddress);
                var assemblyNameAddress = process.ReadPtr(assembly + 0x8);
                var assemblyName        = process.ReadAsciiString(assemblyNameAddress);
                if (assemblyName == name)
                {
                    return(new AssemblyImage(process, process.ReadPtr(assembly + MonoLibraryOffsets.AssemblyImage)));
                    //return new AssemblyImage(process, process.ReadPtr(assembly + 0x44)); -> CollectionManager is null if we have this
                    //return new AssemblyImage(process, process.ReadPtr(assembly + 0x54)); -> CollectionManager is null if we have this
                    //return new AssemblyImage(process, process.ReadPtr(assembly + 0x6c)); -> CollectionManager is null if we have this
                    //return new AssemblyImage(process, process.ReadPtr(assembly + 0xac)); -> CollectionManager is null if we have this
                    //return new AssemblyImage(process, process.ReadPtr(assembly + 0xac));
                }
            }

            throw new InvalidOperationException($"Unable to find assembly '{name}'");
        }
        /// <summary>
        /// Creates an <see cref="IAssemblyImage"/> that provides access into a Unity application's managed memory.
        /// </summary>
        /// <param name="processId">
        /// The id of the Unity process to be inspected.
        /// </param>
        /// <param name="assemblyName">
        /// The name of the assembly to be inspected. The default setting of 'Assembly-CSharp' is probably what you want.
        /// </param>
        /// <returns>
        /// An <see cref="IAssemblyImage"/> that provides access into a Unity application's managed memory.
        /// </returns>
        public static IAssemblyImage Create(int processId, string assemblyName = "Assembly-CSharp")
        {
            if (Environment.OSVersion.Platform != PlatformID.Win32NT)
            {
                throw new InvalidOperationException(
                          "This library reads data directly from a process's memory, so is platform specific "
                          + "and only runs under Windows. It might be possible to get it running under macOS, but...");
            }

            var process    = new ProcessFacade(processId);
            var monoModule = AssemblyImageFactory.GetMonoModule(process);
            var moduleDump = process.ReadModule(monoModule);
            var rootDomainFunctionAddress = AssemblyImageFactory.GetRootDomainFunctionAddress(moduleDump, monoModule);

            return(AssemblyImageFactory.GetAssemblyImage(process, assemblyName, rootDomainFunctionAddress));
        }
Exemple #4
0
        public static IntPtr[] GetProcessModulePointers(ProcessFacade process)
        {
            var modulePointers = new IntPtr[2048 * Constants.SizeOfPtr];

            // Determine number of modules
            if (!Native.EnumProcessModulesEx(
                    process.Process.Handle,
                    modulePointers,
                    modulePointers.Length,
                    out var bytesNeeded,
                    0x03))
            {
                throw new COMException(
                          "Failed to read modules from the external process.",
                          Marshal.GetLastWin32Error());
            }

            var result = new IntPtr[bytesNeeded / IntPtr.Size];

            Buffer.BlockCopy(modulePointers, 0, result, 0, bytesNeeded);
            return(result);
        }
Exemple #5
0
 public MemoryReadingUtils(ProcessFacade process)
 {
     this.process = process;
 }
Exemple #6
0
        private dynamic InstanceProcessFacade(Mock <IProcessStore> mockProcessStore, Mock <IApprovalsLegacyStore> mockApprovalsLegacyStore, Mock <ISecurityStore> mockSecurityStore)
        {
            var facade = new ProcessFacade(_mockLogger.Object, mockProcessStore.Object, mockApprovalsLegacyStore.Object, mockSecurityStore.Object);

            return(facade);
        }