Win32汇编实现枚举进程(PSAPI.DLL)

来源:互联网 发布:协和抢号软件 编辑:程序博客网 时间:2024/05/18 02:27

EnumProcesses是PSAPI提供的导出函数,利用该函数可以在无须快照的情况下枚举进程,甚至可以枚举出一些简单的隐藏进程。本例中的枚举用到了回调过程,在回调过程中用户可以随时决定是否中断枚举,从而有效的控制枚举过程。另外,进程隐藏与否的状态也可以在回调过程的参数中取得。如果结合笔者的一篇《Win32汇编实现提升进程Debug权限的两种方法 》文章,则可以进一步扩大枚举范围。本例在XP(SP2)和Vista下测试通过。 
(声明:魏滔序原创,转贴请注明出处。)

;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Win32汇编实现枚举进程(PSAPI.DLL)
; Programmed by 魏滔序                  
; WebSite: http:
//www.chenoe.com        
; Blog: http:
//blog.csdn.net/Modest         
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    .
486                                   ;   create   32   bit   code 
    .model   flat,   stdcall               ;   
32   bit   memory   model 
    
option   casemap   :none               ;   case   sensitive 
        
    include    windows.inc 
    include    psapi.inc
    include    kernel32.inc 
    includelib psapi.lib
    includelib kernel32.lib     
    
    include    user32.inc 
    includelib user32.lib
    
    EnumProcs proto :DWORD
    CallProc Proto :DWORD,:DWORD,:DWORD,:DWORD
.data 
    szPSAPI          db 
'psapi.dll',0
    szGetProcessImageFileNameA db 'GetProcessImageFileNameA',0
    text db '%d',0
.code 
Start:

invoke    EnumProcs,addr CallProc
invoke    ExitProcess,
0

EnumProcs    Proc dwCallProc
    LOCAL    dwProcs[
1023], dwProcCount 
    LOCAL    cbNeeded, dwPID
    LOCAL    hProcess, hModule, szName[MAX_PATH]:
BYTE
    LOCAL    i, dwHide,dwCancel

    Invoke    EnumProcesses,addr dwProcs, SIZEOF dwProcs,ADDR cbNeeded
        .If    EAX !
= 0

        MOV    EAX,cbNeeded
        CDQ
        MOV    ECX, 
4
        IDIV    ECX 
            MOV    dwProcCount ,EAX

        MOV    dwPID,0CH
        .While    
TRUE 
                Invoke    OpenProcess,PROCESS_QUERY_INFORMATION 
Or PROCESS_VM_READ, FALSE, dwPID
                MOV    hProcess,EAX
                   .If    hProcess !
= 0

                        MOV    dwHide,
TRUE
                MOV    i,
0
                        .While    
TRUE
                    LEA    EAX,dwProcs
                    MOV    ECX,i
                    IMUL    ECX,
4
                    ADD    EAX,ECX
                    MOV    EAX,[EAX]
                    
                    .IF dwPID 
== EAX
                                MOV    dwHide,
FALSE
                                .Break .If 
TRUE
                            .EndIf
                            
                            INC    i
                            MOV    EAX,dwProcCount 
                            .Break  .IF i 
== EAX
                        .EndW
                        
                        Invoke    EnumProcessModules,hProcess, ADDR hModule, 
4, ADDR cbNeeded
                        .If    EAX !
= 0
                            Invoke    GetModuleFileNameEx,hProcess, hModule, addr szName, MAX_PATH
                            
                            MOV    dwCancel,
FALSE
                            LEA    EAX,dwCancel
                            PUSH    EAX
                            PUSH    dwHide
                            LEA    EAX,szName
                            PUSH    EAX
                            PUSH    dwPID
                            
CALL    dwCallProc
                            
                            .If    dwCancel
==TRUE
                                Invoke    CloseHandle,hProcess
                                MOV    EAX,
FALSE
                                RET
                            .EndIf
                            
                        .Else
                                PUSH    MAX_PATH
                                LEA    EAX,szName
                                PUSH    EAX
                                PUSH    hProcess
                                Invoke    LoadLibrary,addr szPSAPI
                                Invoke    GetProcAddress,EAX, addr szGetProcessImageFileNameA
                                
CALL    EAX
                                
                                MOV    dwCancel,
FALSE
                            LEA    EAX,dwCancel
                            PUSH    EAX
                                PUSH    
-1
                            LEA    EAX,szName
                            PUSH    EAX
                            PUSH    dwPID
                            
CALL    dwCallProc
                            
                            .If    dwCancel
==TRUE
                                Invoke    CloseHandle,hProcess
                                MOV    EAX,
FALSE
                                RET
                            .EndIf
                            
                        .EndIf
                        Invoke    CloseHandle,hProcess
                   
                   .EndIf
;                    
                    ADD    dwPID,
4
                    .Break  .IF dwPID 
> 0FFFFH
            .EndW
    .EndIf
    MOV    EAX,
TRUE
    RET
EnumProcs    EndP

CallProc Proc dwPID,szName,dwHide,dwCancel
    LOCAL szBuffer[
10]:byte

    Invoke wsprintf,addr szBuffer,addr text,dwPID
    Invoke MessageBox, NULL, szName,addr szBuffer,MB_OK    
    
    ;以下5行用来决定是否继续枚举
    mov ecx,dwCancel 
    assume ecx:ptr 
    push 
TRUE   ;←-如果为FALSE则继续枚举,TRUE则停止,所以在本例中仅枚举出第一个进程。
    pop [ecx]
    assume    ecx:
nothing
    
    ret
CallProc endp

End    Start