I want to enum system processes and display therir filename..

When I use GetModuleFileNameEx() via Psapi lib of MASM32, It works normally,
but it terminates exceptionally when I used the GetModuleFileNameEx() address got by call GetProcAddress().

Here is my code.



.386
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

a_UsePsapiLib EQU 0

if a_UsePsapiLib eq 1
include \masm32\include\Psapi.inc
includelib \masm32\lib\Psapi.lib
endif


EnumProcess PROTO
GetModuleFileSpec PROTO :DWORD, :DWORD

a_ShowGetModuleErr EQU 1

.data
g_szWinTitle db "MouduleName", 0

g_szFailLoadPsapi db "Fail to load"
g_szPsapiDLL db "psapi", 0
g_szFailGetEnumProcMods db "Fail to get"
g_szEnumProcMods db "EnumProcessModules", 0
g_szFailGetModuleFileNameExA db "Fail to get"
g_szGetModFileNameExA db "GetModuleFileNameExA", 0

if a_ShowGetModuleErr eq 1
g_szFailGetProcHandle db "Fail to get the handle of process!", 0
g_szFailEnumModule db "Fail to enum module!", 0
g_szFailGetModName db "Fail to get the filename of module!", 0
endif

.data?
g_hInstance HINSTANCE ?

g_hProcess HANDLE ?

g_lpfnEnumProcMods dword ?
g_lpfnGetModFNameExA dword ?


.code
start:
invoke GetModuleHandle, NULL
mov g_hInstance, eax

invoke LoadLibrary, OFFSET g_szPsapiDLL
.IF (eax == NULL)
invoke MessageBox, NULL, OFFSET g_szFailLoadPsapi, OFFSET g_szWinTitle, MB_ICONERROR
jmp @Exit
.ENDIF

mov g_hProcess, eax
invoke GetProcAddress, g_hProcess, OFFSET g_szEnumProcMods
.if (eax == NULL)
invoke MessageBox, NULL, OFFSET g_szFailGetEnumProcMods, OFFSET g_szWinTitle, MB_ICONERROR
invoke FreeLibrary, g_hProcess
jmp @Exit
.endif

mov g_lpfnEnumProcMods, eax
invoke GetProcAddress, g_hProcess, OFFSET g_szGetModFileNameExA
mov g_lpfnGetModFNameExA, eax
invoke FreeLibrary, g_hProcess
.if (g_lpfnGetModFNameExA == NULL)
invoke MessageBox, NULL, OFFSET g_szFailGetModuleFileNameExA, OFFSET g_szWinTitle, MB_ICONERROR
jmp @Exit
.endif

invoke EnumProcess
@Exit:
invoke ExitProcess, eax


EnumProcess proc
LOCAL Buff [255]: BYTE
LOCAL Handle4EnumProc: HANDLE
LOCAL ProcEntry: PROCESSENTRY32

;---------------------------------------------------
;1 Get the handle needed to enum process
;---------------------------------------------------
invoke CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, 0
mov Handle4EnumProc, eax

;---------------------------------------------------
;2 Initilizes the struct to store process infomation
;---------------------------------------------------
mov ProcEntry.dwSize, sizeof PROCESSENTRY32

;---------------------------------------------------
;3 Enum the first process
;---------------------------------------------------
invoke Process32First, Handle4EnumProc, ADDR ProcEntry
.WHILE (eax != NULL)
invoke GetModuleFileSpec, ProcEntry.th32ProcessID, ADDR Buff
.if (eax == 0)
lea eax, Buff
.IF (byte ptr [eax] == '\') ;The path can have the prefix "\\?\", skip it
add eax, 4
.ENDIF
.else
lea eax, ProcEntry.szExeFile
.endif

;---------------------------------------------------
;4 Display the file name of process
;---------------------------------------------------
invoke MessageBox, NULL, eax, OFFSET g_szWinTitle, NULL

;---------------------------------------------------
;4 Enum next process
;---------------------------------------------------
invoke Process32Next, Handle4EnumProc, ADDR ProcEntry
.ENDW

;---------------------------------------------------
; Close the handle
;---------------------------------------------------
invoke CloseHandle, Handle4EnumProc
ret
EnumProcess endp



;#####################################################################
; Get the Module File specify specified by proc ID
; Input: procID --- the ID of proc we want to get its file specify
; lpszFileSpec --- the pointer to buffer to store file specify
; Output: eax == 0 succeed
; eax == 1 Fail to get proc handle
; eax == 2 Fail to enum module
; eax == 3 Fail to get module file name
;=====================================================================
GetModuleFileSpec PROC uses edi procID: DWORD, lpszFileSpec: DWORD
LOCAL hMods[100]; HMODULE
LOCAL dw_cbNeeded; DWORD
LOCAL buf [255]: BYTE

invoke OpenProcess, PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, FALSE, procID
mov g_hProcess, eax
.IF (eax == NULL)

if a_ShowGetModuleErr eq 1 ;????????????????????????
invoke MessageBox, NULL, OFFSET g_szFailGetProcHandle, OFFSET g_szWinTitle, MB_ICONERROR
endif ;????????????????????????

mov eax, 1
ret
.ENDIF

;invoke EnumProcessModules, g_hProcess, ADDR hMods, SIZEOF hMods, ADDR dw_cbNeeded
lea eax, dw_cbNeeded
push eax
push SIZEOF hMods
lea eax, hMods
push eax
push g_hProcess
call g_lpfnEnumProcMods
.if(eax == 0)
invoke CloseHandle, g_hProcess

if a_ShowGetModuleErr eq 1 ;????????????????????????
invoke MessageBox, NULL, OFFSET g_szFailEnumModule, OFFSET g_szWinTitle, MB_ICONERROR
endif ;????????????????????????

mov eax, 2
ret
.endif

lea edi, hMods

if a_UsePsapiLib eq 1 ;??????????????????????????
invoke GetModuleFileNameEx, g_hProcess, [edi], lpszFileSpec, MAX_PATH
else
push MAX_PATH
push lpszFileSpec
push [edi]
push g_hProcess
call g_lpfnGetModFNameExA
endif ;??????????????????????????

.IF (eax == 0)
push 3
.ELSE
push 0
.ENDIF
invoke CloseHandle, g_hProcess
pop eax

ret
GetModuleFileSpec ENDP

end start
Posted on 2004-05-12 10:38:17 by purpleendurer
purpleendurer
You free psapi.dll but uses function from it.
Move
invoke  FreeLibrary, g_hProcess
to
...

@Exit:
invoke FreeLibrary, g_hProcess
invoke ExitProcess, eax
...
Posted on 2004-05-12 22:15:57 by P2M
Thanks P2M.

You are right:alright:
Posted on 2004-05-13 01:51:23 by purpleendurer