Jump to content

Get CMDLine of a process


ProgAndy
 Share

Recommended Posts

I wanted to know, if you can get the CMD-Line of a process in AutoIt, too and so I tried to convert the Code from http://www.winterdom.com/dev/ptk/cmdline.html ( SOURCECODE ) Th result is this:

#include <Array.au3>
#include<Memory.au3>
#include<WinAPI.au3>
#include<Constants.au3>
#include<Security.au3>
#include<StructureConstants.au3>
;AU3 by Prog@ndy after http://www.winterdom.com/dev/ptk/cmdline.c
;~ ####################################################################
;~ ## File: ProcessCMDline.au3
;~ ## Project: CMDLINE
;~ ## Desc: see in next part
;~ ## Revision: Created 10.06.2008
;~ ##
;~ ## Copyright AU3-Code: 2008, Prog@ndy
;~ ##
;~ ####################################################################

;~ ////////////////////////////////////////////////////////////////////
;~ //
;~ // File:         cmdline.c
;~ // Project:  cmdline
;~ //
;~ // Desc:     this is a sample program that shows how to
;~ //               get the command line for almost any process
;~ //               on the system for WinNT 4 and up.
;~ //
;~ // Revisions:    Created 12/02/99
;~ //
;~ // Copyright(C) 1999, Tomas Restrepo. All rights reserved
;~ //
;~ ///////////////////////////////////////////////////////////////////
;~ #define UNICODE
;~ #define _UNICODE

;~ #include <windows.h>
;~ #include <stdio.h>
;~ #include <tchar.h>


;~ #pragma comment(lib, "advapi32.lib")

;~ // found by experimentation this is where the some
;~ // process data block is found in an NT machine.
;~ // On an Intel system, 0x00020000 is the 32
;~ // memory page. At offset 0x0498 is the process
;~ // current directory (or startup directory, not sure yet)
;~ // followed by the system's PATH. After that is the
;~ // process full command command line, followed by
;~ // the exe name and the window
;~ // station it's running on
;~ #define BLOCK_ADDRESS    (LPVOID)0x00020498
;~ // Additional comments:
;~ // From experimentation I've found
;~ // two notable exceptions where this doesn't seem to apply:
;~ // smss.exe : the page is reserved, but not commited
;~ //           which will get as an invalid memory address
;~ //           error
;~ // crss.exe : although we can read the memory, it's filled
;~ //             with 00 comepletely. No trace of command line
;~ //             information


Func ALIGN_DWORD($DWORD)
    If BitAND($DWORD, 0xFFFFFFFC) Then
        Return BitAND($DWORD, 0xFFFFFFFC) + sizeof("DWORD")
    Else
        Return $DWORD
    EndIf
EndFunc   ;==>ALIGN_DWORD

Global Const $READ_CONTROL = 0x20000
Global Const $STANDARD_RIGHTS_ALL = 0x1F0000
Global Const $STANDARD_RIGHTS_EXECUTE = ($READ_CONTROL)
Global Const $STANDARD_RIGHTS_READ = ($READ_CONTROL)
Global Const $STANDARD_RIGHTS_REQUIRED = 0xF0000
Global Const $STANDARD_RIGHTS_WRITE = ($READ_CONTROL)

Global Const $TOKEN_USER = 0x8
Global Const $TOKEN_STRING_SIZE = 4608
Global Const $TOKEN_SOURCE_LENGTH = 8
Global Const $TOKEN_READ = BitOR($STANDARD_RIGHTS_READ, $TOKEN_QUERY)
;~ Global Const $TOKEN_QUERY_SOURCE = 0x10
;~ Global Const $TOKEN_QUERY = 0x8
Global Const $TOKEN_PAREN = 0x4
Global Const $TOKEN_OR = 0x2
Global Const $TOKEN_OPERATOR = 0x2
Global Const $TOKEN_OPENPAREN = 0x4
Global Const $TOKEN_NOTIN = 0x20
;~ Global Const $TOKEN_IMPERSONATE = 0x4
Global Const $TOKEN_EXECUTE = $STANDARD_RIGHTS_EXECUTE
Global Const $TOKEN_CLOSEPAREN = 0x5
;~ Global Const $TOKEN_DUPLICATE = 0x2
;~ Global Const $TOKEN_ASSIGN_PRIMARY = 0x1
Global Const $TOKEN_AND = 0x3
;~ Global Const $TOKEN_ADJUST_SESSIONID = 0x100
;~ Global Const $TOKEN_ADJUST_PRIVILEGES = 0x20
;~ Global Const $TOKEN_ADJUST_GROUPS = 0x40
;~ Global Const $TOKEN_ADJUST_DEFAULT = 0x80
;~ Global Const $TOKEN_WRITE As Long = BitOR($STANDARD_RIGHTS_WRITE , $TOKEN_ADJUST_PRIVILEGES , $TOKEN_ADJUST_GROUPS , $TOKEN_ADJUST_DEFAULT)
Global Const $TOKEN_ALL_ACCESS_P = BitOR($STANDARD_RIGHTS_REQUIRED, $TOKEN_ASSIGN_PRIMARY, $TOKEN_DUPLICATE, $TOKEN_IMPERSONATE, $TOKEN_QUERY, $TOKEN_QUERY_SOURCE, $TOKEN_ADJUST_PRIVILEGES, $TOKEN_ADJUST_GROUPS, $TOKEN_ADJUST_DEFAULT)
Global Const $TOKEN_ALL_ACCESS = BitOR($STANDARD_RIGHTS_REQUIRED, $TOKEN_ASSIGN_PRIMARY, $TOKEN_DUPLICATE, $TOKEN_IMPERSONATE, $TOKEN_QUERY, $TOKEN_QUERY_SOURCE, $TOKEN_ADJUST_PRIVILEGES, $TOKEN_ADJUST_GROUPS, $TOKEN_ADJUST_SESSIONID, $TOKEN_ADJUST_DEFAULT)


$x = ProcessList()
$name = StringLeft(@ScriptName, StringInStr(@ScriptName, ".", 1, -1))
$len = StringLen($name)
For $i = 1 To $x[0][0]
    
Next
Func _GetProcessCmdLine($hProcess)
    Local $lpszCmdLine
    Local Const $BLOCK_ADDRESS = Ptr(0x00020498)

    Local $lpBuffer ;LPBYTE
    Local $lpPos ;LPBYTE                         // offset from the start of the buffer
    Local $dwBytesRead; DWORD
    Local $tag_MEMORY_BASIC_INFORMATION = "ptr BaseAddress;ptr AllocationBase; DWORD AllocationProtect; dword RegionSize; DWORD State; DWORD Protect; DWORD Type"
    
    Local $mbi = DllStructCreate($tag_MEMORY_BASIC_INFORMATION);MEMORY_BASIC_INFORMATION
    Local $tagSYSTEMINFO = "DWORD dwOemId;DWORD dwPageSize;ptr lpMinimumApplicationAddress;ptr lpMaximumApplicationAddress; ulong_PTR dwActiveProcessorMask;" & _
            "DWORD dwNumberOfProcessors; DWORD dwProcessorType; DWORD dwAllocationGranularity; ushort wProcessorLevel; ushort wProcessorRevision;"
    Local $sysinfo = DllStructCreate($tagSYSTEMINFO);SYSTEM_INFO
    Local $bError = False;BOOL

;~  __try {
;~      // Get the system page size by using GetSystemInfo()
    _WinAPI_GetSystemInfo($sysinfo)
;~      // allocate one on the heap to retrieve a full page
;~      // of memory
    $lpBuffer = _MemGlobalAlloc(DllStructGetData($sysinfo, "dwPageSize"))
;~      if ( lpBuffer == NULL )
;~          SIGNAL_ERROR ();

;~      // first of all, use VirtualQuery to get the start of the memory
;~      // block
    _WinAPI_VirtualQueryEx($hProcess, $BLOCK_ADDRESS, $mbi)
;~          SIGNAL_ERROR ();
;~
;~      // read memory begining at the start of the page
;~      // after that, we know that the env strings block
;~      // will be 0x498 bytes after the start of the page
    _WinAPI_ReadProcessMemory($hProcess, DllStructGetData($mbi, "BaseAddress"), $lpBuffer, DllStructGetData($sysinfo, "dwPageSize"), $dwBytesRead)
;~      if ( !ReadProcessMemory ( hProcess, mbi.BaseAddress, (LPVOID)lpBuffer,
;~                                sysinfo.dwPageSize, &dwBytesRead ) )
;~           SIGNAL_ERROR ();

;~      // now we've got the buffer on our side of the fence.
;~      // first, lpPos points to a string containing the current directory
;~      /// plus the path.
;~      lpPos = lpBuffer + ((DWORD)BLOCK_ADDRESS - (DWORD)mbi.BaseAddress);

    $pos = DllStructCreate("byte[" & DllStructGetData($sysinfo, "dwPageSize") & "]", $lpBuffer)
    $Data = DllStructGetData($pos, 1)

    $lpPos = (Number($BLOCK_ADDRESS) - Number(DllStructGetData($mbi, "BaseAddress")))
    $x = BinaryMid($Data, $lpPos)
    $z = BinaryLen(StringToBinary(BinaryToString($x, 3), 3))
    $x = BinaryMid($x, BinaryLen(StringToBinary($z, 3)))
;~  MsgBox(0, '', $x)
    $x = StringRegExpReplace($x, "0x.*?00000000.*?0000", "0x", 1)
;~ $x = StringReplace($x,"0000","0021")
    Do
        $x = StringReplace($x, "0x0000", "0x00", 1)
    Until @extended = 0
;~ MsgBox(0, '', $x)
    $z = BinaryToString(BinaryMid($x, 1), 3)
    $pos = ""
    _MemGlobalFree($lpBuffer)
    Return $z
;~ MsgBox(0, '', $Data & @CRLF & $x &  @CRLF & )
;~      lpPos = lpPos + (wcslen ( (LPWSTR)lpPos ) + 1) * sizeof(WCHAR); >
;~      // now goes full path an filename, aligned on a DWORD boundary
;~      // skip it
;~      lpPos = (LPBYTE)ALIGN_DWORD((DWORD)lpPos); >
;~      lpPos = lpPos + (wcslen ( (LPWSTR)lpPos ) + 1) * sizeof(WCHAR);
;~      // hack: Sometimes, there will be another '\0' at this position
;~      // if that's so, skip it
;~      if ( *lpPos == '\0' ) lpPos += sizeof(WCHAR);
;~      // now we have the actual command line
;~      // copy it to the buffer
;~      wcsncpy  ( lpszCmdLine, (LPWSTR)lpPos, MAX_PATH );
;~      // make sure the path is null-terminted
;~      lpszCmdLine[MAX_PATH-1] = L'\0';

;~  }
;~  __finally  {
;~      // clean up
;~      if ( lpBuffer != NULL ) free ( lpBuffer );
;~      return bError ? FALSE : TRUE;
;~  }
;~
EndFunc   ;==>_GetProcessCmdLine
Func _WinAPI_GetSystemInfo(ByRef $SysInfoStruct)
    Local $aResult

    $aResult = DllCall("Kernel32.dll", "int", "GetSystemInfo", "ptr", DllStructGetPtr($SysInfoStruct))
    Return $aResult[0]
EndFunc   ;==>_WinAPI_GetSystemInfo

;~ SIZE_T WINAPI VirtualQueryEx(
;~   __in      HANDLE hProcess,
;~   __in_opt  LPCVOID lpAddress,
;~   __out     PMEMORY_BASIC_INFORMATION lpBuffer,
;~   __in      SIZE_T dwLength
;~ );
Func _WinAPI_VirtualQueryEx(ByRef $hProcess, $BLOCK_ADDRESS, ByRef $buffer)
    Local $aResult

    $aResult = DllCall("Kernel32.dll", "dword", "VirtualQueryEx", "hwnd", $hProcess, "ptr", $BLOCK_ADDRESS, "ptr", DllStructGetPtr($buffer), "dword", DllStructGetSize($buffer))
    Return $aResult[0]
EndFunc   ;==>_WinAPI_VirtualQueryEx



;~ ////////////////////////////////////////////////////////////////////
;~ //
;~ // Function: EnableTokenPrivilege()
;~ //
;~ // Added: 20/02/99
;~ //
;~ // Description: Enables a specific token privilege
;~ //
;~ ///////////////////////////////////////////////////////////////////
Func EnableTokenPrivilege($privilege)

    Local $hToken;HANDLE                        // process token
    Local $tp = DllStructCreate("int Count;int64 LUID[1];int Attributes[1]")
    ;TOKEN_PRIVILEGES           // token provileges
    Local $dwSize;              DWORD

;~  // initialize privilege structure
;~  ZeroMemory (&tp, sizeof (tp));
    DllStructSetData($tp, "Count", 1)
    Local $hProcess = _WinAPI_GetCurrentProcess()
    $hToken = _Security__OpenProcessToken($hProcess, $TOKEN_ALL_ACCESS)
    If $hToken = 0 Then Return False
;~  // open the process token
;~  if ( !OpenProcessToken ( GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken ) )
;~      return FALSE;


    DllStructSetData($tp, "LUID", _Security__LookupPrivilegeValue("", $privilege))
    If DllStructGetData($tp, "LUID") = 0 Then
        _WinAPI_CloseHandle($hToken)
        Return False
    EndIf
    DllStructSetData($tp, "Attributes", 0x2)
;~  // look up the privilege LUID and enable it
;~  if ( !LookupPrivilegeValue ( NULL, privilege, &tp.Privileges[0].Luid ) )
;~  {
;~      CloseHandle ( hToken);
;~      return FALSE;
;~  }
;~
;~  tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

;~  // adjust token privileges
    _Security__AdjustTokenPrivileges($hToken, False, DllStructGetPtr($tp), 0, 0, $dwSize)
    If @error Then
        _WinAPI_CloseHandle($hToken)
        Return False
    EndIf
;~  if ( !AdjustTokenPrivileges ( hToken, FALSE, &tp, 0, NULL, &dwSize ) )
;~  {
;~      CloseHandle ( hToken);
;~      return FALSE;
;~  }

;~  // clean up
    _WinAPI_CloseHandle($hToken)
    Return True;
EndFunc   ;==>EnableTokenPrivilege


Func sizeof($x)
    Return DllStructGetSize(DllStructCreate($x))
EndFunc   ;==>sizeof

; Internal Funcs End

; Get Debug provilege
EnableTokenPrivilege("SeDebugPrivilege")

; The UDF to call :)
Func _GetCMDLine($pid)
    $pid = ProcessExists($pid)
    If $pid = 0 Then Return SetError(1, 0, "")
    Local $hProcess = _WinAPI_OpenProcess(BitOR($PROCESS_VM_OPERATION, $PROCESS_VM_READ, $PROCESS_QUERY_INFORMATION), False, $pid)
    Local $CMD = _GetProcessCmdLine($hProcess)
    If $CMD = "" Then
        Return SetError(2, 0, "")
        _WinAPI_CloseHandle($hProcess)
    EndIf
    Return $CMD
EndFunc   ;==>_GetCMDLineoÝ÷ Ù«­¢+Øìa5A1(¥¹±ÕÅÕ½ÐíAɽÍÍ
5±¥¹¹ÔÌÅÕ½Ðì)5Í ½à À°ÌäìÌäì°}Ñ
51¥¹ ÅÕ½Ðí¥É½à¹áÅÕ½Ð줤

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

Yes, but i wanted to try it without WMI :P

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

Hi, ProgAndy!

Your solution is good for Windows-2000 (& server).

Because WMI on W-2000 don't give the command-line of a process (this feature come in WMI with XP & +).

I know that, because I use cmdline.exe since several years.

@+

Michel Claveau

Edited by Michel Claveau
Link to comment
Share on other sites

already done by PaulIA and me, and implemented in UDF but good UDF then.

-- Arck System _ Soon -- Ideas make everything

"La critique est facile, l'art est difficile"

Projects :

[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list]
Link to comment
Share on other sites

  • 3 months later...

The example is not working for me!

I get only a window with an unknown character within! Of course Firefox is running!

I'm using Vista.

What's wrong?

UEZ

Getürkter *GERMAN* :mellow:

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

  • 2 months later...

Sorry, forgot this post. I think, in Vista, the Data is saved in an other format in mem, so this won't work anymore. Anyway, the the solution from Manko is much better

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

Thanks for feedback :)

I already saw that from Manko :lmao:

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...