
permanent process remover (NT,W2k,XP)
I posted that code which says it doesn't work on '9x or NT4. Although the code below won't work on NT4 (you will need PSAPI for that), this will list processes on '9x.
(It appears that if you use the Process32First/Next calls inside a function they fail on '9x! You can use the code below in a Gosub/Return though.)
(It appears that if you use the Process32First/Next calls inside a function they fail on '9x! You can use the code below in a Gosub/Return though.)
Code: Select all
; -----------------------------------------------------------------------------
; List running processes (9x, ME, 2000 and XP -- not NT4)...
; -----------------------------------------------------------------------------
; james @ hi - toro . com
; -----------------------------------------------------------------------------
; Snapshot requirements...
#TH32CS_SNAPPROCESS = $2
; Library number...
#KERNEL32LIB = 999
; -----------------------------------------------------------------------------
; Structure required...
; -----------------------------------------------------------------------------
Structure PROCESSENTRY32
dwSize.l
cntUsage.l
th32ProcessID.l
th32DefaultHeapID.l
th32ModuleID.l
cntThreads.l
th32ParentProcessID.l
pcPriClassBase.l
dwFlags.l
szExeFile.b [#MAX_PATH]
EndStructure
; -----------------------------------------------------------------------------
; List all processes. Won't work on NT4 (should use PSAPI)...
; -----------------------------------------------------------------------------
; IMPORTANT: If you try to place this stuff into a function, it will fail on Windows
; 9x for no apparent reason! Using it in Gosub/Return is fine...
If OpenLibrary (#KERNEL32LIB, "kernel32.dll")
DefType.PROCESSENTRY32 Proc32
Proc32\dwSize = SizeOf (PROCESSENTRY32)
; Get snapshot of running processes...
snap = CallFunction (#KERNEL32LIB, "CreateToolhelp32Snapshot", #TH32CS_SNAPPROCESS, 0)
If snap
If CallFunction (#KERNEL32LIB, "Process32First", snap, @Proc32)
Debug PeekS (@Proc32\szExeFile)
While CallFunction (#KERNEL32LIB, "Process32Next", snap, @Proc32)
Debug PeekS (@Proc32\szExeFile)
Wend
EndIf
CloseHandle_ (snap)
EndIf
CloseLibrary (#KERNEL32LIB)
EndIf
I tried to enhance it a bit so it doesn't rely on pskill anymore to kill the processes. It works for me (I killed anything to a state only a reset workedRings wrote:Also is the Kill procedure is not able to kill everything (i mean everything, also services). You have to be in a special mode (security rights),So for the first time i use pskill from sysinternals, but i will investigate more time in that later.

There are 2 major changes to it:
1.
A procedure AssignDebugPrivileges, that enables the required privilege which is disabled by default for administrators.
Note that there is a difference between non-existent->disabled->enabled. Also by default, that privilege is non-existent for non-administrators and a non-existent privilege cannot be enabled.
Code: Select all
Procedure AssignDebugPrivilege()
#TOKEN_QUERY = $8
#TOKEN_ADJUST_PRIVILEGES = $20
#SE_DEBUG_NAME = "SeDebugPrivilege"
Priv.TOKEN_PRIVILEGES
PrivOld.TOKEN_PRIVILEGES
cbPriv = SizeOf(PrivOld)
hToken.l
Result = OpenThreadToken_(GetCurrentThread_(), #TOKEN_QUERY|#TOKEN_ADJUST_PRIVILEGES, #True, @hToken.l)
If Result=#False
If GetLastError_()<>#ERROR_NO_TOKEN
ProcedureReturn #False
EndIf
If OpenProcessToken_(GetCurrentProcess_(),#TOKEN_QUERY|#TOKEN_ADJUST_PRIVILEGES,@hToken)=#False
ProcedureReturn #False
EndIf
EndIf
Priv\PrivilegeCount = 1
Priv\Privileges[0]\Attributes = #SE_PRIVILEGE_ENABLED
LookupPrivilegeValue_(0, #SE_DEBUG_NAME, @Priv\Privileges[0]\Luid)
If AdjustTokenPrivileges_(hToken,#False,@Priv,SizeOf(Priv),@PrivOld,@cbPriv)=#False
dwError = GetLastError_()
CloseHandle_(hToken)
ProcedureReturn SetLastError_(dwError)
EndIf
If GetLastError_() = #ERROR_NOT_ALL_ASSIGNED
CloseHandle_(hToken)
ProcedureReturn SetLastError_(#ERROR_ACCESS_DENIED)
EndIf
ProcedureReturn #True
EndProcedure
The KillProcess Procedure was renamed to RKillProcedure, to not interfere with existing libraries.
Further, the reference to pskill.exe was removed and substituted by an OpenProcess / TerminateProcess combo.
Code: Select all
Procedure RKillProcess(pID)
pHandle = OpenProcess_(#PROCESS_ALL_ACCESS, #false, pID)
Result=TerminateProcess_(pHandle,0)
ProcedureReturn Result
EndProcedure

USE AT YOUR OWN RISK!
Code: Select all
; Author: Rings
; Date: 8. July 2004
; List processes on WinNT and kill un-wanted ones.
; to prevent pc from unwanted trojaners
; (i need that to kill winservicess.ex on customers pc's )
; Works with PSKILL.exe from syst-internals
; download PSKill.exe at http://www.sysinternals.com/files/pskill.zip
;
; modified 13. January 2005 by Max.
; KillProcess was renamed to RKillProcess and the reference to PSKILL.exe substituted with API calls
; AssignDebugPrivileges was added so OpenProcess also works on special programs (SYSTEM services e.g.)
; File deletion was commented for safety
; USE AT YOUR OWN RISK!
#PROCESS_QUERY_INFORMATION = $400
#READ_CONTROL = $20000
#STANDARD_RIGHTS_EXECUTE = #READ_CONTROL
#STANDARD_RIGHTS_READ = #READ_CONTROL
#STANDARD_RIGHTS_WRITE = #READ_CONTROL
#TOKEN_ADJUST_DEFAULT = $80
#TOKEN_ADJUST_PRIVILEGES = $20
#TOKEN_ADJUST_GROUPS = $40
#TOKEN_ADJUST_SESSIONID = $100
#TOKEN_ASSIGN_PRIMARY = $1
#TOKEN_DUPLICATE = $2
#TOKEN_QUERY = $8
#TOKEN_EXECUTE = #STANDARD_RIGHTS_EXECUTE
#TOKEN_IMPERSONATE = $4
#TOKEN_QUERY_SOURCE = $10
#TOKEN_READ = #STANDARD_RIGHTS_READ | #TOKEN_QUERY
#TOKEN_WRITE = #STANDARD_RIGHTS_WRITE | #TOKEN_ADJUST_PRIVILEGES
#TOKEN_ALL_ACCESS = #TOKEN_ADJUST_DEFAULT | #TOKEN_ADJUST_PRIVILEGES | #TOKEN_ADJUST_GROUPS | #TOKEN_ADJUST_SESSIONID | #TOKEN_DUPLICATE | #TOKEN_ASSIGN_PRIMARY | #TOKEN_QUERY | #TOKEN_EXECUTE
Enumeration
#Window_0
EndEnumeration
Enumeration
#Listview_0
#String_0
#CheckBox_0
#Text_0
#Text_1
#Listview_1
#Listview_2
EndEnumeration
Procedure Open_Window_0()
If OpenWindow(#Window_0, 290, 108, 665, 345, #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_TitleBar , "'NotNeeded' a permanent Process and File Killer by Siegfried Rings")
If CreateGadgetList(WindowID())
ListViewGadget(#Listview_0, 10, 30, 220, 60)
StringGadget(#String_0, 380, 30, 40, 20, "1000", #PB_String_Numeric)
CheckBoxGadget(#CheckBox_0, 260, 30, 120, 20, "Scan every msecs")
TextGadget(#Text_0, 10, 10, 230, 20, "Processes to Kill:")
TextGadget(#Text_1, 10, 90, 230, 20, "Processes that have been killed:")
ListViewGadget(#Listview_1, 10, 110, 450, 230)
SetGadgetState(#CheckBox_0,1)
ListViewGadget(#Listview_2, 460, 10, 200, 330)
EndIf
EndIf
EndProcedure
Structure PROCESS_MEMORY_COUNTERS
cb.l
PageFaultCount.l
PeakWorkingSetSize.l
WorkingSetSize.l
QuotaPeakPagedPoolUsage.l
QuotaPagedPoolUsage.l
QuotaPeakNonPagedPoolUsage.l
QuotaNonPagedPoolUsage.l
PageFileUsage.l
PeakPagefileUsage.l
EndStructure
#OWNER_SECURITY_INFORMATION = $00000001
#GROUP_SECURITY_INFORMATION = $00000002
#DACL_SECURITY_INFORMATION = $00000004
#SACL_SECURITY_INFORMATION = $00000008
#PROCESS_TERMINATE = $0001
#PROCESS_CREATE_THREAD = $0002
#PROCESS_SET_SESSIONID = $0004
#PROCESS_VM_OPERATION = $0008
#PROCESS_VM_READ = $0010
#PROCESS_VM_WRITE = $0020
#PROCESS_DUP_HANDLE = $0040
#PROCESS_CREATE_PROCESS = $0080
#PROCESS_SET_QUOTA = $0100
#PROCESS_SET_INFORMATION = $0200
#PROCESS_QUERY_INFORMATION = $0400
#PROCESS_ALL_ACCESS = #STANDARD_RIGHTS_REQUIRED | #SYNCHRONIZE | $FFF
#NbProcessesMax = 10000
Dim ProcessesArray(#NbProcessesMax)
AppPath.s=Space(1024)
GetCurrentDirectory_(1024,@AppPath.s)
Global IniFile.s
Parameter$ = ProgramParameter()
If Parameter$ <>""
IniFile=Parameter$
Else
IniFile=AppPath.s+"\Notneeded.ini"
EndIf
Debug IniFile
NewList NotNeeded.s()
Procedure GetnotNeeded()
ResetList(NotNeeded()) ; Reset the list index before the first element.
If ReadFile(1,IniFile)
While Eof(1)=0
Text$ = ReadString()
If Trim(text$)<>""
AddElement(NotNeeded())
NotNeeded()=Trim(LCase(text$))
AddGadgetItem(#Listview_0,-1,NotNeeded())
EndIf
Wend
CloseFile(1)
EndIf
EndProcedure
Procedure RKillProcess(pID)
;Max - procedure renamed and rewritten
pHandle = OpenProcess_(#PROCESS_ALL_ACCESS, #false, pID)
Result=TerminateProcess_(pHandle,0)
ProcedureReturn Result
EndProcedure
Procedure AssignDebugPrivilege()
;Max - procedure added
#TOKEN_QUERY = $8
#TOKEN_ADJUST_PRIVILEGES = $20
#SE_DEBUG_NAME = "SeDebugPrivilege"
Priv.TOKEN_PRIVILEGES
PrivOld.TOKEN_PRIVILEGES
cbPriv = SizeOf(PrivOld)
hToken.l
Result = OpenThreadToken_(GetCurrentThread_(), #TOKEN_QUERY|#TOKEN_ADJUST_PRIVILEGES, #True, @hToken.l)
If Result=#False
If GetLastError_()<>#ERROR_NO_TOKEN
ProcedureReturn #False
EndIf
If OpenProcessToken_(GetCurrentProcess_(),#TOKEN_QUERY|#TOKEN_ADJUST_PRIVILEGES,@hToken)=#False
ProcedureReturn #False
EndIf
EndIf
Priv\PrivilegeCount = 1
Priv\Privileges[0]\Attributes = #SE_PRIVILEGE_ENABLED
LookupPrivilegeValue_(0, #SE_DEBUG_NAME, @Priv\Privileges[0]\Luid)
If AdjustTokenPrivileges_(hToken,#False,@Priv,SizeOf(Priv),@PrivOld,@cbPriv)=#False
dwError = GetLastError_()
CloseHandle_(hToken)
ProcedureReturn SetLastError_(dwError)
EndIf
If GetLastError_() = #ERROR_NOT_ALL_ASSIGNED
CloseHandle_(hToken)
ProcedureReturn SetLastError_(#ERROR_ACCESS_DENIED)
EndIf
ProcedureReturn #True
EndProcedure
Procedure DoProcessListNt()
ClearGadgetItemList(#Listview_2)
If OpenLibrary(0, "psapi.dll")
EnumProcesses = IsFunction(0, "EnumProcesses")
EnumProcessModules = IsFunction(0, "EnumProcessModules")
GetModuleBaseName = IsFunction(0, "GetModuleBaseNameA")
GetModuleBaseNameFull = IsFunction(0, "GetModuleFileNameExA")
Debug GetModuleBaseNameFull
If EnumProcesses And EnumProcessModules And GetModuleBaseName ; Be sure we have detected all the functions
CallFunctionFast(EnumProcesses, ProcessesArray(), #NbProcessesMax, @nProcesses)
For k=1 To nProcesses/4
PID=ProcessesArray(k-1)
hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, 0, PID)
If hProcess
CallFunctionFast(EnumProcessModules, hProcess, @BaseModule, 4, @cbNeeded)
Name$ = Space(255)
CallFunctionFast(GetModuleBaseName, hProcess, BaseModule, @Name$, Len(Name$))
FullName$=Space(1024)
CallFunctionFast(GetModuleBaseNameFull,hProcess, BaseModule, @FullName$, Len(FullName$))
Debug Str(PID) + Name$
Name$=Trim(LCase(Name$))
CloseHandle_(hProcess)
AddGadgetItem(#Listview_2,0,Str(PID) +" "+Name$)
ResetList(NotNeeded())
While NextElement(NotNeeded())
If NotNeeded()=Name$
;Debug "Yes is in List !"
;Now kill Process
If CountGadgetItems(#Listview_1)>200
ClearGadgetItemList(#Listview_1)
EndIf
;Max. - calling the renamed KillProcess procedure, added a check if it really was killed and changed PID parameter to long
; from string
If RKillProcess(PID) ;Name$)
AddGadgetItem(#Listview_1,0,NotNeeded()+ " has been killed at "+ FormatDate("%hh:%ii:%ss %dd.%mm.%yy", Date()))
EndIf
;Max. - following 2 lines commented
; SetFileAttributes_(@Fullname$,#FILE_ATTRIBUTE_NORMAL );set attribute to normal
; Result=DeleteFile(Fullname$)
If Result
AddGadgetItem(#Listview_1,0,Fullname$ +" has been killed from disk")
EndIf
EndIf
Wend
EndIf
Next
EndIf
CloseLibrary(0)
EndIf
EndProcedure
Result = AssignDebugPrivilege()
Open_Window_0()
GetNotNeeded()
Repeat
Event = WindowEvent()
t=GetTickCount_()
Time=Val(GetGadgetText(#String_0))
If t>(t0+time)
If GetGadgetState(#Checkbox_0)=1
DoProcessListNt()
EndIf
t0=t
Else
Delay(1)
EndIf
Until Event = #PB_EventCloseWindow
End
;Max. - PSKILL.exe should not be needed anymore
;L1:
;IncludeBinary "PSKill.exe"
;L2:
- Psychophanta
- Always Here
- Posts: 5153
- Joined: Wed Jun 11, 2003 9:33 pm
- Location: Anare
- Contact:
While not Rings, I hope I can answer your question.Psychophanta wrote:Sorry Rings,
I must be idiot or something: How to kill a process using your tip?
All you need is a textfile notneeded.ini in the app's directory, containing the process names of unwanted stuff (virus, trojan horse, worm, real player

The file in Rings' archive looks like this:
---snip
winservicess.ex
winservicess.exe
Test.exe
---snip
For the tests with the above's code I used some others
---snip
qttask.exe
services.exe
winlogon.exe
---snip
Note that the latter two are system services, you cannot end usually. I used them to verify if the AssignDebugPrivilege procedure really gives me access to these processes.
End them at your own risk!
[/i]
- Psychophanta
- Always Here
- Posts: 5153
- Joined: Wed Jun 11, 2003 9:33 pm
- Location: Anare
- Contact:
- Psychophanta
- Always Here
- Posts: 5153
- Joined: Wed Jun 11, 2003 9:33 pm
- Location: Anare
- Contact:
AHA! I see.Max.² wrote: Did you try to run a program that you previously entered into the notneeded.ini?
That program should be more careful, for example ask before to shoot


XP ProMax.² wrote:What OS are you using?
I don't know.Max.² wrote:Is this a problem with my version or with Rings' original or both?
- Psychophanta
- Always Here
- Posts: 5153
- Joined: Wed Jun 11, 2003 9:33 pm
- Location: Anare
- Contact:
Re: permanent process remover (NT,W2k,XP)
@Rings: Thanks for your code, but I have a problem here with a part of it:
On my PC, where I do have admin rights, the above doesn't always give a
full pathname for a given PID. For example, here is what is returned when
I use it in a loop of all running processes:
Sometimes I get the full path returned, but other times, not. Svchost.exe
is located in the System32 folder, so shouldn't the above CallFunctionFast
get it each time for every svchost.exe process? It seems to only get a few.
And why not for csrss.exe? As a clue, I know it's this line causing the failure:
It's returning 0 for hProcess (but only sometimes) and I don't know why.
(PS. While we're here, is there a way to get the RAM usage of a process?).
Code: Select all
CallFunctionFast(GetModuleBaseNameFull,hProcess, BaseModule, @FullName$, Len(FullName$))
full pathname for a given PID. For example, here is what is returned when
I use it in a loop of all running processes:
Code: Select all
; Process,PID,FullPathToProcess
csrss.exe,740,
svchost.exe,1004,C:\WINDOWS\system32\svchost.exe
svchost.exe,1052,
svchost.exe,1092,C:\WINDOWS\System32\svchost.exe
svchost.exe,1196,
svchost.exe,1224,
svchost.exe,1312,C:\WINDOWS\System32\svchost.exe
svchost.exe,1832,C:\WINDOWS\System32\svchost.exe
is located in the System32 folder, so shouldn't the above CallFunctionFast
get it each time for every svchost.exe process? It seems to only get a few.
And why not for csrss.exe? As a clue, I know it's this line causing the failure:
Code: Select all
hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, 0, PID)
(PS. While we're here, is there a way to get the RAM usage of a process?).
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
"PureBasic won't be object oriented, period" - Fred.