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