コード例 #1
0
ファイル: SteamLauncher.cs プロジェクト: WildGenie/UOMachine
        private static IntPtr GetBaseAddress(Win32.SafeProcessHandle hProcess, Win32.SafeThreadHandle hThread)
        {
            /* Entry point varies, so need to use GetThreadContext to find entrypoint */
            Win32.CONTEXT cntx = new Win32.CONTEXT();
            cntx.ContextFlags = (int)Win32.CONTEXT_FLAGS.CONTEXT_FULL;
            Win32.GetThreadContext(hThread.DangerousGetHandle(), ref cntx);

            /* Ebx+8 = pointer to entrypoint to be read with ReadProcessMemory. */
            byte[] tmp = new byte[4];
            Memory.Read(hProcess.DangerousGetHandle(), (IntPtr)(cntx.Ebx + 8), tmp, true);

            int baseAddress = tmp[3] << 24 | tmp[2] << 16 | tmp[1] << 8 | tmp[0];

            return((IntPtr)baseAddress);
        }
コード例 #2
0
        internal bool ReadProcessMemory(Win32.SafeProcessHandle processHandle, out string commandLine, out string imagePath)
        {
            if (processHandle is null)
            {
                throw new ArgumentNullException(nameof(processHandle));
            }

            commandLine = null;
            imagePath   = null;

            if (processHandle.IsInvalid)
            {
                return(false);
            }

            // Gloves off...
            unsafe
            {
                int  bytesRead = 0;
                long outResult = 0;

                var basicInfo = new Win32.ProcessBasicInformation {
                };

                // Ask the OS for information about the process, this will include the address of the PEB or
                // Process Environment Block, which contains useful information (like the offset of the process' parameters).
                var hresult = Win32.Ntdll.QueryInformationProcess(processHandle: processHandle,
                                                                  processInformationClass: Win32.ProcessInformationClass.BasicInformation,
                                                                  processInformation: &basicInfo,
                                                                  processInformationLength: sizeof(Win32.ProcessBasicInformation),
                                                                  returnLength: &outResult);

                if (hresult != Win32.Hresult.Ok)
                {
                    var error = Win32.Kernel32.GetLastError();

                    Trace.WriteLine($"failed to query process information [{error}].");

                    return(false);
                }

                var peb = new Win32.ProcessEnvironmentBlock {
                };

                // Now that we know the offsets of the process' parameters, read it because
                // we want the offset to the image-path and the command-line strings.
                if (!Win32.Kernel32.ReadProcessMemory(processHandle: processHandle,
                                                      baseAddress: basicInfo.ProcessEnvironmentBlock,
                                                      buffer: &peb,
                                                      bufferSize: sizeof(Win32.ProcessEnvironmentBlock),
                                                      bytesRead: out bytesRead) ||
                    bytesRead < sizeof(Win32.ProcessEnvironmentBlock))
                {
                    var error = Win32.Kernel32.GetLastError();

                    Trace.WriteLine($"failed to read process environment block [{error}] ({bytesRead:n0} bytes read).");

                    return(false);
                }

                var processParameters = new Win32.PebProcessParameters {
                };

                // Read the process parameters data structure to get the offsets to
                // the image-path and command-line strings.
                if (!Win32.Kernel32.ReadProcessMemory(processHandle: processHandle,
                                                      baseAddress: peb.ProcessParameters,
                                                      buffer: &processParameters,
                                                      bufferSize: sizeof(Win32.PebProcessParameters),
                                                      bytesRead: out bytesRead) ||
                    bytesRead < sizeof(Win32.PebProcessParameters))
                {
                    var error = Win32.Kernel32.GetLastError();

                    Trace.WriteLine($"failed to read process parameters [{error}] ({bytesRead:n0} bytes read).");

                    return(false);
                }

                byte *buffer = stackalloc byte[4096];

                // Read the image-path string, then use it to produce a new string object.
                // Don't give up if the read fails, move on to the next value - have hope.
                if (!Win32.Kernel32.ReadProcessMemory(processHandle: processHandle,
                                                      baseAddress: processParameters.ImagePathName.Buffer,
                                                      buffer: buffer,
                                                      bufferSize: processParameters.ImagePathName.MaximumSize,
                                                      bytesRead: out bytesRead) ||
                    bytesRead != processParameters.ImagePathName.MaximumSize)
                {
                    var error = Win32.Kernel32.GetLastError();

                    Trace.WriteLine($"failed to read process image path [{error}] ({bytesRead:n0} bytes read).");
                }
                else
                {
                    // Only allocate the string object if the read was successful.
                    imagePath = new string((char *)buffer);
                }

                // Read the command-line string, then use it to produce a new string object.
                if (!Win32.Kernel32.ReadProcessMemory(processHandle: processHandle,
                                                      baseAddress: processParameters.CommandLine.Buffer,
                                                      buffer: buffer,
                                                      bufferSize: processParameters.CommandLine.MaximumSize,
                                                      bytesRead: out bytesRead) ||
                    bytesRead != processParameters.CommandLine.MaximumSize)
                {
                    var error = Win32.Kernel32.GetLastError();

                    Trace.WriteLine($"failed to read process command line [{error}] ({bytesRead:n0} bytes read).");
                }
                else
                {
                    // Only allocate the string object if the read was successful.
                    commandLine = new string((char *)buffer);
                }
            }

            return(true);
        }