C# 获取没有WMI的进程的命令行

C# 获取没有WMI的进程的命令行,c#,C#,我找到了关于如何通过WinAPI读取指定进程的命令行的wj32。我试着在C#上翻译这个例子,我有几个问题。我可以获得一个指向RTL_USER_PROCESS_PARAMETERS结构的字段命令行的有效指针,但困难的是获取字符串本身。我应该使用不安全的代码吗?如何使用wj32的示例正确获取进程的命令行 using System; using System.Runtime.InteropServices; namespace CommandLine { internal static clas

我找到了关于如何通过WinAPI读取指定进程的命令行的wj32。我试着在C#上翻译这个例子,我有几个问题。我可以获得一个指向RTL_USER_PROCESS_PARAMETERS结构的字段命令行的有效指针,但困难的是获取字符串本身。我应该使用不安全的代码吗?如何使用wj32的示例正确获取进程的命令行

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

好的,我已经在几个进程上测试了这个版本。请注意,它只能在32位进程上工作,因为64位的内存布局不同。我没有时间写下我为什么做出这些改变,但希望你能处理好。如果我有时间,我会回来更新答案

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;
        }
    }
}
使用系统;
使用System.Runtime.InteropServices;
名称空间命令行
{
内部静态类NativeMethods
{
[DllImport(“kernel32.dll”,SetLastError=true)]
[返回:Marshallas(UnmanagedType.Bool)]
内部静态外部布尔闭合句柄(
IntPtr hObject
);
[DllImport(“kernel32.dll”,SetLastError=true)]
内部静态外部IntPtr OpenProcess(
UInt32 DWD期望访问,
[Marshallas(UnmanagedType.Bool)]
布尔二进制句柄,
Int32 dwProcessId
);
[DllImport(“kernel32.dll”,SetLastError=true)]
[返回:Marshallas(UnmanagedType.Bool)]
内部静态外部布尔ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
字节[]lpBuffer,
Int32 nSize,
out IntPtr lpNumberOfBytesRead
);
[DllImport(“ntdll.dll”)]
内部静态外部Int32 NtQueryInformationProcess(
IntPtr进程句柄,
UInt32进程信息类,
参考过程基本信息过程信息,
UInt32进程信息长度,
IntPtr返回长度
);
[StructLayout(LayoutKind.Sequential,Pack=1)]
内部结构流程基本信息
{
内部Int32出口流程;
内部IntPtr PebBaseAddress;
内部IntPtr仿射任务;
内部Int32基优先级;
内部IntPtr UniqueProcessId;
从UniqueProcessId继承的内部IntPtr;
内部UInt32尺寸
{
获取{return(UInt32)Marshal.SizeOf(typeof(进程基本信息));}
}
}
[StructLayout(LayoutKind.Sequential,Pack=1)]
内部结构UNICODE\u字符串
{
内部UInt16长度;
内部UInt16最大长度;
内部IntPtr缓冲区;
}
}
内部密封类程序
{
私有const UInt32进程查询信息=0x400;
私有const UInt32进程\虚拟机\读取=0x010;
[STAThread()]
静态void Main(字符串[]参数)
{
如果(args.Length!=1)返回;
int32pid;
如果(!Int32.TryParse(args[0],out-pid))返回;
IntPtr程序;
NativeMethods.PROCESS_BASIC_INFORMATION pbi=新的NativeMethods.PROCESS_BASIC_INFORMATION();
IntPtr读取;
如果((proc=NativeMethods.OpenProcess(
进程查询信息进程虚拟机读取错误pid
))==IntPtr.Zero)返回;
if(NativeMethods.NtQueryInformationProcess(proc,0,ref-pbi,pbi.Size,IntPtr.Zero)==0)
{
byte[]rupp=新字节[IntPtr.Size];
如果(NativeMethods.ReadProcessMemory(
进程(IntPtr)(pbi.PebBaseAddress.ToInt32()+0x10),rupp,IntPtr.Size,读出
))
{
Int32 ruppPtr=BitConverter.ToInt32(rupp,0);
byte[]cmdl=新字节[Marshal.SizeOf(typeof(NativeMethods.UNICODE_STRING));
如果(NativeMethods.ReadProcessMemory(
过程(IntPtr)(ruppPtr+0x40),cmdl,
Marshal.SizeOf(typeof(NativeMethods.UNICODE_STRING)),读出
))
{
NativeMethods.UNICODE_字符串ucsData;
ucsData=字节数组结构(cmdl);
byte[]parms=新字节[ucsData.Length];
如果(NativeMethods.ReadProcessMemory(
程序,ucsData.buffer,parms,
ucsData.长度,读出
))
{
var s=System.Text.Encoding.Unicode.GetString(parms);
WriteLine(“参数={0}”,s);
}
}
}
}
NativeMethods.CloseHandle(proc);
}
静态T ByteArrayToStructure(字节[]字节),其中T:struct
{
GCHandle=GCHandle.Alloc(字节,GCHandleType.pinted);
T stuff=(T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(),typeof(T));
handle.Free();
归还物品;
}
}
}

你能发布你已经开始的代码吗,这样我们就不必从头开始了?你想避免使用WMI有什么原因吗?为什么你要问你是否不帮我?嗨,凯特,谢谢你发布代码,我一整天都在出差,所以直到早上我才有机会看到你的选择。仅供参考,WMI有托管包装器。首先,我要感谢你没有对我的问题漠不关心。多谢各位!我想这个例子足以让我明白发生了什么,明白我做错了什么。再次感谢你!顺便说一下,我知道x86和x64之间的区别。