Share via

Finding which command PowerShell is running using Windows API

Parth Gupta 180 Reputation points
2023-10-15T12:17:09.1033333+00:00

Hi,

I'm working on a final year project to detect malicious use of PowerShell and command prompt on Windows. I'm having trouble finding the appropriate Windows API to accomplish this.

I have successfully used the CreateToolhelp32Snapshot API to list all processes and then iterated over them to find the PID of PowerShell.exe. However, I am now trying to use the GetModuleFileNameEx API after OpenProcess API to determine which command PowerShell is running. For example, I want to know that the command it is running isdir or any other.

Can you please advise me on which API to use for this task?

Thanks

Windows development | Windows API - Win32
Windows for business | Windows Client for IT Pros | User experience | Other

1 answer

Sort by: Most helpful
  1. Castorix31 91,876 Reputation points
    2023-10-16T13:50:20.9933333+00:00

    To intercept a PowerShell command, like

    powershell -Command dir

    you can adapt the MSDN code from :

    https://learn.microsoft.com/en-us/windows/win32/wmisdk/example--receiving-event-notifications-through-wmi-

    In a Win32 app, I commented the code after Sleep(10000);, to let it running,

    I updated the query :

      _bstr_t("SELECT * "
          "FROM __InstanceCreationEvent WITHIN 1 "
          "WHERE TargetInstance ISA 'Win32_Process' and TargetInstance.Name='powershell.exe'"),
    

    and I updated :

    HRESULT EventSink::Indicate(long lObjectCount, IWbemClassObject** apObjArray)
    {
        HRESULT hr = S_OK;
        VARIANT vtTargetInstance;
        VARIANT vtTargetProp;
        for (int i = 0; i < lObjectCount; i++)
        {     
            hr = apObjArray[i]->Get(L"TargetInstance", 0, &vtTargetInstance, NULL, NULL);
            if (SUCCEEDED(hr))
            {
                IWbemClassObject* pTargetInstance = NULL;
                hr = vtTargetInstance.punkVal->QueryInterface(IID_IWbemClassObject, reinterpret_cast<void**>(&pTargetInstance));
                if (SUCCEEDED(hr))
                {              
                    hr = pTargetInstance->Get(L"CommandLine", 0, &vtTargetProp, NULL, NULL);
                    if (SUCCEEDED(hr))
                    {
                        WCHAR wsProp[512] = L"";
                        lstrcpy(wsProp, vtTargetProp.bstrVal);
    
                        // Command Line : "C:\WINDOWS\system32\WindowsPowerShell\v1.0\PowerShell.exe" -Command dir
                        WCHAR wsText[1024] = L"";
                        wsprintf(wsText, L"Command Line : %s\r\n", wsProp);
                        OutputDebugString(wsText);
                        VariantClear(&vtTargetProp);
                    }
                    pTargetInstance->Release();
                    pTargetInstance = NULL;
                }
                VariantClear(&vtTargetInstance);
            }      
        }
        return WBEM_S_NO_ERROR;
    }
    

    Was this answer helpful?

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.