[VB.Net] Terminate dll file in a Process

Discussion in 'Mixed Languages' started by jcgo16, May 8, 2012.

  1. jcgo16

    jcgo16 MDL Junior Member

    Sep 16, 2010
    74
    2
    0
    i tried searching this on google but i got nothing, the only i know is p.kill which terminate the whole app, but not the modules
     
  2. BobSheep

    BobSheep MDL Guru

    Apr 19, 2010
    2,326
    1,362
    90
    #2 BobSheep, May 8, 2012
    Last edited: May 8, 2012
    You cannot terminate dll's. You can only terminate threads or processess. A dll is a module which is loaded by processes or threads and a single dll is shared by multiple processes/threads. Therefore a single dll could be used by 10's of threads. To remove all usage of the dll you would need to terminate all threads in all processes using it.

    Please explain what you're trying to achieve because your question as it stands doesn't make much sense.

    edit:

    Do you mean you just want to unload a dll from a process?
     
  3. jcgo16

    jcgo16 MDL Junior Member

    Sep 16, 2010
    74
    2
    0
  4. QuantumBug

    QuantumBug MDL Developer

    Mar 7, 2012
    1,485
    1,323
    60
    #4 QuantumBug, Sep 5, 2012
    Last edited by a moderator: Apr 20, 2017
    Code:
        <DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> 
    _
        Public Shared Function LoadLibrary(<[In](), 
    MarshalAs(UnmanagedType.LPStr)> ByVal lpFileName As String) As IntPtr
        
    End Function
        <DllImport("kernel32.dll", CharSet:=CharSet.Auto, 
    SetLastError:=True)> _
        Public Shared Function GetModuleHandle(ByVal 
    lpModuleName As String) As IntPtr
        End Function
        
    <DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> 
    _
        Public Shared Function FreeLibrary(<[In]()> ByVal hModule As 
    IntPtr) As Boolean
        End 
    Function
    Usage:
    Code:
            Dim hAddress As Long = 
    GetModuleHandle("thedll.dll")
            While hAddress >= 1
                
    FreeLibrary(hAddress)
                hAddress = 
    GetModuleHandle("thedll.dll")
            End While
            
    ?
     
  5. Josh Cell

    Josh Cell MDL Developer

    Jan 8, 2011
    3,519
    7,110
    120
    This isn't the DLLs.

    Is the threads on the process. You can kill it by some kernel calls if you want.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  6. Josh Cell

    Josh Cell MDL Developer

    Jan 8, 2011
    3,519
    7,110
    120
    #6 Josh Cell, Sep 5, 2012
    Last edited by a moderator: Apr 20, 2017
    In a C# Example:

    Code:
            [Flags]
            public enum ThreadAccess : int
            {
                TERMINATE = (0x0001),
                SUSPEND_RESUME = (0x0002),
                GET_CONTEXT = (0x0008),
                SET_CONTEXT = (0x0010),
                SET_INFORMATION = (0x0020),
                QUERY_INFORMATION = (0x0040),
                SET_THREAD_TOKEN = (0x0080),
                IMPERSONATE = (0x0100),
                DIRECT_IMPERSONATION = (0x0200)
            }
    
            [DllImport("kernel32.dll")]
            static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
    
    [DllImport("kernel32.dll")]
            static extern bool TerminateThread(IntPtr hThread, uint dwExitCode);
    
    private void KillAllThreads(int PID)
            {
                Process proc = Process.GetProcessById(PID);
    
                if (proc.ProcessName == string.Empty)
                    return;
    
                foreach (ProcessThread pT in proc.Threads)
                {
                    IntPtr pOpenThread = OpenThread(ThreadAccess.TERMINATE, false, (uint)pT.Id);
    
                    if (pOpenThread == IntPtr.Zero)
                    {
                        break;
                    }
    
                    TerminateThread(pOpenThread, 0);
                }
            }
    Usage:

    Code:
    KillAllThreads(Process.GetProcessesByName("MyProcessHereWithoutExtension")[0].Id);
    You can filter the thread kill using the pT object.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  7. jcgo16

    jcgo16 MDL Junior Member

    Sep 16, 2010
    74
    2
    0
    Sorry "The Dev" its not working


    Btw Josh i did some modification on your code, it works great but the problem is the thread names
    any suggestions?

    btw thanks josh
     
  8. Alphawaves

    Alphawaves Super Moderator/Developer
    Staff Member

    Aug 11, 2008
    5,891
    20,339
    180
    #8 Alphawaves, Sep 6, 2012
    Last edited: Sep 6, 2012
    Can you post your problem ?
    Shouldn't 0 be 1 ? :eek:
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  9. jcgo16

    jcgo16 MDL Junior Member

    Sep 16, 2010
    74
    2
    0
  10. QuantumBug

    QuantumBug MDL Developer

    Mar 7, 2012
    1,485
    1,323
    60
    #11 QuantumBug, Sep 6, 2012
    Last edited: Sep 6, 2012
    :eek: maybe next time :)

    You did reference the location of your .dll properly?
     
  11. jcgo16

    jcgo16 MDL Junior Member

    Sep 16, 2010
    74
    2
    0
    actually im trying to terminate ijl15.dll from the other process

    and its hard because i cant find out if it is ijl15.dll or not
     
  12. Daz

    Daz MDL Developer / Admin
    Staff Member

    Jul 31, 2009
    9,490
    66,578
    300
    #13 Daz, Sep 6, 2012
    Last edited: Sep 6, 2012
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  13. jcgo16

    jcgo16 MDL Junior Member

    Sep 16, 2010
    74
    2
    0
    its hard ^^

    but some i can manage to fix, but still having problems though
     
  14. Josh Cell

    Josh Cell MDL Developer

    Jan 8, 2011
    3,519
    7,110
    120
    #15 Josh Cell, Sep 6, 2012
    Last edited by a moderator: Apr 20, 2017
    I haven't looked, but an solution is the use of DbgHelp class for get the thread info:

    http://www.koders.com/csharp/fidAB470706CB5969E4C035A4ED5335B647A1B82DB8.aspx?s=search#L30

    Code:
    private void KillThreads(int PID)
            {
                Process proc = Process.GetProcessById(PID);
    
                if (proc.ProcessName == string.Empty)
                    return;
    
                foreach (ProcessThread pT in proc.Threads)
                {
                    string ThreadName = "";
                    {
                           IntPtr pOpenThread = OpenThread(ThreadAccess.QUERY_INFORMATION, false, (uint)_processthread.Id);
    
                           DbgHelp.SymInitialize(pOpenThread, null, true);
    
                           DbgHelp.SYMBOL_INFO _symbol = new DbgHelp.SYMBOL_INFO();
    
                           ulong ul = new ulong();
    
                           DbgHelp.SymFromAddr(pOpenThread, (ulong)(_processthread.StartAddress),ref ul, ref _symbol);
    
                           ThreadName = _symbol.Name;
                    }
    
                    if (ThreadName.Contains("User32.dll")
                    {
                           IntPtr pOpenThread = OpenThread(ThreadAccess.TERMINATE, false, (uint)pT.Id);
    
                           if (pOpenThread == IntPtr.Zero)
                           {
                                 break;
                           }
    
                          TerminateThread(pOpenThread, 0);
                    }
                }
            }
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  15. jcgo16

    jcgo16 MDL Junior Member

    Sep 16, 2010
    74
    2
    0
    #16 jcgo16, Sep 6, 2012
    Last edited by a moderator: Apr 20, 2017
    (OP)
    it should be like this right??


    Code:
      Private Sub KillThreads(ByVal PID As Integer)
            Dim proc As Process = Process.GetProcessById(PID)
            If (proc.ProcessName = String.Empty) Then
                Return
            End If
            For Each pT As ProcessThread In proc.Threads
                Dim ThreadName As String = ""
                Dim pOpenThread As IntPtr = OpenThread(ThreadAccess.QUERY_INFORMATION, False, CType(pT.Id, UInteger))
                DbgHelp.SymInitialize(pOpenThread, Nothing, True)
                Dim symbol As DbgHelp.SYMBOL_INFO = New DbgHelp.SYMBOL_INFO
                Dim ul As System.UInt64 = New System.UInt64
                DbgHelp.SymFromAddr(pOpenThread, (pT.StartAddress), ul, symbol)
                ThreadName = symbol.Name
                If ThreadName.Contains("ijl15.dll") Then
                    Dim pOpenThread As IntPtr = OpenThread(ThreadAccess.TERMINATE, False, CType(pT.Id, UInteger))
                    If (pOpenThread = IntPtr.Zero) Then
                        Exit For
                    End If
                    TerminateThread(pOpenThread, 0)
                End If
            Next
        End Sub
    but theres no output
     
  16. master131

    master131 MDL Novice

    Apr 12, 2011
    45
    22
    0
    #17 master131, Sep 9, 2012
    Last edited by a moderator: Apr 20, 2017
    It is possible to unload a DLL from another process using CreateRemoteThread combined with FreeLibrary, similar to the technique many injectors use to inject foreign DLLs into another process. FreeLibrary takes a HMODULE which is essentially the base address of the module to be unloaded. You pass that value using CreateRemoteThread's lpParameter parameter.

    You could also kill or suspend the threads that are running within a module, which takes a little more work. Enumerate through each thread (using the .Threads property) in the target process and "terminate" the DLL/module by suspending or killing the threads that reside inside the module.

    Here is an explanation about how to go about the 2nd method, I may create a small demo when I have time:
    Get a handle of each thread using OpenThread using the thread's ID with the required permissions (THREAD_QUERY_INFORMATION | THREAD_SUSPEND_RESUME | THREAD_TERMINATE). Also make sure to obtain a handle to the process using OpenProcess Now here come's the slightly tricking part, finding which module the thread resides in. You'll need to use DuplicateHandle to obtain a real handle with THREAD_QUERY_INFORMATION as the dwDesiredAccess parameter. Make sure to pass the current process's handle, that is, Process.GetCurrentProcess().Handle as the 1st and 3rd parameters (hSourceProcessHandle and hTargetProcessHandle) respectively. Use NtQueryInformationThread from the 'undocumented' ntdll.dll. The 1st parameter should be the 'real handle'. The 2nd parameter should be ThreadQuerySetWin32StartAddress from the THREADINFOCLASS enum. Pass a reference to an integer as the 3rd parameter and the 4th parameter should be the size of the 3rd parameter (in this case 4, since an integer is 4 bytes long). The last parameter is a reference to an integer containing how many bytes were returned, we don't need this but you can pass a reference anyway. Check that NtQueryInformationThread returned STATUS_SUCCESS (essentially 0) and save the integer we passed as a reference in the 3rd parameter which now contains the address of where the thread is located in memory. Make sure to free the handle using CloseHandle too. Now finally, enumerate through each ProcessModule from the .ProcessModules property of the Process class and check if the thread's address resides within the current module.
    Code:
    ' threadAddress is the address of where the thread is located in memory
    ' targetBaseAddress is the base address of the module we want to unload.
    If currentModule.BaseAddress.ToInt64() >= threadAddress AndAlso threadAddress <= currentModule.BaseAddress.ToInt64() + currentModule.ModuleMemorySize Then
        ' Current thread resides in the current module, check if the current module base address matches our target one.
        If currentModule.BaseAddress = targeBaseAddress Then
            ' Terminate or suspend thraad here using SuspendThread or TerminateThread using the thread handle
            ' obtained earlier. Call CloseHandle afterwards on the thread handle since we won't need it anymore.
        End If
    End If
    Thanks to Napalm at SysInternals for a partial part of this explanation/code.
     
  17. master131

    master131 MDL Novice

    Apr 12, 2011
    45
    22
    0
    #18 master131, Sep 11, 2012
    Last edited: Sep 11, 2012
    Alright, I've whipped up a little library and demo application to do some stuff with processes. It comes with XML comments and source comments so enjoy.

    ProcessUtilities Library Features:
    - Resume, suspend and terminate threads
    - Unload modules from memory
    - Obtain the address of a thread (as a string or integer)

    ProcessUtilities Demo Features:
    - Process list, with icons, PID, description and path
    - Thread list, with TID, start time, state, wait reason and start address
    - Module list, with base address, module size, description, company name and path
    - Kill processes.
    - The features described in the library.

    A lot of the things in the demo are already available through .NET classes. 64-bit process will not appear on the process list (due to the nature of the Process class) and some processes will not appear if UAC is enabled (you can fix by running as administrator).

    Credits: Napalm and myself, master131.

    If you use any of the code, credits would be nice. :biggrin:
     

    Attached Files:

  18. jcgo16

    jcgo16 MDL Junior Member

    Sep 16, 2010
    74
    2
    0
    i got it, i got it working, thanks dude, I LOVE YOU NOW


    and by the way, thanks for those who helped me

    :hug2:
     
  19. Josh Cell

    Josh Cell MDL Developer

    Jan 8, 2011
    3,519
    7,110
    120
    @master131

    Very interesting.. Are working flawless here. :popcorn:

    Good job! :smokecowboy:
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...