本帖最后由 漠北雪~狼 于 2015-1-20 22:27 编辑
暴力法查找隐藏进程及Processlist增强、结束进程树、ProcessExist增强、ProcessColse增强 函数
查找隐藏进程基本原理(咱这种菜鸟水平,也就顶多能这样了):
先ProcessList列表并存于数组,从0 - 65535(FFFF) 依次打开进程(OpenProcess)关闭,若此PID能被打开、能获取到该进程映像路径 且 不存在于之前ProcessList列表的数组中,则在进程名屁股后搞个“(Hide)”并添加至ProcessList列表的数组中。
原创,经测可行。希望有发现异常的朋友跟贴指出。。。
无意中回到此贴,发现Func __ProcessList函数效率极低,发现此处可以提高效率
For $I = 0 To $h_MaxID
改为
For $I = 0 To $h_MaxID Setp 4
ProcessList.au3Global $PROCESS_LIST_EX[1][2] = [[0, 0]]
#include <array.au3>
; #FUNCTION# ====================================================================================================================
; Name...........: _ProcessListTree
; Description ...: 进程树型结构列表
; Syntax.........: _ProcessListTree(允许枚举隐藏进程的最大PID值)
; Return values .: 成功返回 数组
; ===============================================================================================================================
Func _ProcessListTree($h_MaxID = 65535)
Local $s_Array[1][6], $x , $PList = __ProcessList($h_MaxID)
For $i = 1 To $PList[0][0]
If __AFind($s_Array, $PList[$i][1]) Then ContinueLoop
$x = UBound($s_Array)
ReDim $s_Array[$x + 1][4]
$s_Array[$x][0] = $PList[$i][0]
$s_Array[$x][1] = $PList[$i][1]
$s_Array[$x][2] = _WinAPI_GetCommandLine($s_Array[$x][1])
$s_Array[$x][3] = 0
_EnumChild($s_Array, $s_Array[$x][1], 1)
Next
$s_Array[0][0] = UBound($s_Array) - 1
Return $s_Array
EndFunc ;==>_ProcessList
; #FUNCTION# ====================================================================================================================
; Name...........: __ProcessList
; Description ...: ProcessList函数增加枚举隐藏进程功能
; Syntax.........: __ProcessList(允许枚举隐藏进程的最大PID值)
; Return values .: 成功返回 数组
; ===============================================================================================================================
Func __ProcessList($h_MaxID = 65535);65535
If TimerDiff($PROCESS_LIST_EX[0][1]) <= 1000 Then Return $PROCESS_LIST_EX;1秒内不重复枚举所有PID
Local $h_Process[1][1], $iElement, $h_pro, $d_PName, $d_IsHide
$PROCESS_LIST_EX = ProcessList()
For $I = 0 To $h_MaxID Setp 4
$h_pro = _OpenProcessEX($I)
If Not $h_pro Then ContinueLoop
$d_PName = __WinAPI_GetProcessFileName($I)
If @error Then ContinueLoop
ReDim $h_Process[UBound($h_Process) + 1][2]
$d_IsHide = StringInStr($d_PName, "", 0, -1)
If $d_IsHide <> 0 Then $d_PName = StringTrimLeft($d_PName, $d_IsHide) & "(Hide)"
$h_Process[UBound($h_Process) - 1][0] = $d_PName
$h_Process[UBound($h_Process) - 1][1] = $I
$I += 3
Next
For $I = 1 To UBound($h_Process) - 1
$iElement = -1
For $x = 0 To UBound($PROCESS_LIST_EX) - 1
If $h_Process[$I][1] = $PROCESS_LIST_EX[$x][1] Then
$iElement = $I
ExitLoop
EndIf
Next
If $iElement = -1 Then
$PROCESS_LIST_EX[0][0] += 1
ReDim $PROCESS_LIST_EX[$PROCESS_LIST_EX[0][0] + 1][2]
$PROCESS_LIST_EX[$PROCESS_LIST_EX[0][0]][0] = $h_Process[$I][0]
$PROCESS_LIST_EX[$PROCESS_LIST_EX[0][0]][1] = $h_Process[$I][1]
EndIf
Next
_ArraySort($PROCESS_LIST_EX, 0, 0, 0, 1)
$PROCESS_LIST_EX[0][1] = TimerInit()
Return $PROCESS_LIST_EX
EndFunc ;==>__ProcessList
; #FUNCTION# ====================================================================================================================
; Name...........: _ProcessExist
; Description ...: ProcessExist函数增加判断隐藏进程功能
; Syntax.........: _ProcessExist(进程PID或进程名[, 允许枚举隐藏进程的最大PID值])
; Return values .: 成功返回 进程PID
; ===============================================================================================================================
Func _ProcessExist($s_nProcessID, $h_MaxID = 65535)
Local $h_Process = __ProcessList($h_MaxID)
For $I = 1 To $h_Process[0][0]
If $h_Process[$i][1] = 0 Then ContinueLoop
If BitOR($s_nProcessID = $h_Process[$I][1], $s_nProcessID = $h_Process[$I][0], $s_nProcessID & "(Hide)" = $h_Process[$I][0]) Then Return $h_Process[$I][1]
Next
Return 0
EndFunc ;==>_ProcessExist
; #FUNCTION# ====================================================================================================================
; Name...........: _ProcessKillTree
; Description ...: 结束进程树
; Syntax.........: _ProcessKillTree(进程PID或进程名)
; Return values .: 成功返回 进程PID
; ===============================================================================================================================
Func _ProcessKillTree($s_nProcessID)
If Not IsNumber($s_nProcessID) Then $s_nProcessID = _ProcessExist($s_nProcessID)
_ProcessClose($s_nProcessID)
Local $Temp = __WinAPI_EnumChildProcess($s_nProcessID)
If BitOR(@error, $Temp[0][0] = "") Then Return SetError(1)
_ArrayDisplay($Temp)
For $i = 0 To UBound($Temp) - 1
_ProcessClose($Temp[$i][0])
Next
EndFunc
; #FUNCTION# ====================================================================================================================
; Name...........: _ProcessClose
; Description ...: 结束进程
; Syntax.........: _ProcessClose(进程PID或进程名)
; Return values .: 成功返回 进程PID
; ===============================================================================================================================
Func _ProcessClose($s_nProcessID)
If Not IsNumber($s_nProcessID) Then $s_nProcessID = _ProcessExist($s_nProcessID)
If Not $s_nProcessID Then Return SetError(1, 0, 0)
Local $hProcess = DllCall("kernel32.dll", "hwnd", "OpenProcess", "dword", BitOR(0x0400, 0x0004, 0x0001), "int", 0, "dword", $s_nProcessID)
If BitOR(@error, $hProcess[0] = 0) Then Return SetError(2, 0, 0)
Local $pStruct = DllStructCreate("dword")
Local $ProcTerminate = DllCall("kernel32.dll", "int", "TerminateProcess", "hwnd", $hProcess[0], "uint", DllStructGetData($pStruct, 1))
If @error Then Return SetError(3, 0, 0)
Return 1
EndFunc ;==>_ProcessClose
;~ 循环枚举子进程
Func _EnumChild(ByRef $s_Array, $s_nProcessID, $s_iStep)
Local $Temp = __WinAPI_EnumChildProcess($s_nProcessID)
If BitOR(@error, Not UBound($Temp)) Then Return SetError(1)
If $Temp[0][0] = "" Then Return SetError(1)
For $i = 0 To UBound($Temp) - 1
If __AFind($s_Array, $Temp[$i][0]) Then ContinueLoop
ReDim $s_Array[UBound($s_Array) + 1][4]
$s_Array[UBound($s_Array) - 1][0] = $Temp[$i][1]
$s_Array[UBound($s_Array) - 1][1] = $Temp[$i][0]
$s_Array[UBound($s_Array) - 1][2] = _WinAPI_GetCommandLine($s_Array[UBound($s_Array) - 1][1])
$s_Array[UBound($s_Array) - 1][3] = $s_iStep
_EnumChild($s_Array, $s_Array[UBound($s_Array) - 1][1], $s_iStep + 1)
If BitOR(@error, $Temp[0][0] = "") Then ContinueLoop
Next
EndFunc ;==>_EnumChild
;判断第2列是否存在指定无素
Func __AFind(ByRef $s_Array, $s_nData)
If $s_nData = 0 Then Return False
For $i = 0 To UBound($s_Array) - 1
If $s_Array[$i][1] = $s_nData Then Return True
Next
Return False
EndFunc ;==>__AFind
;获取进程命令行
Func _WinAPI_GetCommandLine($s_nProcessID = 0)
If Not $s_nProcessID Then Return ""
Local $ret1 = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x00000410, 'int', False, 'int', $s_nProcessID)
Local $PBI = DllStructCreate("int ExitStatus;ptr PebBaseAddress;ptr AffinityMask;ptr BasePriority;ulong UniqueProcessId;ulong InheritedFromUniqueProcessId;")
DllCall("ntdll.dll", "int", "ZwQueryInformationProcess", "hwnd", $ret1[0], "int", 0, "ptr", DllStructGetPtr($PBI), "int", DllStructGetSize($PBI), "int", 0)
Local $dw = DllStructCreate("ptr")
DllCall("kernel32.dll", "int", "ReadProcessMemory", "hwnd", $ret1[0], "ptr", DllStructGetData($PBI, 2) + 0x10, "ptr", DllStructGetPtr($dw), "int", 4, "ptr", 0)
Local $unicode_string = DllStructCreate("ushort Length;ushort MaxLength;ptr String")
DllCall("kernel32.dll", "int", "ReadProcessMemory", "hwnd", $ret1[0], "ptr", DllStructGetData($dw, 1) + 0x40, "ptr", DllStructGetPtr($unicode_string), "int", DllStructGetSize($unicode_string), "ptr", 0)
Local $Ret = DllCall("kernel32.dll", "int", "ReadProcessMemory", "hwnd", $ret1[0], "ptr", DllStructGetData($unicode_string, "String"), "wstr", 0, "int", DllStructGetData($unicode_string, "Length") + 2, "int*", 0)
DllCall("kernel32.dll", 'int', 'CloseHandle', "hwnd", $ret1[0])
If $Ret[5] Then Return $Ret[3]
Return ""
EndFunc ;==>_WinAPI_GetCommandLine
;~ 枚举子进程
Func __WinAPI_EnumChildProcess($s_nProcessID = 0)
If Not $s_nProcessID Then Return False
Local $hSnapshot = DllCall('kernel32.dll', 'ptr', 'CreateToolhelp32Snapshot', 'dword', 0x00000002, 'dword', 0)
If (@error) Or (Not $hSnapshot[0]) Then
Return SetError(1, 0, 0)
EndIf
Local $tPROCESSENTRY32 = DllStructCreate('dword Size;dword Usage;dword ProcessID;ulong_ptr DefaultHeapID;dword ModuleID;dword Threads;dword ParentProcessID;long PriClassBase;dword Flags;wchar ExeFile[260]')
Local $pPROCESSENTRY32 = DllStructGetPtr($tPROCESSENTRY32)
Local $Ret, $Result[1][2], $i = 0
$hSnapshot = $hSnapshot[0]
DllStructSetData($tPROCESSENTRY32, 'Size', DllStructGetSize($tPROCESSENTRY32))
$Ret = DllCall('kernel32.dll', 'int', 'Process32FirstW', 'ptr', $hSnapshot, 'ptr', $pPROCESSENTRY32)
While (Not @error) And ($Ret[0])
If DllStructGetData($tPROCESSENTRY32, 'ParentProcessID') = $s_nProcessID Then
ReDim $Result[$i + 1][2]
$Result[$i][0] = DllStructGetData($tPROCESSENTRY32, 'ProcessID')
$Result[$i][1] = DllStructGetData($tPROCESSENTRY32, 'ExeFile')
$i += 1
EndIf
$Ret = DllCall('kernel32.dll', 'int', 'Process32NextW', 'ptr', $hSnapshot, 'ptr', $pPROCESSENTRY32)
WEnd
DllCall("kernel32.dll", 'int', 'CloseHandle', "hwnd", $hSnapshot)
Return $Result
EndFunc ;==>__WinAPI_EnumChildProcess
;~ 获取进程映像文件
Func __WinAPI_GetProcessFileName($s_nProcessID = 0)
If Not $s_nProcessID Then Return SetError(1, 0, '')
Local $hProcess = DllCall('kernel32.dll', 'ptr', 'OpenProcess', 'dword', 0x00000410, 'int', 0, 'dword', $s_nProcessID)
If (@error) Or (Not $hProcess[0]) Then Return SetError(1, 0, '')
Local $tPath = DllStructCreate('wchar[1024]')
Local $Ret = DllCall(@SystemDir & '\psapi.dll', 'int', 'GetModuleFileNameExW', 'ptr', $hProcess[0], 'ptr', 0, 'ptr', DllStructGetPtr($tPath), 'int', 1024)
If (@error) Or (Not $Ret[0]) Then $Ret = 0
DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hProcess[0])
If Not IsArray($Ret) Then Return SetError(1, 0, '')
Return DllStructGetData($tPath, 1)
EndFunc ;==>__WinAPI_GetProcessFileName
;~ 试探进程句柄是否可以打开
Func _OpenProcessEX($s_nProcessID)
Local $hProcess = DllCall('kernel32.dll', 'ptr', 'OpenProcess', 'dword', 0x00000410, 'int', 0, 'dword', $s_nProcessID);OpenProcess
If BitOR(@error, $hProcess[0] = 0) Then Return 0
DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hProcess[0]);CloseHandle
Return $hProcess[0]
EndFunc ;==>_OpenProcessEX
;按进程树的级在进程名前添加相应空格
Func _ProcessName_Format($s_ProcessName, $s_Type)
If $s_Type <= 0 Then Return $s_ProcessName
Do
$s_ProcessName = " " & $s_ProcessName
$s_Type -= 1
Until $s_Type = 0
Return $s_ProcessName
EndFunc ;==>_ProcessName_Format
例子.au3#include<ProcessList.au3>
Local $Temp = _ProcessListTree(5000);ms XP下PID 上限值设置5000基本够了,但Win7中须设置更高或不设置参数即65535(0xFFFF)
_ArrayDisplay($Temp ,"进程列表" , -1, 0, "", "|", "Row|进程名|PID|命令行|进程树级")
For $i = 1 To UBound($Temp) - 1
$Temp[$i][0] = _ProcessName_Format($Temp[$i][0], $Temp[$i][3]);按进程树的级在进程名前添加相应空格
Next
_ArrayDisplay($Temp ,"按树状添加空格列表" , -1, 0, "", "|", "Row|进程名|PID|命令行|进程树级")
Local $Temp = __ProcessList(5000)
_ArrayDisplay($Temp,"包含隐藏进程列表", -1, 0, "", "|", "Row|进程名|PID")
附件跟上边的代码是一样的。
|