News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

IsProcessRunning

Started by dedndave, June 13, 2010, 06:20:46 PM

Previous topic - Next topic

dedndave

i have a need to find out if a process is running
i have a null-terminated string pointer (like 'SomeProc.exe',0)
i would like the function to return the PID if the process is running, or 0 if it isn't
it would be nice if it would work from Win 2000 through Win 7

currently, my game-plan is to use EnumProcesses, OpenProcess, then GetModuleFileName
i was wondering if anyone had experience with this kind of function
and, if so, if you used GetModuleFileName or one of the other functions to retrieve the process name

donkey

From my system.lib library, only works with NT based systems (ie NT4.0+). Note that it uses GetProcAddress for the API functions so it will not cause a program to fail if it is loaded (but not executed) on a Win9x system.

#Define SystemProcessInformation 5
#Define PAGE_READWRITE 4
#Define MEM_COMMIT 1000h
#Define MEM_RELEASE 8000h

VM_COUNTERS STRUCT
//  NtQueryInformationProcess using ProcessVmCounters
PeakVirtualSize DD
VirtualSize DD
PageFaultCount DD
PeakWorkingSetSize DD
WorkingSetSize DD
QuotaPeakPagedPoolUsage DD
QuotaPagedPoolUsage DD
QuotaPeakNonPagedPoolUsage DD
QuotaNonPagedPoolUsage DD
PagefileUsage DD
PeakPagefileUsage DD
ENDS

CLIENT_ID STRUCT
UniqueProcess DD
UniqueThread DD
ENDS

SYSTEM_THREAD STRUCT
KernelTime DQ
UserTime DQ
CreateTime DQ
WaitTime DD
StartAddress DD
ClientId CLIENT_ID <>
Priority DD
BasePriority DD
ContextSwitches DD
ThreadState DD // 2=running; 5=waiting
WaitReason DD
ENDS

ANSI_STRING STRUCT
Length dw
MaximumLength dw
Buffer DD
ENDS

UNICODE_STRING STRUCT
Length DW
MaximumLength DW
Buffer DD
ENDS

SYSTEM_PROCESS_INFORMATION STRUCT
dNext DD
dThreadCount DD
dReserved01 DD
dReserved02 DD
dReserved03 DD
dReserved04 DD
dReserved05 DD
dReserved06 DD
qCreateTime DQ
qUserTime DQ
qKernelTime DQ
usName UNICODE_STRING <>
BasePriority DD
dUniqueProcessId DD
dInheritedFromUniqueProcessId DD
dHandleCount DD
dReserved07 DD
dReserved08 DD
VmCounters VM_COUNTERS <>
dCommitCharge DD
Threads SYSTEM_THREAD <>
ENDS

DATA SECTION
szFPBNDLL DB A"NTDLL.DLL",0
szFPBNFUNC DB A"NtQuerySystemInformation",0

CODE SECTION

FindProcessByNameNT FRAME pszProcess,StartID
uses edi,esi,ebx
LOCAL pProcessSnap :D
LOCAL buffer[256] :W
LOCAL hlib :D
LOCAL pNtQInf :D

invoke LoadLibraryA,offset szFPBNDLL
mov [hlib],eax
or eax,eax
jnz >
sub eax,eax
dec eax
ret
:

invoke GetProcAddress,[hlib],offset szFPBNFUNC
mov [pNtQInf],eax
or eax,eax
jnz >
sub eax,eax
dec eax
ret
:

mov edi,[pszProcess]
sub eax,eax
mov ecx,256
repne scasb
not cl
or ecx,ecx
jnz >
sub eax,eax
dec eax
ret
:

mov al, "\"
std
repne scasb
cld
add edi,2
or ecx,ecx
jnz >
mov edi,[pszProcess]
:

invoke MultiByteToWideChar,0,0,edi,-1,offset buffer,256

invoke VirtualAlloc,0,020000h,MEM_COMMIT,PAGE_READWRITE
mov [pProcessSnap],eax
mov esi,eax
or eax,eax
jnz >
sub eax,eax
dec eax
ret
:

invoke [pNtQInf],5,esi,20000h,0

; Find our processID
mov esi,[pProcessSnap]
L0:
mov ebx,[esi+SYSTEM_PROCESS_INFORMATION.dUniqueProcessId]
cmp ebx,[StartID]
jle >L1
; Do a quick compare to weed out the impossible ones by
; checking the first 2 characters to see if they match
lea eax, buffer
mov eax,[eax]
mov ecx,[esi+SYSTEM_PROCESS_INFORMATION.usName.Buffer]
or ecx,ecx
jz >L1
mov ecx,[ecx]
cmp eax,ecx
jne >L1
invoke lstrcmpiW,[esi+SYSTEM_PROCESS_INFORMATION.usName.Buffer],offset buffer
jz >.FOUND
L1:
mov eax,[esi+SYSTEM_PROCESS_INFORMATION.dNext]
add esi,eax
or eax,eax
jnz <L0
dec eax
push eax
jmp >.DONE

.FOUND
push ebx

.DONE
invoke VirtualFree,[pProcessSnap],0,MEM_RELEASE
invoke FreeLibrary,[hlib]
pop eax
or eax,eax
RET
ENDF
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

dedndave

many thanks, Edgar   :U
i'll just use your lib   :P

qWord

Quote from: msdnNtQuerySystemInformation may be altered or unavailable in future versions of Windows. Applications should use the alternate functions...
I would use the method dedndave describe here, but use GetModuleBaseName instead of GetModuleFileName.
FPU in a trice: SmplMath
It's that simple!

Slugsnack

just in case. here is something from one of my old projects.

ProcessWatch proc uses esi lpszProcessName:DWORD
LOCAL ProcessStructure:PROCESSENTRY32
LOCAL PID:DWORD
LOCAL hSnapshot:DWORD

   NewSnapshot:

       print "."
   invoke Sleep, 100
   invoke CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, ebx
mov hSnapshot, eax

mov eax, sizeof ProcessStructure
mov ProcessStructure.dwSize, eax

   invoke Process32First, hSnapshot, addr ProcessStructure

   @@:

   invoke Sleep, 1
   invoke Process32Next, hSnapshot, addr ProcessStructure
   invoke GetLastError

   .IF eax == ERROR_NO_MORE_FILES
           invoke CloseHandle, hSnapshot
           invoke SetLastError, ERROR_SUCCESS
       jmp NewSnapshot
   .ELSE
           invoke lstrcmp, addr ProcessStructure.szExeFile, lpszProcessName
           .IF eax == 0
               mov eax, ProcessStructure.th32ProcessID
               mov PID, eax
                       print " ", 13, 10, 13, 10
                       print "Process ID of target process :", 9
                       print str$(PID), 13, 10
                   invoke OpenProcess, PROCESS_ALL_ACCESS, TRUE, PID
               mov esi, eax
                       print "Handle of target process :", 9
                       print str$(esi), 13, 10
                   invoke CloseHandle, hSnapshot
               mov eax, esi
               ret
           .ELSE
               jmp @b
           .ENDIF
   .ENDIF

ret
ProcessWatch endp


ew nasty code lol. old old code

donkey

Quote from: qWord on June 13, 2010, 07:21:34 PM
Quote from: msdnNtQuerySystemInformation may be altered or unavailable in future versions of Windows. Applications should use the alternate functions...
I would use the method dedndave describe here, but use GetModuleBaseName instead of GetModuleFileName.

Still working up to and including Windows 7. Microsoft and many many third parties import this function in their tools, I can't see them deciding to trash it after 15 years and breaking hundreds of applications...
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

qWord

Quote from: donkey on June 13, 2010, 07:27:13 PMI can't see them deciding to trash it after 15 years and breaking hundreds of applications...
They have place this warning in their documentation, so it is possible that they break with this hundreds of applications.
Also there is no need to use this function - the normal API can do the same.

FPU in a trice: SmplMath
It's that simple!

dedndave

GetModuleFileName may not be as pretty as GetModuleBaseName
but, it would allow support back to Win 2000 (or even older - not sure)

donkey

Quote from: qWord on June 13, 2010, 07:44:41 PM
Quote from: donkey on June 13, 2010, 07:27:13 PMI can't see them deciding to trash it after 15 years and breaking hundreds of applications...
They have place this warning in their documentation, so it is possible that they break with this hundreds of applications.
Also there is no need to use this function - the normal API can do the same.



Actually they have placed that warning in many APIs over the years and they are almost all still around, in some the warning has been removed in some the function has been wrapped but the original still exists. Almost every one of the native API functions have that warning and AFAIK in the history of Windows only 17 of the Ntxxx functions have ever been removed. There are many many jobs in Windows that other functions can perform, that does not make them the best for the purpose, in this case the best function available is NtQuerySystemInformation. In the end Dave asked for it to work through to Windows 7 and it does, that is all that counts.

However you can use the kernel mode native api from user mode so ZwQuerySystemInformation is a direct replacement if you like, if MS breaks that it risks breaking drivers, another thing they learned from Vista would not be a good idea.

Also if you actually read the entry at MSDN I have followed their guidelines for usage:

QuoteIf you do use NtQuerySystemInformation, access the function through run-time dynamic linking. This gives your code an opportunity to respond gracefully if the function has been changed or removed from the operating system. Signature changes, however, may not be detectable.

Finally it is cited in several MSDN examples as well as by the moderators at MSDN social as the best way to obtain process specific information:

http://social.msdn.microsoft.com/Forums/en-GB/winforms/thread/002f27ac-e36d-429e-9377-661a212462ec

And comments like this by Microsoft MVP's make me think it will never be deprecated:

QuoteNtQuerySystemInformation is the only function currently available to get this list. It would be nice if there was a way to get all of the handles that your process has open, but unfortunately there is no way of doing this. Currently this is the only method known to work.

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

qWord

I've never said, that it won't work.
However, it is strange that Microsoft's employs suggest to use it, while the documentation warn about it usage.
IMO compatibility of drivers can't be compare with compatibility of user land softwar. I'm not an expert on drivers, but for me they are OS-version specific (except for WDF stuff ?), so I would not see any problem when m$ decided to remove/change a Zw... functions. 
My thought was: develop and forget - IMO Zw/NtQuerySystemInformation doesn't offers this  :bg

qWord
FPU in a trice: SmplMath
It's that simple!

donkey

Quote from: qWord on June 13, 2010, 11:21:02 PM
I've never said, that it won't work.
However, it is strange that Microsoft's employs suggest to use it, while the documentation warn about it usage.
IMO compatibility of drivers can't be compare with compatibility of user land softwar. I'm not an expert on drivers, but for me they are OS-version specific (except for WDF stuff ?), so I would not see any problem when m$ decided to remove/change a Zw... functions. 
My though was: develop and forget - IMO Zw/NtQuerySystemInformation doesn't offers this  :bg

qWord


Hi qWord,

Microsoft rarely deprecates any functions and I have not known them to do it to a function that is used as widely as that one. In the history of Windows I think MS has deprecated around 420 core functions (almost all in the change from 9x to NT) most of them kernel mode, around 100 of them were user mode functions and very few of those ever had that warning. So take the "develop and forget" attitude at your own risk...

But mostly that message is just MS covering their arses when dealing with the settlement API since it stung them badly in the court case.

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

qWord

Quote from: donkey on June 13, 2010, 11:32:30 PM
But mostly that message is just MS covering their arses when dealing with the settlement API since it stung them badly in the court case.
They should add warnings for all functions ... just for being one the save side  :toothy
FPU in a trice: SmplMath
It's that simple!

hutch--

I tend to come down on the side of using only published API calls even though the NTDLL ones are well known. There is enough stuff that does not work on Win7, Winfile just for example and i have run into other bits and pieces but to be fair, I have yet to find a normal API that does not work in the same way as XP and Win2000 did.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

donkey

The one that surprised me in the latest round of cuts was the large number of ADVAPI calls dealing with security descriptors, no warnings like the one above just missing in the library for Windows 7. Also many applications that were written using the standard registry calls from Microsoft's examples failed under Vista, we saw enough posts about that here. If you decide you want to support an as of yet unwritten version of Windows you're just going to end up with a klunky ugly program that only does part of what it should and in no way can compare head to head against professionally written software. This was the main reasoning behind my header project supporting the undocumented ordinal calls, some of the functions exported as ordinals as far back as Win95 were "added" as named APIs after the settlement and finally documented, a good example are the DPA group of functions. Another ongoing part of the header project specifically deals with deprecated functions and will warn you if you attempt to use a core function that is not available to your targeted OS version.

My philosophy is that if it works up to the latest version of Windows and is later deprecated then I will rewrite it, after all I do not support Win9x and so it is not a good assumption to think that I will automatically support Windows 11.

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable