WinAPI経由で指定されたプロセスのコマンドラインを読み取る方法について、wj32 postが見つかりました。私はその例をC#で翻訳しようとしていますが、いくつか質問があります。 RTL_USER_PROCESS_PARAMETERS構造体のCommandLineフィールドへの有効なポインタを取得できますが、difficaltyは文字列自体を取得しています。安全でないコードを使用する必要がありますか? wj32の例を使って、プロセスのCommandLineを正しく取得する方法は?WMIなしでプロセスのコマンドラインを取得する
using System;
using System.Runtime.InteropServices;
namespace CommandLine {
internal static class NativeMethods {
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern Boolean CloseHandle(
IntPtr hObject
);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern IntPtr OpenProcess(
UInt32 dwDesiredAccess,
[MarshalAs(UnmanagedType.Bool)]
Boolean bInheritHandle,
Int32 dwProcessId
);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern Boolean ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
out IntPtr lpBuffer,
Int32 nSize,
out IntPtr lpNumberOfBytesRead
);
[DllImport("ntdll.dll")]
internal static extern Int32 NtQueryInformationProcess(
IntPtr ProcessHandle,
UInt32 ProcessInformationClass,
ref PROCESS_BASIC_INFORMATION ProcessInformation,
UInt32 ProcessInformationLength,
IntPtr ReturnLength
);
[StructLayout(LayoutKind.Sequential)]
internal struct PROCESS_BASIC_INFORMATION {
internal Int32 ExitProcess;
internal IntPtr PebBaseAddress;
internal IntPtr AffinityMask;
internal Int32 BasePriority;
internal IntPtr UniqueProcessId;
internal IntPtr InheritedFromUniqueProcessId;
internal UInt32 Size {
get { return (UInt32)Marshal.SizeOf(typeof(PROCESS_BASIC_INFORMATION)); }
}
}
[StructLayout(LayoutKind.Sequential)]
internal struct UNICODE_STRING {
internal UInt16 Length;
internal UInt16 MaximumLength;
[MarshalAs(UnmanagedType.LPWStr)]
internal String Buffer;
}
}
internal sealed class Program {
private const UInt32 PROCESS_QUERY_INFORMATION = 0x400;
private const UInt32 PROCESS_VM_READ = 0x010;
[STAThread()]
static void Main(String[] args) {
if (args.Length != 1) return;
Int32 pid;
if (!Int32.TryParse(args[0], out pid)) return;
IntPtr proc;
NativeMethods.PROCESS_BASIC_INFORMATION pbi = new NativeMethods.PROCESS_BASIC_INFORMATION();
IntPtr rupp; //RTL_USER_PROCESS_PARAMETERS
IntPtr cmdl; //CommandLine field
IntPtr read;
if ((proc = NativeMethods.OpenProcess(
PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid
)) == IntPtr.Zero) return;
if (NativeMethods.NtQueryInformationProcess(proc, 0, ref pbi, pbi.Size, IntPtr.Zero) == 0) {
if (NativeMethods.ReadProcessMemory(
proc, (IntPtr)(pbi.PebBaseAddress.ToInt32() + 0x10), out rupp, IntPtr.Size, out read
)) {
if (NativeMethods.ReadProcessMemory(
proc, (IntPtr)(rupp.ToInt32() + 0x40), out cmdl,
Marshal.SizeOf(typeof(NativeMethods.UNICODE_STRING)), out read
)) {
// what I need to do to get command line?
}
}
}
NativeMethods.CloseHandle(proc);
}
}
}
はあなたが開始したコードを投稿することができ、答えを更新するので、私たちはゼロからスタートする必要はありませんよね? WMIを避けたい理由はありますか? – OldBoyCoder
あなたが私を助けないかどうか尋ねるのはなぜですか? – kate
こんにちはケイト、コードを掲示してくれてありがとう、私は仕事のために一日中旅行していたので、朝まであなたの選択を見るチャンスはありません。 – OldBoyCoder