Jump to content

Get all modules loaded in a process.


monoceres
 Share

Recommended Posts

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!

Link to comment
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.

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.

Link to comment
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

Link to comment
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!

Link to comment
Share on other sites

  • 1 year later...

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.

Link to comment
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

Link to comment
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. ;)
Link to comment
Share on other sites

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
Link to comment
Share on other sites

  • 3 years later...

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
Link to comment
Share on other sites

  • 3 years later...

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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...