function UnloadDll(PID: dword;
DLL:
string; synch: Boolean;
var success: Boolean): Boolean;
var
BytesWritten, hProcess, hThread, TID: Cardinal;
Parameters: pointer;
BaseAddr: Cardinal;
pThreadStartRoutine: Pointer;
lpExitCode: Cardinal;
begin
Result := False;
if PID = 0
then
Exit;
BaseAddr := BaseAddrDllProcesso(PID,
DLL);
if BaseAddr = 0
then
Exit;
hProcess := 0;
hThread := 0;
pThreadStartRoutine :=
nil;
try
hProcess := OpenProcess(PROCESS_CREATE_THREAD +
PROCESS_QUERY_INFORMATION +
PROCESS_VM_OPERATION +
PROCESS_VM_WRITE +
PROCESS_VM_READ,
False,
PID
);
if hProcess = 0
then
begin
ErrStr('
OpenProcess');
Exit;
end;
pThreadStartRoutine := GetProcAddress(GetModuleHandle('
KERNEL32.DLL'), '
FreeLibrary');
if pThreadStartRoutine =
nil then
begin
ErrStr('
GetProcAddress');
Exit;
end;
hThread := CreateRemoteThread(hProcess,
nil,
0,
pThreadStartRoutine,
Pointer(BaseAddr),
0,
TID);
if hThread = 0
then
begin
ErrStr('
CreateRemoteThread');
Exit;
end;
//mi metto in attesa della terminazione del thread
if synch
then
begin
case WaitForSingleObject(hThread, INFINITE)
of
WAIT_FAILED:
begin
ErrStr('
WaitForSingleObject');
Exit;
end;
end;
if not GetExitCodeThread(hThread, lpExitCode)
then
begin
ErrStr('
GetExitCodeThread');
Exit;
end;
success := (lpExitCode > 0);
end;
Result := True;
finally
if hThread <> 0
then
begin
if not CloseHandle(hThread)
then
begin
ErrStr('
CloseHandle');
end;
end;
if hProcess <> 0
then
begin
if not CloseHandle(hProcess)
then
begin
ErrStr('
CloseHandle');
end;
end;
end;
end;