How to suspend a process?

Just starting out? Need help? Post your questions and find answers here.
User avatar
ostapas
Enthusiast
Enthusiast
Posts: 192
Joined: Thu Feb 18, 2010 11:10 pm

How to suspend a process?

Post by ostapas »

Good day,
need to suspend/resume a process. To my astonishment, could not find any PB examples, but found these 2 functions on AutoIt forums:

Code: Select all

Func ProcessSuspend($Process_PID)
	$ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1f0fff, 'int', False, 'int', $Process_PID)
	$i_sucess = DllCall("ntdll.dll", "int", "NtSuspendProcess", "int", $ai_Handle[0])
	DllCall('kernel32.dll', 'ptr', 'CloseHandle', 'ptr', $ai_Handle)
EndFunc   

Func ProcessResume($Process_PID)
	$ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1f0fff, 'int', False, 'int', $Process_PID)
	$i_sucess = DllCall("ntdll.dll", "int", "NtResumeProcess", "int", $ai_Handle[0])
	DllCall('kernel32.dll', 'ptr', 'CloseHandle', 'ptr', $ai_Handle)
EndFunc   
Maybe someone who has winapi knowledge and a spare minute could help to transform this to PB? :)
User avatar
JHPJHP
Addict
Addict
Posts: 2257
Joined: Sat Oct 09, 2010 3:47 am

Re: How to suspend a process?

Post by JHPJHP »

Try the following:
- can also be done with threads: http://stackoverflow.com/questions/1101 ... in-windows
- may not need [ AdjustCurrentProcessPrivilege ], but I included it just in case

Windows Services & Other Stuff\Other_Stuff\ProcessStuff\SuspendProcess.pb
Last edited by JHPJHP on Sat Mar 20, 2021 3:50 pm, edited 2 times in total.

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
User avatar
ostapas
Enthusiast
Enthusiast
Posts: 192
Joined: Thu Feb 18, 2010 11:10 pm

Re: How to suspend a process?

Post by ostapas »

Working fine, many thanks!
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: How to suspend a process?

Post by PB »

> may not need [ AdjustCurrentProcessPrivilege ]

I don't think it does. I run under a Limited account (not Admin) and your
code paused and resumed every process that I tested it with. Good job.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
User avatar
ostapas
Enthusiast
Enthusiast
Posts: 192
Joined: Thu Feb 18, 2010 11:10 pm

Re: How to suspend a process?

Post by ostapas »

JHPJHP, thanks again for arranging the code into procedures
smacker
User
User
Posts: 55
Joined: Thu Nov 06, 2014 7:18 pm

Re: How to suspend a process?

Post by smacker »

NtSuspendProcess is an undocumented function isn't it? Undocumented functions are not supported in the API, and may suddenly vanish or be changed in some way by later updates/service packs or versions of windows, so I'm a little shy about using such if I want my stuff to keep working in later versions of Windows or after updates/service packs in case something does happen to NtSuspendProcess.

This is something I used in Windows 7 64 bit (don't know about Win 7 32 bit version) for my purposes to pause (suspend) the thread of another process via its PID that did not belong to my own process which is the same thing as pausing/suspending the process, you could also do your own process as well, never tried it in Windows 8 so don't know about there but it worked in Windows 7 64 bit, the not so pretty version is this:

Code: Select all

Structure thread32 
size.l 
use.l 
idth.l 
parentid.l 
base.l 
delta.l 
flags.l 
EndStructure 

OpenLibrary(0,"kernel32.dll") 

Procedure pause(pid) 

thread.thread32 

snap = CallFunction(0, "CreateToolhelp32Snapshot",4,0) 
If snap 

thread\size=SizeOf(thread32) 
CallFunction(0,"Thread32First",snap,@thread) 

If thread\parentid=pid 
  h=CallFunction(0,"OpenThread",2,0,thread\idth) 
  SuspendThread_(h) 
  CloseHandle_(h) 
EndIf 

While CallFunction(0,"Thread32Next",snap,@thread) 

If thread\parentid=pid 
  h=CallFunction(0,"OpenThread",2,0,thread\idth) 
  SuspendThread_(h) 
  CloseHandle_(h) 
EndIf 

Wend 

EndIf 

EndProcedure

Procedure resume(pid) 

thread.thread32 

snap = CallFunction (0, "CreateToolhelp32Snapshot",4,0) 
If snap 

thread\size=SizeOf(thread32) 
CallFunction(0,"Thread32First",snap,@thread) 

If thread\parentid=pid 
  h=CallFunction(0,"OpenThread",2,0,thread\idth) 
  ResumeThread_(h) 
  CloseHandle_(h) 
EndIf 

While CallFunction(0,"Thread32Next",snap,@thread) 

If thread\parentid=pid 
  h=CallFunction(0,"OpenThread",2,0,thread\idth) 
  ResumeThread_(h) 
  CloseHandle_(h) 
EndIf 

Wend 

EndIf 
EndProcedure

Can't find the pretty version right now but I'm sure you could restructure the code some to pretty it up a little.
Last edited by smacker on Wed Nov 19, 2014 3:56 pm, edited 3 times in total.
The world and human nature was screwed up before I was born. It's not my fault and I'm just stuck with trying to deal with the mess left behind, so don't blame me.
User avatar
ostapas
Enthusiast
Enthusiast
Posts: 192
Joined: Thu Feb 18, 2010 11:10 pm

Re: How to suspend a process?

Post by ostapas »

Smacker, many thanks!
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: How to suspend a process?

Post by Thunder93 »

smacker raises some valid points.

Code: Select all

Prototype protoOpenThread(dwDesiredAccess.l, bInheritHandle.b, dwThreadId.l)
Global OpenThread.protoOpenThread


Procedure ResumeProcess(ProcessID.l)
  Define.l hSnap, cThr, IsRes
  ThrHandle.i
  
  LibKernel32 = OpenLibrary(#PB_Any,"Kernel32.dll")
  If Not LibKernel32 : ProcedureReturn 0 : EndIf 
  
  OpenThread = GetFunction(LibKernel32, "OpenThread")
  
  Thread.THREADENTRY32
  cThr = GetCurrentThreadId_()  
  
  hSnap = CreateToolhelp32Snapshot_(#TH32CS_SNAPTHREAD, 0)
  If hSnap <> #INVALID_HANDLE_VALUE
    Thread\dwSize = SizeOf(THREADENTRY32)
    If Thread32First_(hSnap, Thread)
      Repeat
        If (Thread\th32ThreadID <> cThr) And (Thread\th32OwnerProcessID = ProcessID)          
          ThrHandle = OpenThread(#THREAD_SUSPEND_RESUME, 0, Thread\th32ThreadID)
          
          If ThrHandle = 0 : Break : EndIf
          IsRes = ResumeThread_(ThrHandle)
          CloseHandle_(ThrHandle) 
        EndIf
        
      Until Not Thread32Next_(hSnap, Thread)      
      CloseHandle_(hSnap)
      CloseLibrary(LibKernel32)
      
      If IsRes > 0 : ProcedureReturn 1 : EndIf      
    EndIf
  EndIf
EndProcedure

Procedure SuspendProcess(PID.l)
  Define.l hSnap, IsSus
  ThrHandle.i  
  
  LibKernel32 = OpenLibrary(#PB_Any,"Kernel32.dll")
  If Not LibKernel32 : ProcedureReturn 0 : EndIf 
  
  OpenThread = GetFunction(LibKernel32, "OpenThread")  
  
  THR32.THREADENTRY32  
  
  hSnap = CreateToolhelp32Snapshot_(#TH32CS_SNAPTHREAD, 0)
  If hSnap <> #INVALID_HANDLE_VALUE
    THR32\dwSize = SizeOf(THR32)
    Thread32First_(hSnap, THR32)
    Repeat
      If THR32\th32OwnerProcessID = PID
        LibKernel32 = OpenLibrary(#PB_Any,"Kernel32.dll")
        
        ThrHandle = OpenThread(#THREAD_SUSPEND_RESUME, #False, THR32\th32ThreadID)      
        If ThrHandle <> #INVALID_HANDLE_VALUE
          IsSus = SuspendThread_(ThrHandle)
          CloseHandle_(ThrHandle)
        EndIf
      EndIf
    Until Thread32Next_(hSnap, THR32) = #False     
    CloseHandle_(hSnap)
    CloseLibrary(LibKernel32)
    
    If IsSus <> #INVALID_HANDLE_VALUE : ProcedureReturn 1 : EndIf
  EndIf
EndProcedure
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
BarryG
Addict
Addict
Posts: 4173
Joined: Thu Apr 18, 2019 8:17 am

Re: How to suspend a process?

Post by BarryG »

Apparently this pausing/resuming with the techniques above is bad/wrong because it doesn't pause all threads of a process, which is required. The answer is to use DebugActiveProcess_(pid) to pause and DebugActiveProcessStop_(pid) to resume, because this is how debuggers do it to ensure all threads of a PID are suspended. However, DebugActiveProcessStop_() doesn't exist in PureBasic. How can we add it? I tried this, but it doesn't work:

Code: Select all

Procedure DebugActiveProcessStop(pid)
  If OpenLibrary(0,"kernel32.dll")
    CallFunction(0,"DebugActiveProcessStop",0,0,pid)
    CloseLibrary(0)
  EndIf
EndProcedure

pid=11392 ; Change to an observable running process ID.
DebugActiveProcess_(pid)
Sleep_(1000)
DebugActiveProcessStop(pid)
breeze4me
Enthusiast
Enthusiast
Posts: 633
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: How to suspend a process?

Post by breeze4me »

BarryG wrote:Apparently this pausing/resuming with the techniques above is bad/wrong because it doesn't pause all threads of a process, which is required. The answer is to use DebugActiveProcess_(pid) to pause and DebugActiveProcessStop_(pid) to resume, because this is how debuggers do it to ensure all threads of a PID are suspended. However, DebugActiveProcessStop_() doesn't exist in PureBasic. How can we add it? I tried this, but it doesn't work:

Code: Select all

Procedure DebugActiveProcessStop(pid)
  If OpenLibrary(0,"kernel32.dll")
    CallFunction(0,"DebugActiveProcessStop",0,0,pid)
    CloseLibrary(0)
  EndIf
EndProcedure

pid=11392 ; Change to an observable running process ID.
DebugActiveProcess_(pid)
Sleep_(1000)
DebugActiveProcessStop(pid)
1. The parameters are wrong.
2. It does not seem to apply to 64-bit processes if it is compiled with PB x86. Compile it with PB x64 and check it out again.

Code: Select all

CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
  CompilerError "Use PB x64."
CompilerEndIf

Procedure DebugActiveProcessStop(pid)
  If OpenLibrary(0,"kernel32.dll")
    CallFunction(0,"DebugActiveProcessStop",pid)
    CloseLibrary(0)
  EndIf
EndProcedure


pid=11392 ; Change to an observable running process ID.
r = DebugActiveProcess_(pid)
If r
  Sleep_(1000)
  Debug DebugActiveProcessStop(pid)
EndIf
BarryG
Addict
Addict
Posts: 4173
Joined: Thu Apr 18, 2019 8:17 am

Re: How to suspend a process?

Post by BarryG »

Thanks, breeze4me. And you're right: compiling as 32-bit works great for 32-bit processes, but can't pause 64-bit.
Post Reply