Jump to content
Sign in to follow this  
oliver369

Loaded DLL files per process

Recommended Posts

oliver369

Hi all,

I have been trying to find over the last few days a way of outputing loaded DLL files (with the full path) for each process and unloading them. I am not sure if this is even possible in AutoIt, having no experience in C++ it makes the job a slight more difficult :) The other difficult point is that it must support 64bit processes and work on 2000/XP/2003/Vista. If anybody has an input or any ideas just let me know. Thanks.

Oliver

Share this post


Link to post
Share on other sites
DarkMatter

If you execute an "associators of" query for Win32_Process.Handle="XXXX", and if you look for the Cim_DataFile instances, then you should have the loaded DLLs for a given running executable.


[sub]Quantum mechanics: The dreams stuff is made of[/sub]

Share this post


Link to post
Share on other sites
oliver369

If you execute an "associators of" query for Win32_Process.Handle="XXXX", and if you look for the Cim_DataFile instances, then you should have the loaded DLLs for a given running executable.

Wow thanks for the fast response, you don't happen to have a link or even better a script where it is explained? :)

edit: thanks SmOke_N I will check this out first...

Edited by oliver369

Share this post


Link to post
Share on other sites
oliver369

Sorry guys to be annoying; I have searched around to find some more information on the Associators Of and Cim_DataFile but cannot find out how to put it together into one query. Could someone possibly give me an example so that I can work on it?

Share this post


Link to post
Share on other sites
DarkMatter

Something like the following would be an example:

Dim $Handle = ProcessExists("notepad.exe")
Dim $colItems
Dim $objItem
Dim $objWMIService = ObjGet("winmgmts:\\localhost\root\CIMV2")

$colItems = $objWMIService.ExecQuery("ASSOCIATORS OF {Win32_Process.Handle='" & $Handle & "'} WHERE ResultClass = CIM_DataFile")

If IsObj($colItems) Then
   For $objItem In $colItems
    ConsoleWrite($objItem.Drive & $objItem.Path & $objItem.FileName & "." & $objItem.Extension & @CRLF)
   Next
EndIf

Here is where you can get a reference for all the Properties in CIM_DataFile: http://msdn2.microsoft.com/en-us/library/a...236(VS.85).aspx

Edited by DarkMatter

[sub]Quantum mechanics: The dreams stuff is made of[/sub]

Share this post


Link to post
Share on other sites
oliver369

DarkMatter works like a charm! Many many thanks!

Share this post


Link to post
Share on other sites
SmOke_N

Something like the following would be an example:

Dim $Handle = ProcessExists("notepad.exe")
Dim $colItems
Dim $objItem
Dim $objWMIService = ObjGet("winmgmts:\\localhost\root\CIMV2")

$colItems = $objWMIService.ExecQuery("ASSOCIATORS OF {Win32_Process.Handle='" & $Handle & "'} WHERE ResultClass = CIM_DataFile")

If IsObj($colItems) Then
   For $objItem In $colItems
    ConsoleWrite($objItem.Drive & $objItem.Path & $objItem.FileName & "." & $objItem.Extension & @CRLF)
   Next
EndIfoÝ÷ Øw«z+0êÞÊjxµªÞ}êÞÇ¢¶¥Ø^>º)z»bzȧjÖW®®
But don't have time to debug my struct at the moment to get it working right.... maybe in a few hours or so unless someone fixes it first.

Edit:

Fixed nasty code tag issue.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites
SmOke_N

Stupid mistake above, I had the wrong size of one of the struct params.

This should be considerably faster than using the object method:

#include<Array.au3>
$avArray = _ProcessListModules("notepad.exe")
_ArrayDisplay($avArray, "Modules")

Func _ProcessListModules($dwPID)
    If IsInt($dwPID) = 0 Then $dwPID = ProcessExists($dwPID)
   
    Local Const $TH32CS_SNAPALL = BitOR(0x01, 0x08, 0x02, 0x04)
    Local $aDLLCall, $tagMODULEENTRY32, $hModuleSnap
   
    $aDLLCall = DllCall("Kernel32.dll", "ptr", "CreateToolhelp32Snapshot", "int", $TH32CS_SNAPALL, "dword", $dwPID)
    If @error Or $aDLLCall[0] = 0xFFFFFFFF Then Return SetError(1, 0, 0)
    $hModuleSnap = $aDLLCall[0]
   
    $tagMODULEENTRY32 = DllStructCreate("dword;dword;dword;dword;dword;byte;dword;uint;char[257];char[256]")
    DllStructSetData($tagMODULEENTRY32, 1, DllStructGetSize($tagMODULEENTRY32))
    
    $aDLLCall = DllCall("Kernel32.dll", "int", "Module32First", "ptr", $hModuleSnap, "long", DllStructGetPtr($tagMODULEENTRY32))
    If @error Or Not $aDLLCall[0] Then Return SetError(2, DllCall("Kernel32.dll", "int", "CloseHandle", "ptr", $hModuleSnap), 0)
    
    Local $avArray[2][2], $iAdd = 1
    While 1
        $avArray[$iAdd][0] = DllStructGetData($tagMODULEENTRY32, 9) ; File Name
        $avArray[$iAdd][1] = DllStructGetData($tagMODULEENTRY32, 10) ; File Path
        $aDLLCall = DllCall("kernel32", "int", "Module32Next", "ptr", $hModuleSnap, "long", DllStructGetPtr($tagMODULEENTRY32))
        If @error Then Return SetError(3, DllCall("Kernel32.dll", "int", "CloseHandle", "ptr", $hModuleSnap), 0)
        If Not $aDLLCall[0] Then ExitLoop
        $iAdd += 1
        ReDim $avArray[$iAdd + 1][2]
    WEnd
    DllCall("Kernel32.dll", "int", "CloseHandle", "ptr", $hModuleSnap)
    $avArray[0][0] = $iAdd
    Return $avArray
EndFunc
Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites
oliver369

Great I will give it a try see which one fits to my needs better :D I now can get on with the rest of the program, when I find a way to unload DLL's I will post it here. :D

Share this post


Link to post
Share on other sites
weaponx

Great I will give it a try see which one fits to my needs better :D I now can get on with the rest of the program, when I find a way to unload DLL's I will post it here. :D

$dll = "my.dll"

RunWait("regsvr32 /u /s " & $dll)

Share this post


Link to post
Share on other sites
oliver369

$dll = "my.dll"

RunWait("regsvr32 /u /s " & $dll)

That unregisters the DLL it does not unload the DLL from the process it attaches itself to.

Share this post


Link to post
Share on other sites
Squirrely1

...I have been trying to find...a way of outputing loaded DLL files (with the full path) for each process and unloading them.

Despite the interesting ways in which we might find of unloading DLL's -

1. Why would you want to unload the DLL's of a process that is still running, except to crash the process ?

2. Why would you need the full path to the already loaded DLL except to delete the file it was loaded from, or steal it ?

3. Even if your intentions are innocent, the Windows OS normally does its own loading and unloading of DLL's

The only things I personally could ever need to do with a dll since I don't know how to create them:

1. Find out how to use its functions.

2. Use its functions.

3. FileInstall() it.

4. Register it (using REGSVR32).

5. Unregister it (using REGSVR32).

Whatever you are all on, please list it so we know to stay off it.

Edit: OK - it could be that the OP is using Linux and Wine - then if Linux handles dll's differently...

Edited by Squirrely1

Das Häschen benutzt Radar

Share this post


Link to post
Share on other sites
oliver369

Basically what I want to achieve is a infection diagnostic/removal tool, as you may know threats such as Virtumondo will inject a DLL into a running process; usually csrss.exe. Here are the facts:

  • You cannot delete/rename the file in even in safe mode (minimal) the file will obviously be in use
  • You cannot end csrss.exe Windows will crash and reboot
  • You cannot unregister the DLL because it will say the entry point has not been specified
  • You cannot rename the file on reboot it is constantly monitoring the following registry HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations so programs such as Killbox will fail
The only ways I can find to remove the DLL are by using something like Sysinternal's Process Explorer (http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx), using the Recovery Console / a linux live CD such as Ubuntu with write capabilities on an NTFS partition. Obviously I would like to be able to do it through my program as the Sysinternal licensing terms does not allow you to add their utilities to your program.

EDIT: Forgot to mention why I needed the full path of the DLL is simply due to the fact that the virus/adware creators are not that stupid (unfortunately :D ) :

If the infected DLL is called ntdll.dll and is placed in the temp directory for example it would appear exactly like the legitimate c:\windows\system32\ntdll.dll file....

Edited by oliver369

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
Sign in to follow this  

×