2016-05-22 19 views
0

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); 
    } 
    } 
} 
+0

はあなたが開始したコードを投稿することができ、答えを更新するので、私たちはゼロからスタートする必要はありませんよね? WMIを避けたい理由はありますか? – OldBoyCoder

+0

あなたが私を助けないかどうか尋ねるのはなぜですか? – kate

+0

こんにちはケイト、コードを掲示してくれてありがとう、私は仕事のために一日中旅行していたので、朝まであなたの選択を見るチャンスはありません。 – OldBoyCoder

答えて

1

[OK]を、私はいくつかのプロセスでこのバージョンをテストしました。 64ビットではメモリレイアウトが異なるため、32ビットプロセスでのみ動作することに注意してください。なぜ私が変更を加えたのかを書き留める時間が足りませんが、うまくいけばこれで作業できます。私はいくつかの時間を取得する場合、私は戻ってくると

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, 
      byte[] 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, Pack=1)] 
     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, Pack=1)] 
     internal struct UNICODE_STRING 
     { 
      internal UInt16 Length; 
      internal UInt16 MaximumLength; 
      internal IntPtr 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 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) 
      { 
       byte[] rupp = new byte[IntPtr.Size]; 
       if (NativeMethods.ReadProcessMemory(
        proc, (IntPtr)(pbi.PebBaseAddress.ToInt32() + 0x10), rupp, IntPtr.Size, out read 
       )) 
       { 
        Int32 ruppPtr = BitConverter.ToInt32(rupp,0); 
        byte[] cmdl = new byte[Marshal.SizeOf(typeof(NativeMethods.UNICODE_STRING))]; 

        if (NativeMethods.ReadProcessMemory(
         proc, (IntPtr)(ruppPtr + 0x40), cmdl, 
         Marshal.SizeOf(typeof(NativeMethods.UNICODE_STRING)), out read 
        )) 
        { 
         NativeMethods.UNICODE_STRING ucsData; 
         ucsData = ByteArrayToStructure<NativeMethods.UNICODE_STRING>(cmdl); 
         byte[] parms =new byte[ucsData.Length]; 
         if (NativeMethods.ReadProcessMemory(
          proc, ucsData.buffer, parms, 
          ucsData.Length, out read 
          )) 
         { 
          var s = System.Text.Encoding.Unicode.GetString(parms); 
          Console.WriteLine("Parameters = {0}", s); 
         } 
        } 
       } 
      } 

      NativeMethods.CloseHandle(proc); 
     } 
     static T ByteArrayToStructure<T>(byte[] bytes) where T : struct 
     { 
      GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned); 
      T stuff = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T)); 
      handle.Free(); 
      return stuff; 
     } 
    } 
} 
+0

まず、私の問題に無関心でいないという理由で、あなたに感謝の意を表します。大いに感謝する!私はこの事例が、私に何が起こっているのかを理解させ、私が間違ったことを理解するのに十分であると思う。ありがとうございました!ところで、私はx86とx64の違いについて知っています。 – kate

関連する問題