gpt4 book ai didi

c# - 在没有 WMI 的情况下获取进程的命令行

转载 作者:太空宇宙 更新时间:2023-11-03 21:11:25 24 4
gpt4 key购买 nike

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

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

关于c# - 在没有 WMI 的情况下获取进程的命令行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37376595/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com