to jingtao:<br> 您的代码偶测试了不能卸载掉Explorer中的Dll.<br>to tt.t:<br> 我们先不说能否这么做,您用IceSword你试试卸载注入Explorer中的Dll!多数情况下Explorer都不会自动关闭。偶想知道的是如何实现这种方法。<br>to 楼主:<br> 借您的宝地讨论一下,希望不要见怪.<br><br>顺便贴出偶的"用钩子卸钩子"的测试代码,请大家研究一下如何来改进<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> UNFile:=ParamStr(1); <br> if UNFile='' then exit;<br><br> if (OpenMutex(MUTEX_ALL_ACCESS, FALSE, ExeMutex) <> 0) or<br> (OpenMutex(MUTEX_ALL_ACCESS, FALSE, DllMutex) <> 0) then Exit;<br><br> HMutex := CreateMutex(nil, TRUE, ExeMutex);<br> ExplorerPID := FindProcess('Explorer.exe');<br> if (ExplorerPID = 0) then<br> begin MessageBox(0, '寻找Explorer出错 ', nil, 0); Exit; end;<br><br> FindDll(ExplorerPID,UNFile);<br> FileMap := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(TNode), FileMapName);<br> if (FileMap = 0) then<br> begin<br> MessageBox(0, '创建映射文件出错 ', nil, 0); Exit;<br> end;<br> PtNode := MapViewOfFile(FileMap, FILE_MAP_WRITE, 0, 0, 0);<br> if (PtNode = nil) then<br> begin<br> MessageBox(0, '映射到本进程出错 ', nil, 0); <br> CloseHandle(FileMap); Exit;<br> end;<br> PtNode^.MainThread := GetCurrentThreadID();<br> PtNode^.ExplorerID := ExplorerPID;<br> ptNode^.UNDLLHandle:=FindDll(ExplorerPID,UNFile);//要卸载的DLL在Explorer中的Handle<br> UnmapViewOfFile(PtNode);<br> GetMsgHookOn; <br> while GetMessage(Msg, 0, 0, 0) do;<br> GetMsgHookOff;<br> CloseHandle(FileMap);<br> ReleaseMutex(HMutex);<br>end.<br><br>//所引用的FUnit.pas如下:<br>unit FUnit;<br><br>interface<br><br>uses Windows,TLHelp32,SysUtils;<br><br>type<br> TNode = record <br> MainThread: DWORD; <br> ExplorerID: DWORD; <br> UNDLLHandle
WORD; <br> end;<br> PNode = ^TNode;<br><br>const<br> ExeMutex = 'ExeMutex_wangsea'; <br> DllMutex = 'DllMutex_wangsea'; <br> FileMapName = 'FileMap_wangsea'; <br><br>var<br> HMutex: THandle; <br> Msg: TMsg; <br> FileMap: THandle; <br> PtNode: PNode; <br> ExplorerPID: DWORD; <br><br>function FindProcess(ExeName: string): DWORD;<br>function FindDll(ProcessID:cardinal;Dll:string):Cardinal;<br><br>procedure GetMsgHookOn; external 'UnloadDll.dll';<br>procedure GetMsgHookOff; external 'UnloadDLL.dll';<br><br>implementation<br><br>type <br> TProcessEntry32 = packed record<br> dwSize: DWORD; <br> cntUsage: DWORD;<br> th32ProcessID: DWORD; <br> th32DefaultHeapID: DWORD;<br> th32ModuleID: DWORD; <br> cntThreads: DWORD;<br> th32ParentProcessID: DWORD; <br> pcPriClassBase: Longint; <br> dwFlags: DWORD;<br> szExeFile: array[0..MAX_PATH - 1] of Char;<br> 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> sphandle: THandle; Found: BOOL;<br> PStruct: TProcessEntry32;<br> function AnsiEndsText(const ASubText, AText: string): Boolean;<br> var<br> P: PChar;<br> L, L2: Integer;<br> begin<br> P := PChar(AText);<br> L := Length(ASubText);<br> L2 := Length(AText);<br> Inc(P, L2 - L);<br> if (L > L2) then<br> Result := FALSE<br> else<br> Result := CompareString(LOCALE_USER_DEFAULT, NORM_IGNORECASE,P, L, PChar(ASubText), L) = 2;<br> end; <br>begin <br> Result := 0;<br> <br> sphandle := CreateToolhelp32Snapshot($00000002, 0);<br> PStruct.dwSize := Sizeof(PStruct);<br> Found := Process32First(sphandle, PStruct);<br><br> while Found do<br> begin<br> if AnsiEndsText(ExeName, PStruct.szExefile) then<br> begin<br> Result := PStruct.th32ProcessID;<br> Break;<br> end;<br> <br> Found := Process32Next(sphandle, PStruct);<br> end;<br> <br> CloseHandle(sphandle);<br>end;<br><br>function FindDll(ProcessID:cardinal;Dll:string):Cardinal;<br>var<br> snap:THandle;<br> lpme:TModuleEntry32;<br>begin<br> result:=0;<br> snap:=CreateToolhelp32Snapshot(TH32CS_SNAPALL,ProcessID);<br> try<br> FillChar(lpme,Sizeof(TModuleEntry32),0);<br> lpme.dwSize:=Sizeof(TModuleEntry32);<br> if Module32First(snap,lpme) then<br> repeat<br> if UpperCase(ExtractFileName(lpme.szExePath))=UpperCase(Dll) then<br> begin<br> result:=lpme.hModule;<br> break;<br> end;<br> until not Module32Next(snap,lpme);<br> finally<br> CloseHandle(snap);<br> end;<br>end;<br><br>end.<br><br>//Dll如下:<br>library Unloaddll;<br><br>uses<br> Windows, Messages,<br> Publics in 'Publics.pas',<br> Threads in 'Threads.pas',<br> JmpHook in 'JmpHook.pas';<br><br>exports<br> GetMsgHookOn,<br> GetMsgHookOff,<br> ThreadPro;<br> <br>procedure DLLProcess(dwReason: Integer);<br>begin <br> if (dwReason = DLL_PROCESS_DETACH) then<br> begin<br> if (PtNode <> nil) then UnmapViewOfFile(PtNode);<br> if (FileMap <> 0) then CloseHandle(FileMap);<br> end;<br>end;<br><br>begin<br> DllProc := @DLLProcess; <br> FileMap := OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, FileMapName);<br> if (FileMap <> 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> Windows;<br>type<br> TNode = record <br> MainThread: DWORD; <br> ExplorerID: DWORD; <br> UNDLLHandle
WORD; <br> end;<br> PNode = ^TNode;<br><br>const<br> DllMutex = 'DllMutex_wangsea'; <br> FileMapName = 'FileMap_wangsea'; <br>var<br> FileMap: THandle;<br> 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> ScreenDC: HDC;<br>begin<br> ScreenDC := GetDC(0);<br> TextOut(ScreenDC, 10, 10, PChar(S), Length(S));<br> ReleaseDC(0, ScreenDC);<br>end;<br><br>function Int2Hex(x: Integer): string;<br>var<br> J, K: Integer;<br>begin<br> Result := '$00000000';<br> for J := 9 downto 2 do<br> begin<br> K := x and $0F;<br><br> if (K > 9) then K := K + 7;<br> K := K + $30;<br> Result[J] := Char(K);<br> <br> x := x shr 4;<br> end;<br>end;<br><br>procedure ThreadPro(Ct: Integer); stdcall;<br>var<br> //TheMsg: TMsg;<br> HMutex: DWORD;<br> //AtomID: ATOM;<br>begin<br> PostThreadMessage(PtNode^.MainThread, WM_QUIT, 0, 0);<br> HMutex := OpenMutex(MUTEX_ALL_ACCESS, FALSE, DllMutex);<br> if (HMutex = 0) then<br> begin<br> HMutex := CreateMutex(nil, TRUE, DllMutex);<br> if PtNode^.UNDLLHandle<>0 then <br> FreeLibrary(PtNode^.UNDLLHandle);<br> ReleaseMutex(HMutex);<br> end;<br> CloseHandle(HMutex);<br> 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> Windows, Publics;<br><br>var<br> GetMsgHook: HHOOK; <br> LibraryH: DWORD; <br> ThreadPt: Pointer; <br> ThreadID: DWORD; <br> ModuleFileName: array [0..MAX_PATH] of Char;<br><br>function GetMsgHookPro(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;<br>begin<br> if (PtNode <> nil) and (PtNode^.ExplorerID <> 0) and<br> (GetCurrentProcessId() = PtNode^.ExplorerID) then <br> begin<br> GetModuleFileName(HInstance, @ModuleFileName[0], MAX_PATH);<br> LibraryH := LoadLibrary(ModuleFileName);<br> if (LibraryH <> 0) then ThreadPt := GetProcAddress(LibraryH, 'ThreadPro');<br> if (ThreadPt <> nil) then CreateThread(nil, 0, ThreadPt, Pointer($66666666), 0, ThreadID);<br> end;<br> Result:= CallNextHookEx(GetMsgHook, nCode, wParam, lParam); <br>end;<br><br>procedure GetMsgHookOn; <br>begin<br> GetMsgHook := SetWindowsHookEx(WH_GETMESSAGE, @GetMsgHookPro, HInstance, 0);<br>end;<br><br>procedure GetMsgHookOff; <br>begin<br> UnHookWindowsHookEx(GetMsgHook);<br>end;<br><br>end.