请问如何卸载进程中exe的一个dll模块 ( 积分: 50 )

  • 主题发起人 主题发起人 飞来石
  • 开始时间 开始时间

飞来石

Unregistered / Unconfirmed
GUEST, unregistred user!
比如当前进程中有abc.exe,他有一个模块a.dll,如何卸载掉呢?
 
比如当前进程中有abc.exe,他有一个模块a.dll,如何卸载掉呢?
 
楼主是两边发贴啊~~!<br><br>使用FreeLibrary<br><br>FreeLibrary('a.dll');<br>LibHandle:=0; &nbsp;<br><br>还要注意这个dll是否传递过Application.Handle,有的话,要释放。
 
FreeLibrary如果我没记错的话,参数应该是THandle<br><br>比较难,因为你找不到加载的那个Handle值,等高手
 
h := GetModuleHandle('a.dll');<br>FreeLibrary(h);<br>不过要是动态装载的才行,静态链接的好象不行。
 
静态链接的DLL不能卸载。延迟架载的DLL未必能卸载,根据程序开发时的设定.动态加载的支持卸载,可是写在别人程序的DLL基本上出错的可能性很大。<br>你可以用PSAPI中的函数得到其他进程的MODULE,你可以在MSDN中搜索ModuleFirst??/CreateXXXSnapXXX找到相关内容.<br>得到句柄之后,直接CreateRemoteThread(...,_FREELIBRARYW_ADDR_FROM_GETPROCADDR - KERNEL32_BASE_AT_THIS + KERNEL32_BASE_AT_THAT, hDll_AT_THAT,...)
 
我是想用在进程管理程序里面,比如我查看a.exe的时候,显示出了相应的模块dll(已经实现),然后想free掉用户想free的一些dll,这个怎么实现呢?
 
我这有个C++的代码,楼主可以看看,高手可以翻译一下<br>Command Line dll Unloader v1.0<br>by r3L4x - r3L4x.com<br><br>This creates a remote thread in a target<br>process and attempts to call FreeLibrary()<br>in order to unload the target dll.<br><br>This software is FREE and OPEN SOURCE<br>visit http://r3L4x.com for the C++ source!!<br><br>usage:<br>Unload.exe &lt;Target PID&gt; &lt;Target dll&gt;<br><br>http://www.nohack.cn/bbs/UploadFile/2005-4/2005417121443574.rar
 
这里有一些别人讨论的资料,你看看吧<br>若强行杀掉一个.exe,它的私有.DLL就自动释放了,<br>若单独强行卸掉某进程的某一个.DLL,API怎么做?<br>每一个Module都有一个局柄,利用FreeLibrary试一下,刊可不可以释放,获得<br>DLL局柄的方法在上面我提供的源程序中有(http://www.applevb.com/sourcecode/moudle.zip<br>)<br>FreeLibrary只释放自已进程的.DLL,人家的可能就不行了;FreeLibrary()好象无效,结果返回总是0,说明不成功 <br>那么这个呢?<br>FreeLibraryAndExitThread <br>FreeLibraryAndExitThread <br>参数中的线程句柄与退出码没法知道,也不行
 
猜测一下,一般程序调用DLL用,都会使DLL的使用计数器加1.当有N个程序调用他的时候,那么他的计数器为N.当计数器为0时,DLL自动消失。想想用一般的API估计很难实现DLL的撤除,会造成系统崩溃的,MS不可能没考虑到此点的。<br>希望来个高手,把DLL的使用计算器置0,那就自动消失了。
 
静态链接或者延迟加载且不支持卸载的DLL,其引用计数是-1,因此FreeLibrary看到-1就直接返回了。Win2K可以有办法,但是WinXP到现在我还没有看到资料可以做到。<br>因为DLL不仅仅涉及到代码,关键是他会和整个进程交互,基本上你不可能做到卸载DLL而不导致进程失败。<br>不要追求镜花水月了。
 
自己做一个DLL,然后把该DLL插入进程EXE,在自己的DLL中卸掉.详细见&lt;&lt;编程技巧与维护&gt;&gt;
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=2583789
 
标记一下,希望有答案<br>---------------------------------<br>自己做一个DLL,然后把该DLL插入进程EXE,在自己的DLL中卸掉,<br>--------------------------------<br>这种做法是可行,但偶测试的结果是主进程也会同时被关闭,不知哪位有办法卸掉Explorer中注入的dll而Explorer又不关闭?
 
不现实.因为Explorer会使用到该DLL的函数之类.卸了就找不到地址了,当然不错.
 
to jintao:<br> &nbsp;用TASKKILL /IM /pid Explorer的pid /FI &quot;MODULES EQ Dll文件名&quot;<br>某些dll是可以卸掉而Explorer不关闭的呀!不信你试试http://www.2ccc.com/article.asp?articleid=1717 刘麻子的&lt;利用Hook进行线程插入的改进版本&gt;,用此命令可以卸掉(注意:如果不成功请多执行几次)<br> &nbsp;同样是卸这个dll,改用相同的注入方法注入另一个dll去Free它,就会出现Explorer关闭的情况.
 
unit Unit1;<br><br>interface<br><br>uses<br> &nbsp;Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br> &nbsp;Dialogs, StdCtrls;<br><br>type<br> &nbsp;TForm1 = class(TForm)<br> &nbsp; &nbsp;Button1: TButton;<br> &nbsp; &nbsp;Edit1: TEdit;<br> &nbsp; &nbsp;Label1: TLabel;<br> &nbsp; &nbsp;Label2: TLabel;<br> &nbsp; &nbsp;Edit2: TEdit;<br> &nbsp; &nbsp;procedure Button1Click(Sender: TObject);<br> &nbsp;private<br> &nbsp; &nbsp;{ Private declarations }<br> &nbsp;public<br> &nbsp; &nbsp;{ Public declarations }<br> &nbsp;end;<br><br>var<br> &nbsp;Form1: TForm1;<br><br>type<br> &nbsp;TFreeLibrary = function(hLibModule: HMODULE): BOOL; stdcall;<br> &nbsp;TMessageBox = function(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall;<br> &nbsp;TVirtualFree = function(lpAddress: Pointer; dwSize, dwFreeType: DWORD): BOOL; stdcall;<br> &nbsp;TExitThread = procedure(dwExitCode: DWORD); stdcall;<br> &nbsp;TBuf = array[0..1023] of char;<br>{ Remote thread code start }<br>function RemoteThreadProc(LParam: Integer): Integer; stdcall;<br>function DummyBlockAddr: Integer; stdcall;<br>{ Remote thread code end ... }<br>function DummyCodeEnd: Integer;<br>implementation<br><br>{$R *.dfm}<br>type<br> &nbsp;PRemoteData = ^TRemoteData;<br> &nbsp;TRemoteData= record<br> &nbsp; &nbsp; &nbsp;// 全局变量区和重定位表<br> &nbsp; &nbsp;FreeLibrary: TFreeLibrary;<br> &nbsp; &nbsp;MessageBox: TMessageBox;<br> &nbsp; &nbsp;VirtualFree: TVirtualFree;<br> &nbsp; &nbsp;ExitThread: TExitThread;<br> &nbsp; &nbsp;Title:TBuf;//标题<br> &nbsp; &nbsp;Buf: TBuf;<br> &nbsp; &nbsp;dwModule: HMODULE;<br> &nbsp;end;<br>var<br> &nbsp;RemoteData: TRemoteData=(Title:'Info';);<br><br>function RemoteThreadProc(LParam: Integer): Integer; stdcall;<br>var<br> &nbsp;cp: PRemoteData;<br> &nbsp;p2, p3: Pointer;<br>begin<br> &nbsp;Result := 0;<br> &nbsp;if LParam &lt;&gt; 0 then<br> &nbsp;begin<br> &nbsp; &nbsp;cp := Pointer(LParam);<br> &nbsp; &nbsp;cp.FreeLibrary(cp.dwModule);<br> &nbsp; &nbsp;cp.MessageBox(0, cp.Buf, cp.Title, MB_ICONINFORMATION + MB_TOPMOST);<br> &nbsp; &nbsp;p2 := @cp.VirtualFree;<br> &nbsp; &nbsp;p3 := @cp.ExitThread;<br> &nbsp; &nbsp;asm<br> &nbsp; &nbsp; &nbsp; &nbsp;push Result<br> &nbsp; &nbsp; &nbsp; &nbsp;push 0<br><br> &nbsp; &nbsp; &nbsp; &nbsp;push MEM_RELEASE<br> &nbsp; &nbsp; &nbsp; &nbsp;push 0<br> &nbsp; &nbsp; &nbsp; &nbsp;push cp<br> &nbsp; &nbsp; &nbsp; &nbsp;push p3<br><br> &nbsp; &nbsp; &nbsp; &nbsp;push p2<br> &nbsp; &nbsp; &nbsp; &nbsp;ret<br> &nbsp; &nbsp;end;<br> &nbsp;end<br> &nbsp;else<br> &nbsp; &nbsp;asm<br> &nbsp; &nbsp;call @@1<br> &nbsp;@@1:<br> &nbsp; &nbsp;pop eax<br> &nbsp; &nbsp;mov Result, eax<br> &nbsp; &nbsp;end;<br>end;<br><br>function DummyBlockAddr: Integer; stdcall;<br>asm<br> &nbsp;call @@1<br>@@1:<br> &nbsp;pop eax;<br> &nbsp;ret<br> &nbsp;dd 0,0,0,0,0,0,0,0<br> &nbsp;dd 0,0,0,0,0,0,0,0<br> &nbsp;nop; nop; nop; nop;<br>end;<br><br>function DummyCodeEnd: Integer;<br>begin<br> &nbsp;Result := Integer(@DummyCodeEnd);<br>end;<br><br><br>function EnableDebugPrivilege: Boolean;<br> &nbsp;function EnablePrivilege(hToken: Cardinal; PrivName: string; bEnable: Boolean): Boolean;<br> &nbsp;var<br> &nbsp; &nbsp;TP: TOKEN_PRIVILEGES;<br> &nbsp; &nbsp;Dummy: Cardinal;<br> &nbsp;begin<br> &nbsp; &nbsp;TP.PrivilegeCount := 1;<br> &nbsp; &nbsp;LookupPrivilegeValue(nil, pchar(PrivName), TP.Privileges[0].Luid);<br> &nbsp; &nbsp;if bEnable then<br> &nbsp; &nbsp; &nbsp;TP.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED<br> &nbsp; &nbsp;else TP.Privileges[0].Attributes := 0;<br> &nbsp; &nbsp;AdjustTokenPrivileges(hToken, False, TP, SizeOf(TP), nil, Dummy);<br> &nbsp; &nbsp;Result := GetLastError = ERROR_SUCCESS;<br> &nbsp;end;<br><br>var<br> &nbsp;hToken: Cardinal;<br>begin<br> &nbsp;OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hToken);<br> &nbsp;result := EnablePrivilege(hToken, 'SeDebugPrivilege', True);<br> &nbsp;CloseHandle(hToken);<br>end;<br><br>function FuncOffset(P1, P2: TFarProc): Integer;<br>begin<br> &nbsp;Result := Integer(P2) - Integer(P1);<br>end;<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br> &nbsp;kernel32, user32: THandle;<br> &nbsp;PID: Integer;<br> &nbsp;hProcess, th: THandle;<br> &nbsp;m, n, &nbsp;len: Integer;<br> &nbsp;p, lp, cp, dp: Pointer;<br> &nbsp;tmp: string;<br> &nbsp;rmt: PRemoteData;<br> &nbsp;dw, tid: Cardinal;<br>begin<br> &nbsp;Tid := 0;<br> &nbsp;EnableDebugPrivilege; //提升权限<br><br> &nbsp;PID := StrToIntDef(Edit1.Text, 0);<br> &nbsp;if PID = 0 then<br> &nbsp;begin<br> &nbsp; &nbsp;ShowMessage('Process ID Error!');<br> &nbsp; &nbsp;Exit;<br> &nbsp;end;<br><br> &nbsp;hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, PID);<br> &nbsp;if hProcess = 0 then<br> &nbsp;begin<br> &nbsp; &nbsp;ShowMessage('Open Process Error!');<br> &nbsp; &nbsp;Exit;<br> &nbsp;end;<br><br><br> &nbsp;kernel32 := GetModuleHandle(Windows.kernel32);<br> &nbsp;user32 := GetModuleHandle(Windows.user32);<br><br> &nbsp;@RemoteData.FreeLibrary := GetProcAddress(kernel32, 'FreeLibrary');<br> &nbsp;@RemoteData.MessageBox := GetProcAddress(user32, 'MessageBoxA');<br><br> &nbsp;StrPCopy(RemoteData.Buf, '成功完成!');<br> &nbsp;RemoteData.dwModule := StrToIntDef(Edit2.Text, 0);<br><br> &nbsp;@RemoteData.ExitThread := GetProcAddress(kernel32, 'ExitThread');<br> &nbsp;@RemoteData.VirtualFree := GetProcAddress(kernel32, 'VirtualFree');<br><br> &nbsp;p := @RemoteThreadProc;<br> &nbsp;m := FuncOffset(p, @DummyCodeEnd) + 100;<br> &nbsp;n := FuncOffset(p, Pointer(DummyBlockAddr)) + 16;<br> &nbsp;len := m + SizeOf(TRemoteData) + 1024;<br> &nbsp;lp := VirtualAllocEx(hProcess, nil, len, MEM_COMMIT, PAGE_EXECUTE_READWRITE);<br> &nbsp;if lp &lt;&gt; nil then<br> &nbsp;begin<br> &nbsp; &nbsp;SetLength(tmp, len);<br> &nbsp; &nbsp;rmt := PRemoteData(tmp);<br> &nbsp; &nbsp;cp := PChar(tmp) + SizeOf(RemoteData);<br> &nbsp; &nbsp;Move(RemoteData, rmt^, SizeOf(RemoteData));<br> &nbsp; &nbsp;Move(p^, cp^, m);<br> &nbsp; &nbsp;PInteger(Integer(cp) + n)^ := Integer(lp);<br> &nbsp; &nbsp; // 函数重定位<br> &nbsp; &nbsp;dp := lp;<br> &nbsp; &nbsp;cp := Pointer(Integer(dp) + SizeOf(TRemoteData));<br><br> &nbsp; &nbsp;if WriteProcessMemory(hProcess, lp, rmt, len - 100, dw) then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;th := CreateRemoteThread(hProcess, nil, 0, cp, dp, 0, tid);<br> &nbsp; &nbsp; &nbsp;if th = 0 then<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;Showmessage('Create remote thread fail');<br> &nbsp; &nbsp; &nbsp; &nbsp;if lp &lt;&gt; nil then VirtualFreeEx(hProcess, lp, 0, MEM_RELEASE);<br> &nbsp; &nbsp; &nbsp; &nbsp;if hProcess &lt;&gt; 0 then CloseHandle(hProcess);<br> &nbsp; &nbsp; &nbsp; &nbsp;Exit;<br> &nbsp; &nbsp; &nbsp;end;<br><br> &nbsp; &nbsp; &nbsp;CloseHandle(th);<br> &nbsp; &nbsp;end<br> &nbsp; &nbsp;else<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;if lp &lt;&gt; nil then VirtualFreeEx(hProcess, lp, 0, MEM_RELEASE);<br> &nbsp; &nbsp; &nbsp;if hProcess &lt;&gt; 0 then CloseHandle(hProcess);<br> &nbsp; &nbsp; &nbsp;Exit;<br> &nbsp; &nbsp;end;<br> &nbsp;end;<br> &nbsp;ShowMessage('Remote thread create successfully, Addr: ' + '0x' + IntToHex(Integer(lp), 8));<br>end;<br><br>end.<br><br>你试试
 
“这种做法是可行,但偶测试的结果是主进程也会同时被关闭”<br>如果卸载掉的dll还会被调用自然会出错,这不是卸载的问题,问题出在没被卸载的模块里。
 
to jingtao:<br> &nbsp;您的代码偶测试了不能卸载掉Explorer中的Dll.<br>to tt.t:<br> &nbsp;我们先不说能否这么做,您用IceSword你试试卸载注入Explorer中的Dll!多数情况下Explorer都不会自动关闭。偶想知道的是如何实现这种方法。<br>to 楼主:<br> 借您的宝地讨论一下,希望不要见怪.<br><br>顺便贴出偶的&quot;用钩子卸钩子&quot;的测试代码,请大家研究一下如何来改进<br><br>使用方法:unload.exe insert.dll<br><br>申明:本示例只做了针对Exlporer中的Dll的卸载,代码改自刘麻子的线程插入的例子,实现了用钩子卸钩子的基本要求,但本程序不完善,卸载了Explorer中的Dll后会出现Explorer自动结束的情况.<br><br>//主程序如下:<br>program Unload;<br><br>uses Windows, FUnit in 'FUnit.pas';<br><br>var UNFile:string;<br>begin<br><br> &nbsp;UNFile:=ParamStr(1); <br> &nbsp;if UNFile='' then exit;<br><br> &nbsp;if (OpenMutex(MUTEX_ALL_ACCESS, FALSE, ExeMutex) &lt;&gt; 0) or<br> &nbsp; &nbsp; (OpenMutex(MUTEX_ALL_ACCESS, FALSE, DllMutex) &lt;&gt; 0) then Exit;<br><br> &nbsp;HMutex := CreateMutex(nil, TRUE, ExeMutex);<br> &nbsp;ExplorerPID := FindProcess('Explorer.exe');<br> &nbsp;if (ExplorerPID = 0) then<br> &nbsp;begin MessageBox(0, '寻找Explorer出错 ', nil, 0); &nbsp;Exit; end;<br><br> &nbsp;FindDll(ExplorerPID,UNFile);<br> &nbsp;FileMap := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(TNode), FileMapName);<br> &nbsp;if (FileMap = 0) then<br> &nbsp;begin<br> &nbsp; &nbsp;MessageBox(0, '创建映射文件出错 ', nil, 0); &nbsp;Exit;<br> &nbsp;end;<br> &nbsp;PtNode := MapViewOfFile(FileMap, FILE_MAP_WRITE, 0, 0, 0);<br> &nbsp;if (PtNode = nil) then<br> &nbsp;begin<br> &nbsp; &nbsp;MessageBox(0, '映射到本进程出错 ', nil, 0); &nbsp; &nbsp;<br> &nbsp; &nbsp;CloseHandle(FileMap); &nbsp;Exit;<br> &nbsp;end;<br> &nbsp;PtNode^.MainThread := GetCurrentThreadID();<br> &nbsp;PtNode^.ExplorerID := ExplorerPID;<br> &nbsp;ptNode^.UNDLLHandle:=FindDll(ExplorerPID,UNFile);//要卸载的DLL在Explorer中的Handle<br> &nbsp;UnmapViewOfFile(PtNode);<br> &nbsp;GetMsgHookOn; <br> &nbsp;while GetMessage(Msg, 0, 0, 0) do;<br> &nbsp;GetMsgHookOff;<br> &nbsp;CloseHandle(FileMap);<br> &nbsp;ReleaseMutex(HMutex);<br>end.<br><br>//所引用的FUnit.pas如下:<br>unit FUnit;<br><br>interface<br><br>uses Windows,TLHelp32,SysUtils;<br><br>type<br> &nbsp;TNode = record &nbsp; &nbsp; &nbsp; <br> &nbsp; &nbsp;MainThread: DWORD; <br> &nbsp; &nbsp;ExplorerID: DWORD; <br> &nbsp; &nbsp;UNDLLHandle:DWORD; <br> &nbsp;end;<br> &nbsp;PNode = ^TNode;<br><br>const<br> &nbsp;ExeMutex = 'ExeMutex_wangsea'; &nbsp; <br> &nbsp;DllMutex = 'DllMutex_wangsea'; &nbsp; <br> &nbsp;FileMapName = 'FileMap_wangsea'; <br><br>var<br> &nbsp;HMutex: THandle; &nbsp;<br> &nbsp;Msg: TMsg; &nbsp; &nbsp; &nbsp; &nbsp;<br> &nbsp;FileMap: THandle; <br> &nbsp;PtNode: PNode; &nbsp; &nbsp;<br> &nbsp;ExplorerPID: DWORD; <br><br>function FindProcess(ExeName: string): DWORD;<br>function FindDll(ProcessID:cardinal;Dll:string):Cardinal;<br><br>procedure GetMsgHookOn; external &nbsp;'UnloadDll.dll';<br>procedure GetMsgHookOff; external 'UnloadDLL.dll';<br><br>implementation<br><br>type <br> &nbsp;TProcessEntry32 = packed record<br> &nbsp; &nbsp;dwSize: DWORD; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br> &nbsp; &nbsp;cntUsage: DWORD;<br> &nbsp; &nbsp;th32ProcessID: DWORD; &nbsp; &nbsp; &nbsp; <br> &nbsp; &nbsp;th32DefaultHeapID: DWORD;<br> &nbsp; &nbsp;th32ModuleID: DWORD; &nbsp; &nbsp; &nbsp; &nbsp;<br> &nbsp; &nbsp;cntThreads: DWORD;<br> &nbsp; &nbsp;th32ParentProcessID: DWORD; <br> &nbsp; &nbsp;pcPriClassBase: Longint; &nbsp; &nbsp;<br> &nbsp; &nbsp;dwFlags: DWORD;<br> &nbsp; &nbsp;szExeFile: array[0..MAX_PATH - 1] of Char;<br> &nbsp;end;<br><br>function CreateToolhelp32Snapshot(dwFlags, th32ProcessID: DWORD): THandle stdcall; external 'kernel32.dll';<br>function Process32First(hSnapshot: THandle; var lppe: TProcessEntry32): BOOL stdcall; external 'kernel32.dll';<br>function Process32Next(hSnapshot: THandle; var lppe: TProcessEntry32): BOOL stdcall; external 'kernel32.dll';<br><br>function FindProcess(ExeName: string): DWORD;<br>var<br> &nbsp;sphandle: THandle; &nbsp;Found: BOOL;<br> &nbsp;PStruct: TProcessEntry32;<br> &nbsp;function AnsiEndsText(const ASubText, AText: string): Boolean;<br> &nbsp;var<br> &nbsp; &nbsp;P: PChar;<br> &nbsp; &nbsp;L, L2: Integer;<br> &nbsp;begin<br> &nbsp; &nbsp;P := PChar(AText);<br> &nbsp; &nbsp;L := Length(ASubText);<br> &nbsp; &nbsp;L2 := Length(AText);<br> &nbsp; &nbsp;Inc(P, L2 - L);<br> &nbsp; &nbsp;if (L &gt; L2) then<br> &nbsp; &nbsp; &nbsp;Result := FALSE<br> &nbsp; &nbsp;else<br> &nbsp; &nbsp; &nbsp;Result := CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE,P, L, PChar(ASubText), L) = 2;<br> &nbsp;end; &nbsp; &nbsp; &nbsp; <br>begin &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br> &nbsp;Result := 0;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br> &nbsp;sphandle := CreateToolhelp32Snapshot($00000002, 0);<br> &nbsp;PStruct.dwSize := Sizeof(PStruct);<br> &nbsp;Found := Process32First(sphandle, PStruct);<br><br> &nbsp;while Found do<br> &nbsp;begin<br> &nbsp; &nbsp;if AnsiEndsText(ExeName, PStruct.szExefile) then<br> &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp;Result := PStruct.th32ProcessID;<br> &nbsp; &nbsp; &nbsp;Break;<br> &nbsp; &nbsp;end;<br> &nbsp; &nbsp;<br> &nbsp; &nbsp;Found := Process32Next(sphandle, PStruct);<br> &nbsp;end;<br> &nbsp;<br> &nbsp;CloseHandle(sphandle);<br>end;<br><br>function FindDll(ProcessID:cardinal;Dll:string):Cardinal;<br>var<br> &nbsp;snap:THandle;<br> &nbsp;lpme:TModuleEntry32;<br>begin<br> &nbsp;result:=0;<br> &nbsp;snap:=CreateToolhelp32Snapshot(TH32CS_SNAPALL,ProcessID);<br> &nbsp;try<br> &nbsp; &nbsp;FillChar(lpme,Sizeof(TModuleEntry32),0);<br> &nbsp; &nbsp;lpme.dwSize:=Sizeof(TModuleEntry32);<br> &nbsp; &nbsp;if Module32First(snap,lpme) then<br> &nbsp; &nbsp; repeat<br> &nbsp; &nbsp; &nbsp; if UpperCase(ExtractFileName(lpme.szExePath))=UpperCase(Dll) then<br> &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;result:=lpme.hModule;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;break;<br> &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; until not Module32Next(snap,lpme);<br> &nbsp;finally<br> &nbsp; &nbsp;CloseHandle(snap);<br> &nbsp;end;<br>end;<br><br>end.<br><br>//Dll如下:<br>library Unloaddll;<br><br>uses<br> &nbsp;Windows, Messages,<br> &nbsp;Publics in 'Publics.pas',<br> &nbsp;Threads in 'Threads.pas',<br> &nbsp;JmpHook in 'JmpHook.pas';<br><br>exports<br> &nbsp;GetMsgHookOn,<br> &nbsp;GetMsgHookOff,<br> &nbsp;ThreadPro;<br> &nbsp; &nbsp;<br>procedure DLLProcess(dwReason: Integer);<br>begin &nbsp; &nbsp;<br> &nbsp;if (dwReason = DLL_PROCESS_DETACH) then<br> &nbsp;begin<br> &nbsp; &nbsp;if (PtNode &lt;&gt; nil) then UnmapViewOfFile(PtNode);<br> &nbsp; &nbsp;if (FileMap &lt;&gt; 0) then CloseHandle(FileMap);<br> &nbsp;end;<br>end;<br><br>begin<br> &nbsp;DllProc := @DLLProcess; <br> &nbsp;FileMap := OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, FileMapName);<br> &nbsp;if (FileMap &lt;&gt; 0) then PtNode := MapViewOfFile(FileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);<br>end.<br><br>//Dll所用的三个pas如下:<br>1:<br>unit Publics;<br><br>interface<br>uses<br> &nbsp;Windows;<br>type<br> &nbsp;TNode = record &nbsp; &nbsp; &nbsp; &nbsp;<br> &nbsp; &nbsp;MainThread: DWORD; &nbsp;<br> &nbsp; &nbsp;ExplorerID: DWORD; &nbsp;<br> &nbsp; &nbsp;UNDLLHandle:DWORD; &nbsp;<br> &nbsp;end;<br> &nbsp;PNode = ^TNode;<br><br>const<br> &nbsp;DllMutex = 'DllMutex_wangsea'; <br> &nbsp;FileMapName = 'FileMap_wangsea'; <br>var<br> &nbsp;FileMap: THandle;<br> &nbsp;PtNode: PNode;<br>implementation<br><br>end.<br>2:<br>unit Threads;<br><br>interface<br>procedure ThreadPro(Ct: Integer); stdcall;<br><br>implementation<br><br>uses Windows, Messages, Publics,SysUtils;<br><br>procedure WriteScreen(S: string);<br>var<br> &nbsp;ScreenDC: HDC;<br>begin<br> &nbsp;ScreenDC := GetDC(0);<br> &nbsp;TextOut(ScreenDC, 10, 10, PChar(S), Length(S));<br> &nbsp;ReleaseDC(0, ScreenDC);<br>end;<br><br>function Int2Hex(x: Integer): string;<br>var<br> &nbsp;J, K: Integer;<br>begin<br> &nbsp;Result := '$00000000';<br> &nbsp;for J := 9 downto 2 do<br> &nbsp;begin<br> &nbsp; &nbsp;K := x and $0F;<br><br> &nbsp; &nbsp;if (K &gt; 9) then K := K + 7;<br> &nbsp; &nbsp;K := K + $30;<br> &nbsp; &nbsp;Result[J] := Char(K);<br> &nbsp; &nbsp;<br> &nbsp; &nbsp;x := x shr 4;<br> &nbsp;end;<br>end;<br><br>procedure ThreadPro(Ct: Integer); stdcall;<br>var<br> &nbsp;//TheMsg: TMsg;<br> &nbsp;HMutex: DWORD;<br> &nbsp;//AtomID: ATOM;<br>begin<br> &nbsp;PostThreadMessage(PtNode^.MainThread, WM_QUIT, 0, 0);<br> &nbsp;HMutex := OpenMutex(MUTEX_ALL_ACCESS, FALSE, DllMutex);<br> &nbsp;if (HMutex = 0) then<br> &nbsp;begin<br> &nbsp; &nbsp;HMutex := CreateMutex(nil, TRUE, DllMutex);<br> &nbsp; &nbsp;if PtNode^.UNDLLHandle&lt;&gt;0 then <br> &nbsp; &nbsp; &nbsp;FreeLibrary(PtNode^.UNDLLHandle);<br> &nbsp; &nbsp;ReleaseMutex(HMutex);<br> &nbsp;end;<br> &nbsp;CloseHandle(HMutex);<br> &nbsp;FreeLibraryAndExitThread(HInstance, 0);<br>end;<br><br>end.<br><br>3:<br>unit JmpHook;<br><br>interface<br><br>procedure GetMsgHookOn;<br>procedure GetMsgHookOff;<br><br>implementation<br><br>uses<br> &nbsp;Windows, Publics;<br><br>var<br> &nbsp;GetMsgHook: HHOOK; &nbsp; &nbsp; <br> &nbsp;LibraryH: DWORD; &nbsp; &nbsp; &nbsp;<br> &nbsp;ThreadPt: Pointer; &nbsp; &nbsp; <br> &nbsp;ThreadID: DWORD; &nbsp; &nbsp; &nbsp; <br> &nbsp;ModuleFileName: array [0..MAX_PATH] of Char;<br><br>function GetMsgHookPro(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;<br>begin<br> &nbsp;if (PtNode &lt;&gt; nil) and (PtNode^.ExplorerID &lt;&gt; 0) and<br> &nbsp; &nbsp; (GetCurrentProcessId() = PtNode^.ExplorerID) then <br> &nbsp;begin<br> &nbsp; &nbsp;GetModuleFileName(HInstance, @ModuleFileName[0], MAX_PATH);<br> &nbsp; &nbsp;LibraryH := LoadLibrary(ModuleFileName);<br> &nbsp; &nbsp;if (LibraryH &lt;&gt; 0) then ThreadPt := GetProcAddress(LibraryH, 'ThreadPro');<br> &nbsp; &nbsp;if (ThreadPt &lt;&gt; nil) then CreateThread(nil, 0, ThreadPt, Pointer($66666666), 0, ThreadID);<br> &nbsp;end;<br> &nbsp;Result:= CallNextHookEx(GetMsgHook, nCode, wParam, lParam); &nbsp;<br>end;<br><br>procedure GetMsgHookOn; <br>begin<br> &nbsp;GetMsgHook := SetWindowsHookEx(WH_GETMESSAGE, @GetMsgHookPro, HInstance, 0);<br>end;<br><br>procedure GetMsgHookOff; <br>begin<br> &nbsp;UnHookWindowsHookEx(GetMsgHook);<br>end;<br><br>end.
 
不会吧.你填写了EXE的进程ID和该DLL在EXE里面的MODULE吗?<br>很多DLL是需要卸几次才能干净的.因为可能EXE多次引用了该DLL
 
后退
顶部