ProgAndy Posted July 27, 2008 Posted July 27, 2008 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:expandcollapse popup#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
monoceres Posted July 27, 2008 Posted July 27, 2008 Good Job You are not the first to implement this in autoit though:http://www.autoitscript.com/forum/index.ph...c=70538&hl= Broken link? PM me and I'll send you the file!
ProgAndy Posted July 27, 2008 Author Posted July 27, 2008 Yes, but i wanted to try it without WMI *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
Michel Claveau Posted July 27, 2008 Posted July 27, 2008 (edited) 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 July 27, 2008 by Michel Claveau
arcker Posted July 28, 2008 Posted July 28, 2008 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]
UEZ Posted November 10, 2008 Posted November 10, 2008 (edited) 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* Edited November 10, 2008 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
ProgAndy Posted January 28, 2009 Author Posted January 28, 2009 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
UEZ Posted January 28, 2009 Posted January 28, 2009 (edited) Thanks for feedback I already saw that from Manko UEZ Edited January 28, 2009 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now