-1

I'm writing a program that what it does first, is to retrieve the first command line argument (which should be a process name), and find the corresponding PID of the process.

Here's how I do it:

in main

DWORD PID = FindProcessId(argv[1]);

and here's the function that finds PID:

DWORD FindProcessId(PWCHAR processname)
{
    NTSTATUS status;
    PVOID buffer;
    PSYSTEM_PROCESS_INFORMATION spi;
    DWORD pid = 0;

    buffer = VirtualAlloc(NULL, 1024 * 1024, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    spi = (PSYSTEM_PROCESS_INFORMATION)buffer;

    status = NtQuerySystemInformation(SystemProcessInformation, spi, 1024 * 1024, NULL);

    while (spi->NextEntryOffset) // Loop over the list until we reach the last entry, or found PID.
    {
        if (wcsncmp(spi->ImageName.Buffer, processname, spi->ImageName.Length) == 0)
        {
            pid = spi->UniqueProcessId;
            break;
        }
        spi = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)spi + spi->NextEntryOffset); // Calculate the address of the next entry.

    }

    return pid;
}

The thing is, it works perfectly if i simply write

DWORD PID = FindProcessId(L"notepad.exe");,

for example.

But when i use the command line argument and runthe program like so: find_pid.exe notepad.exe the FindProcessId returns 0, meaning it didn't find the process. Even though notepad.exe is running like before.

Any ideas why this doesn't work with the command line argument?


To make the program accept PWCHAR rather than char * (Wide strings rather than ascii ones), I had to use main instead of wmain

nortain32
  • 69
  • 1
  • 7
  • 2
    Use a debugger to see what data you are extracting from the command line args. Or even just print the vakue. You need to learn debugging. – David Heffernan May 13 '23 at 15:26
  • [Convert char * to LPWSTR](https://stackoverflow.com/questions/6858524/convert-char-to-lpwstr) – Retired Ninja May 13 '23 at 15:29
  • But i'm passing a PWCHAR to FindProcessId, wouldn't converting the input cmd line argument cause it to misbehave? – nortain32 May 13 '23 at 15:32
  • Are you using some Windows-specific alternative version of `main()` that gets wide strings as arguments? – Shawn May 13 '23 at 15:34
  • 1
    No `FindProcessId` expects a PWCHAR, but one is passing a `char *` if one's entry function is named `main`, it should named `wmain`. https://learn.microsoft.com/en-us/cpp/c-language/using-wmain?view=msvc-170 – Motomotes May 13 '23 at 15:35
  • 1
    `while (spi->NextEntryOffset)` is wrong logic. always last process is lost. need `do { } while (spi->NextEntryOffset)` – RbMm May 13 '23 at 19:49
  • Don't include the answer in the question, add an answer instead (and later mark it as a solution). – CristiFati May 14 '23 at 20:36
  • Why don't you just call EnumProcesses ? – AndersK May 14 '23 at 21:08

1 Answers1

1

To make the program accept PWCHAR rather than char * (Wide strings rather than ascii ones), I had to use wmain instead of main, like so:

int wmain(int argc, PWCHAR argv[])
{
    ....
    return 0;
}

OR

Just convert the char * to a wide string - PWCHAR, like so:

WCHAR victimProcessName[MAX_PATH];
mbstowcs(victimProcessName, argv[1], MAX_PATH); // Plus null
nortain32
  • 69
  • 1
  • 7