Example #1
0
        /// <summary>
        /// Loads libraries into the main executable and patches them as needed
        /// </summary>
        /// <param name="processInformation">The <see cref="ProcessInformation"/> corresponding to the main executable</param>
        /// <param name="patchDocument">The <see cref="XElement"/> containing the data to use</param>
        private static void PatchLibraries(ProcessInformation processInformation, XElement patchDocument)
        {
            foreach (var patchLibrary in patchDocument.Elements(PatchLibraryTag))
            {
                var libraryNameAttr = patchLibrary.Attribute(LibraryNameAttribute);
                if (libraryNameAttr == null)
                {
                    throw new InvalidOperationException("The library name attribute is not found");
                }

                var offsetAttr = patchLibrary.Attribute(OffsetAttribute);
                if (offsetAttr == null)
                {
                    throw new InvalidOperationException("The offset attribute is not found");
                }

                var dataAttr = patchLibrary.Attribute(DataAttribute);
                if (dataAttr == null)
                {
                    throw new InvalidOperationException("The data attribute is not found");
                }

                var offset = ParseAddress(offsetAttr.Value);
                var data = ParseData(dataAttr.Value);

                var libraryHandle = GetLibraryAddress(libraryNameAttr.Value, (int) processInformation.dwProcessId);

                MemoryProtection oldProtect;
                var result = Kernel32.VirtualProtectEx(
                    processInformation.hProcess,
                    libraryHandle + (int) offset,
                    (uint) data.Length,
                    MemoryProtection.ExcecuteReadWrite,
                    out oldProtect);
                ValidateResult(result);

                using (var alloc = new CoTaskMemoryAllocator(data.Length))
                {
                    alloc.Write(data);

                    uint mumberOfBytesWritten;
                    result = Kernel32.WriteProcessMemory(
                        processInformation.hProcess,
                        libraryHandle + (int) offset,
                        alloc.BufferAddress,
                        (uint) alloc.BufferLength,
                        out mumberOfBytesWritten);
                    ValidateResult(result);
                }

                result = Kernel32.VirtualProtectEx(
                    processInformation.hProcess,
                    libraryHandle + (int) offset,
                    (uint) data.Length,
                    oldProtect,
                    out oldProtect);
                ValidateResult(result);
            }
        }
Example #2
0
        /// <summary>
        /// Populates the list of loaded modules within the specified process
        /// </summary>
        /// <param name="hProcess">The handle of the process to populate the list of modules</param>
        private static void EnumModules(IntPtr hProcess)
        {
            using (var alloc = new CoTaskMemoryAllocator(0x10000))
            {
                int needed;
                var result = Kernel32.EnumProcessModulesExPsapi(
                    hProcess,
                    alloc,
                    alloc.BufferLength,
                    out needed,
                    ListModulesFlag.LIST_MODULES_ALL);
                ValidateResult(result);

                for (var i = 0; i < needed/IntPtr.Size; i++)
                {
                    var hModule = Marshal.ReadIntPtr(alloc.BufferAddress, i*IntPtr.Size);

                    var baseName = new StringBuilder(260);
                    result = Kernel32.GetModuleFileNameExWPsapi(hProcess, hModule, baseName, baseName.Capacity);
                    ValidateResult(result);

                    LoadedLibraries.Add(Path.GetFileName(baseName.ToString()).ToLower(), hModule);
                }
            }
        }
Example #3
0
        /// <summary>
        /// Patches the main executable
        /// </summary>
        /// <param name="processInformation">The <see cref="ProcessInformation"/> corresponding to the main executable</param>
        /// <param name="patchDocument">The <see cref="XElement"/> containing the data to use</param>
        private static void PatchExecutable(ProcessInformation processInformation, XElement patchDocument)
        {
            foreach (var patch in patchDocument.Elements(PatchTag))
            {
                var offsetAttr = patch.Attribute(OffsetAttribute);
                if (offsetAttr == null)
                {
                    throw new InvalidOperationException("The offset attribute is not found");
                }

                var dataAttr = patch.Attribute(DataAttribute);
                if (dataAttr == null)
                {
                    throw new InvalidOperationException("The data attribute is not found");
                }

                var offset = ParseAddress(offsetAttr.Value);
                var baseAddress = GetExecutableBaseAddress(processInformation);
                if (baseAddress == IntPtr.Zero)
                {
                    throw new InvalidOperationException("The base address of the main executable is not found");
                }
                var address = new IntPtr(baseAddress.ToInt64() + offset.ToInt64());

                var data = ParseData(dataAttr.Value);

                MemoryProtection oldProtect;
                var result = Kernel32.VirtualProtectEx(
                    processInformation.hProcess,
                    address,
                    (uint) data.Length,
                    MemoryProtection.ExcecuteReadWrite,
                    out oldProtect);
                ValidateResult(result);

                using (var alloc = new CoTaskMemoryAllocator(data.Length))
                {
                    alloc.Write(data);

                    uint mumberOfBytesWritten;
                    result = Kernel32.WriteProcessMemory(
                        processInformation.hProcess,
                        address,
                        alloc.BufferAddress,
                        (uint) alloc.BufferLength,
                        out mumberOfBytesWritten);
                    ValidateResult(result);
                }

                result = Kernel32.VirtualProtectEx(
                    processInformation.hProcess,
                    address,
                    (uint) data.Length,
                    oldProtect,
                    out oldProtect);
                ValidateResult(result);
            }
        }