monoceres

Get all modules loaded in a process.

17 posts in this topic

#1 ·  Posted (edited)

Hi all!

I don't think anyone has done this before so here it goes:

This returns an array of all the modules (dll files) that are loaded into a process.

For some reason the array also contains a great deal of copies of the process's full path.

#Include <WinAPI.au3>

; #FUNCTION#;===============================================================================
;
; Name...........: _ProcessGetLoadedModules
; Description ...: Returns an array containing the full path of the loaded modules
; Syntax.........: _ProcessGetLoadedModules($iPID)
; Parameters ....:
; Return values .: Success - An array with all the paths
;               : Failure - -1 and @error=1 if the specified process couldn't be opened.
; Author ........: Andreas Karlsson (monoceres) & ProgAndy
; Modified.......:
; Remarks .......:
; Related .......: 
; Link ..........;
; Example .......; No
;
;;==========================================================================================
Func _ProcessGetLoadedModules($iPID)
    Local Const $PROCESS_QUERY_INFORMATION=0x0400
    Local Const $PROCESS_VM_READ=0x0010
    Local $aCall, $hPsapi=DllOpen("Psapi.dll")
    Local $hProcess, $tModulesStruct
    $tModulesStruct=DllStructCreate("hwnd [200]")
    Local $SIZEOFHWND = DllStructGetSize($tModulesStruct)/200
    $hProcess=_WinAPI_OpenProcess(BitOR($PROCESS_QUERY_INFORMATION,$PROCESS_VM_READ),False,$iPID)
    If Not $hProcess Then Return SetError(1,0,-1)
    $aCall=DllCall($hPsapi,"int","EnumProcessModules","ptr",$hProcess,"ptr",DllStructGetPtr($tModulesStruct),"dword",DllStructGetSize($tModulesStruct),"dword*","")
    If $aCall[4]>DllStructGetSize($tModulesStruct) Then
        $tModulesStruct=DllStructCreate("hwnd ["&$aCall[4]/$SIZEOFHWND&"]")
        $aCall=DllCall($hPsapi,"int","EnumProcessModules","ptr",$hProcess,"ptr",DllStructGetPtr($tModulesStruct),"dword",$aCall[4],"dword*","")
    EndIf
    Local $aReturn[$aCall[4]/$SIZEOFHWND]
    For $i=0 To Ubound($aReturn)-1
        
$aCall=DllCall($hPsapi,"dword","GetModuleFileNameExW","ptr",$hProcess,"ptr",DllStructGetData($tModulesStruct,1,$i+1),"wstr","","dword",65536)
$aReturn[$i]=$aCall[3]
    
Next
    _WinAPI_CloseHandle($hProcess)
    DllClose($hPsapi)
    Return $aReturn
EndFunc

Enjoy!

:)

Edited by monoceres

Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites



This is like DOS command

TASKLIST /M
?


When the words fail... music speaks

Share this post


Link to post
Share on other sites

This is like DOS command

TASKLIST /M
?
Yeah, I guess so. This should be faster though :)

Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

I don'y know if is a bug or is normal but at one time appeared that process as module several times.

Try this to see what I want to say.

#Include <WinAPI.au3>
#include <Array.au3>

; #FUNCTION#;===============================================================================
;
; Name...........: _ProcessGetLoadedModules
; Description ...: Returns an array containing the full path of the loaded modules
; Syntax.........: _ProcessGetLoadedModules($iPID)
; Parameters ....:
; Return values .: Success - An array with all the paths
;               : Failure - -1 and @error=1 if the specified process couldn't be opened.
; Author ........: Andreas Karlsson (monoceres)
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; No
;
;;==========================================================================================
Func _ProcessGetLoadedModules($iPID)
    Local Const $PROCESS_QUERY_INFORMATION=0x0400
    Local Const $PROCESS_VM_READ=0x0010
    Local $aCall, $hPsapi=DllOpen("Psapi.dll")
    Local $hProcess, $tModulesStruct
    $tModulesStruct=DllStructCreate("int [1000]")
    $hProcess=_WinAPI_OpenProcess(BitOR($PROCESS_QUERY_INFORMATION,$PROCESS_VM_READ),False,$iPID)
    If Not $hProcess Then Return SetError(1,0,-1)
    $aCall=DllCall($hPsapi,"int","EnumProcessModules","ptr",$hProcess,"ptr",DllStructGetPtr($tModulesStruct),"dword",1000,"dword*","")
    If $aCall[4]>1000 Then
        $tModulesStruct=DllStructCreate("int ["&$aCall[4]&"]")
        $aCall=DllCall($hPsapi,"int","EnumProcessModules","ptr",$hProcess,"ptr",DllStructGetPtr($tModulesStruct),"dword",$aCall[4],"dword*","")
    EndIf
    Local $aReturn[$aCall[4]]
    For $i=0 To Ubound($aReturn)-1
        $aCall=DllCall($hPsapi,"dword","GetModuleFileNameExW","ptr",$hProcess,"int",DllStructGetData($tModulesStruct,1,$i+1),"wstr","","dword",65536)
        $aReturn[$i]=$aCall[3]
    Next
    _WinAPI_CloseHandle($hProcess)
    DllClose($hPsapi)
    Return $aReturn
EndFunc

$LIST = ProcessList()
$MODULES = _ProcessGetLoadedModules($LIST[5][1])
_ArrayDisplay($MODULES,$LIST[5][0])
Edited by Andreik

When the words fail... music speaks

Share this post


Link to post
Share on other sites

I don'y know if is a bug or is normal but at one time appeared that process as module several times.

I mentioned that in my original post :)


Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites

I mentioned that in my original post :)

Sorry. >_<


When the words fail... music speaks

Share this post


Link to post
Share on other sites

I have the BugFix. EnumProcessModules returns the BYTES needed, not the count of Module Hanldes. So you have to divide the Bytes through SIZEOFHWND :)

#Include <WinAPI.au3>
#include <Array.au3>

; #FUNCTION#;===============================================================================
;
; Name...........: _ProcessGetLoadedModules
; Description ...: Returns an array containing the full path of the loaded modules
; Syntax.........: _ProcessGetLoadedModules($iPID)
; Parameters ....:
; Return values .: Success - An array with all the paths
;               : Failure - -1 and @error=1 if the specified process couldn't be opened.
; Author ........: Andreas Karlsson (monoceres)
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; No
;
;;==========================================================================================
Func _ProcessGetLoadedModules($iPID)
    Local Const $PROCESS_QUERY_INFORMATION=0x0400
    Local Const $PROCESS_VM_READ=0x0010
    Local $aCall, $hPsapi=DllOpen("Psapi.dll")
    Local $hProcess, $tModulesStruct
    $tModulesStruct=DllStructCreate("hwnd [200]")
    Local $SIZEOFHWND = DllStructGetSize($tModulesStruct)/200
    $hProcess=_WinAPI_OpenProcess(BitOR($PROCESS_QUERY_INFORMATION,$PROCESS_VM_READ),False,$iPID)
    If Not $hProcess Then Return SetError(1,0,-1)
    $aCall=DllCall($hPsapi,"int","EnumProcessModules","ptr",$hProcess,"ptr",DllStructGetPtr($tModulesStruct),"dword",DllStructGetSize($tModulesStruct),"dword*","")
    If $aCall[4]>DllStructGetSize($tModulesStruct) Then
        $tModulesStruct=DllStructCreate("hwnd ["&$aCall[4]/$SIZEOFHWND&"]")
        $aCall=DllCall($hPsapi,"int","EnumProcessModules","ptr",$hProcess,"ptr",DllStructGetPtr($tModulesStruct),"dword",$aCall[4],"dword*","")
    EndIf
    Local $aReturn[$aCall[4]/$SIZEOFHWND]
    For $i=0 To Ubound($aReturn)-1
        $aCall=DllCall($hPsapi,"dword","GetModuleFileNameExW","ptr",$hProcess,"int",DllStructGetData($tModulesStruct,1,$i+1),"wstr","","dword",65536)
        $aReturn[$i]=$aCall[3]
    Next
    _WinAPI_CloseHandle($hProcess)
    DllClose($hPsapi)
    Return $aReturn
EndFunc

$LIST = ProcessList()
$MODULES = _ProcessGetLoadedModules($LIST[5][1])
_ArrayDisplay($MODULES,$LIST[5][0])

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

I have the BugFix. EnumProcessModules returns the BYTES needed, not the count of Module Hanldes. So you have to divide the Bytes through SIZEOFHWND :)

Of course, how stupid of me Posted Image

Thanks for fixing it (updating my first post and adding you to authors) >_<


Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites

Hi,does it not work in windows 7? Why can't I get anything in the win7 pro?

Share this post


Link to post
Share on other sites

Hi,does it not work in windows 7? Why can't I get anything in the win7 pro?

It works for me under Win 7 RC (x64). It gives wrong results for x64 but running under x86 gives the expected results.

You must be using it wrong, please show a small (but runnable) reproducer of your problem.

Share this post


Link to post
Share on other sites

It works for me under Win 7 RC (x64). It gives wrong results for x64 but running under x86 gives the expected results.

You must be using it wrong, please show a small (but runnable) reproducer of your problem.

The x64-error could come from the GetModuleFileNameExW. There is "int" as type instead of "ptr", so try and change it ;)

$aCall=DllCall($hPsapi,"dword","GetModuleFileNameExW","ptr",$hProcess,"ptr",DllStructGetData($tModulesStruct,1,$i+1),"wstr","","dword",65536)

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

The x64-error could come from the GetModuleFileNameExW. There is "int" as type instead of "ptr", so try and change it :evil:

$aCall=DllCall($hPsapi,"dword","GetModuleFileNameExW","ptr",$hProcess,"ptr",DllStructGetData($tModulesStruct,1,$i+1),"wstr","","dword",65536)

Works perfect now. ;)

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

The code seems not wrong for no mistake show in the console(win7 x86). So I can't know how to deal with it.

And with your opnion(instead of "ptr" with "int"), that is the same.

Second line of what you quoted was: You must be using it wrong, please show a small (but runnable) reproducer of your problem.

You saw that?

Edited by trancexx

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

Updated with ProgAndys fix.


Broken link? PM me and I'll send you the file!

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

Nice script.
 
I used it on Win 7 (x64) and got an error:
 

Local $aReturn[$aCall[4]/$SIZEOFHWND]
Local $aReturn[^ ERROR
 
Error: Array variable subscript badly formatted.

 

Added a BugFix  before the line:

If Not $aCall[4] Then Return SetError(1,0,-1)

The script worked.

If I run the script or compile it to x86, it works (on x64) properly.

If I compile the script to x64, it will only returns the x64 modules. The x32 modules will not be ruturned.

What could be the reason?

Thanks in advance.

Edited by Factfinder

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

It seems that compiling to x86 version only returns the x86 modules.

When compiled with to x64 version only returns the x64 modules.

So the script needs modification to cover both the versions.

Edited by Factfinder

Share this post


Link to post
Share on other sites

would agree with this. no go on win10 either

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now