Does somebody know how to unload a dll or any other type of module loaded by an external process?
I tried to do GetModuleHandle and then FreeLibrary with no result…
Thank you for all your replies
Thank you for all your replies. I found an interesting msdn article here :
http://blogs.msdn.com/b/jmstall/archive/2006/09/28/managed-create-remote-thread.aspx
The problem is that when i try to do a OpenProcess the external process crashes.
What are the minimum process access rights to unload a module from it ?
Here is what i am trying to do in c# :
[code]
protected const int PROCESS_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF);
protected const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
protected const int SYNCHRONIZE = 0x100000;
public static bool UnloadRemoteModule(FileEntry le)
{
try
{
Process process = System.Diagnostics.Process.GetProcessById(le.ProcessID);
if (process == null) return false;
StringBuilder sb = new StringBuilder(le.File);
UnloadModuleThreadProc umproc = new UnloadModuleThreadProc(UnloadModule);
IntPtr fpProc = Marshal.GetFunctionPointerForDelegate(umproc);
SafeProcessHandle processHandle = null;
IntPtr currentProcess = NativeMethods.GetCurrentProcess();
int processId = le.ProcessID;
bool remote = (processId != NativeMethods.GetProcessId(currentProcess));
try
{
if (remote)
{
MessageBox.Show("OPENING PROCESS !");
processHandle = NativeMethods.OpenProcess(PROCESS_ALL_ACCESS, true, processId);
System.Threading.Thread.Sleep(200);
uint dwThreadId;
if (processHandle.DangerousGetHandle() == IntPtr.Zero)
{
MessageBox.Show("COULD NOT OPEN HANDLE !");
}
else
{
// Create a thread in the first process.
IntPtr hThread = CreateRemoteThread(
processHandle.DangerousGetHandle(),
IntPtr.Zero,
0,
fpProc, IntPtr.Zero,
0,
out dwThreadId);
System.Threading.Thread.Sleep(200);
WaitForThreadToExit(hThread);
}
}
return true;
}
finally
{
if (remote)
{
if (processHandle != null)
{
processHandle.Close();
}
}
}
return false;
}
catch (Exception ex)
{
//Module.ShowError(ex);
return false;
}
}
public delegate int UnloadModuleThreadProc(IntPtr sb_module_name);
static int UnloadModule(IntPtr sb_module_name2)
{
using (StreamWriter sw = new StreamWriter(@"c:\a\logerr.txt"))
{
sw.AutoFlush = true;
sw.WriteLine("In Unload Module");
StringBuilder sb_module_name =new StringBuilder(@"C:\Windows\System32\MyDll.dll");
IntPtr mh = DetectOpenFiles.GetModuleHandle(sb_module_name.ToString());
sw.WriteLine("LAST ERROR="+Marshal.GetLastWin32Error().ToString());
sw.WriteLine("POINTER="+mh.ToInt32());
if (mh != IntPtr.Zero)
{
return (FreeLibrary(mh) ? 1 : 0);
}
sw.WriteLine("LAST ERROR 2 =" + Marshal.GetLastWin32Error().ToString());
sw.WriteLine("EXIT " + mh.ToInt32());
}
return 0;
}[/code]
You can do it, but honestly I must ask why? You’re most likely going to screw things up beyond what you realize. Seriously, there’s nothing that can go right if you do this. Don’t read the rest of this post, close your browser, do some meditation, and figure out what you’re doing wrong that made you ask this question.
HERE BE DRAGONS
That said, it can be done, and rather easily too.
All you have to do is use
CreateRemoteThread, pass a handle to the process you want to force unload in, and a function pointer to a function that callsGetModuleHandleandFreeLibrary. Easy as pie.Sample code (untested, written in vi, and not to be used no matter what):