none
P/Invoke to get INFOBLOCK structure and Command line

    Domanda

  • Hi, I've been working on this for several days straight and I can't seem to get it to work correctly... I honestly don't even know that it's getting the correct addresses and don't know how to check for validity:/ But this is what I have so far:

    public partial class Form1 : Form
        {
            IntPtr handle;
            int pebAddress;
            int procInfoAddress;
            string cmdLine;
    
            public Form1()
            {
                InitializeComponent();
    
                if (NativeFunctions.Privileges.EnableDebuggingPrivileges())
                {
                    MessageBox.Show("Successfully got SeDebugPrivilege.");
                    if ((handle = Open(NativeFunctions.Privileges.PROCESS_ALL_ACCESS, true, 3396)) == IntPtr.Zero)
                    {
                        MessageBox.Show("Failed to open process!");
                    }
    
                    else
                    {
                        MessageBox.Show("Successfully opened process.");
                        pebAddress = GetPEBAddress(handle);
                        if (pebAddress == 0 || pebAddress == -1)
                        {
                            MessageBox.Show("Failed to get PEB Address!");
                        }
    
                        else
                        {
                            MessageBox.Show("PEB Address: " + pebAddress.ToString());
                            procInfoAddress = GetProcInfoAddress(handle);
                            if (procInfoAddress == 0)
                            {
                                MessageBox.Show("Failed to get INFOBLOCK Address!");
                            }
    
                            else
                            {
                                MessageBox.Show("INFOBLOCK Address: " + procInfoAddress.ToString());
                                cmdLine = GetCommandLine(handle);
                                MessageBox.Show(cmdLine);
                            }
                        }
                    }
                    Close(handle);
                }
    
                else
                {
                    Application.Exit();
                }
            }
    
            public unsafe int GetPEBAddress(IntPtr handle)
            {
                int address;
                if (handle != null && handle != IntPtr.Zero)
                {
                    NativeFunctions.ProcessInformation.PROCESS_BASIC_INFORMATION pbi = new NativeFunctions.ProcessInformation.PROCESS_BASIC_INFORMATION();
                    uint size = (uint)sizeof(NativeFunctions.ProcessInformation.PROCESS_BASIC_INFORMATION);
                    int returnLength = 0;
                    if (NativeFunctions.ProcessInformation.NtQueryInformationProcess(handle, NativeFunctions.ProcessInformation.PROCESSINFOCLASS.ProcessBasicInformation, ref pbi, size, ref returnLength) == 0)
                    {
                        address = pbi.PebBaseAddress;
                    }
    
                    else
                    {
                        address = 0;
                    }
                }
    
                else
                {
                    address = -1;
                }
                return address;
            }
    
            public unsafe int GetProcInfoAddress(IntPtr handle)
            {
                IntPtr address;
                uint size = (uint)sizeof(IntPtr);
                uint returnLength = 0;
                int offset = (int)0x10;
                int x = pebAddress;
                int y = x + offset;
                MessageBox.Show("Size: " + y);
                if (!NativeFunctions.ProcessInformation.ReadProcessMemory(handle, (IntPtr)y, out address, size, out returnLength)) //(IntPtr)pebAddress + 0x10
                {
                    return 0;
                }
    
                else
                {
                    return address.ToInt32();
                }
            }
    
            public unsafe string GetCommandLine(IntPtr handle)
            {
                IntPtr str;
                uint size = (uint)sizeof(IntPtr);
                uint returnLength = 0;
                int offset = (int)0x40;
                MessageBox.Show(offset.ToString());
                int x = procInfoAddress;
                int y = x + offset;
                MessageBox.Show("Size: " + y);
                if (!NativeFunctions.ProcessInformation.ReadProcessMemory(handle, (IntPtr)y, out str, size, out returnLength))
                {
                    return "FAIL!";
                }
    
                else
                {
                    return Marshal.PtrToStringAuto(str);
                }
            }
    
            public IntPtr Open(int access, bool inherit, int pid)
            {
                return NativeFunctions.Kernel32.OpenProcess(access, inherit, pid);
            }
    
            public void Close(IntPtr handle)
            {
                NativeFunctions.Kernel32.CloseHandle(handle);
            }
        }

    Please help me!

    Aaron Chapman

    martedì 10 aprile 2012 17:32

Risposte

Tutte le risposte

  • Why don't you properly define the PEB structure here?

    Also, don't hardcode offset as the PEB structure has changed on x64 systems (Note that it doesn't really matter if your application run as 32 or 64-bit, so don't use that kind of detection. Instead, properly detect whether you're running on a 64-bit machine).


    EDIT: Added a link to others implementation of PEB structure from Koders there. However if you plan to use that on x64 machine, it won't work for aforementioned reason.

    mercoledì 11 aprile 2012 02:27
  • But I thought you were supposed to use the PROCESS_BASIC_INFORMATION block to find the PEB address? Then from that get the PEB block to find the command line?

    Aaron Chapman

    martedì 1 maggio 2012 16:24
  • If you just want the commandline, use GetCommandLine() API instead.

    As said in the documentation of NTQueryInformation(), it's a function that will potentially change in future versions of Windows. Unless you have plans to release seperate binaries to support that seperate version of Windows, you're advised to find a suitable replacement function instead of containue using this.

    EDIT: When you want command line from other process, you can use WMI instead.


    • Modificato cheong00 mercoledì 2 maggio 2012 06:13
    mercoledì 2 maggio 2012 03:04