Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.03.18;
Скачать: CL | DM;

Вниз

разблокировать чужой файл   Найти похожие ветки 

 
Apachi   (2007-01-18 15:29) [0]

уважаемые мастера
возможно ли разблокировать файл, котоый держит другой, неизвестный нам процесс


 
Apachi   (2007-01-18 15:30) [1]

ну или в крайнем случае как определить процесс для того что бы его остановить


 
novill ©   (2007-01-18 16:02) [2]

Читал, что можно, методы хакерские, исходниками были, сам не проверял.


 
Игорь Шевченко ©   (2007-01-18 16:09) [3]

Возможно, запустить Process Explorer с www.sysinternals.com, найти, кто держит файл, и убить держателя


 
Styx_   (2007-01-18 20:20) [4]

Есть утилита Unlocker - она как-то это делает. Без убийства процесса.


 
ors_archangel ©   (2007-01-18 20:33) [5]

Сам написал, может не работь, а если работает, то долго :)

type
 PIPF_RemoteThreadRec = ^TIPF_RemoteThreadRec;
 TIPF_RemoteThreadRec = record
   hp,minappaddr,maxappaddr,pagesize: dword;
   minHandleValue,maxHandleValue: THandle;
   targetFInfo: TByHandleFileInformation;
   ProcessUsesFile: boolean;
 { funcs }
   GetFileInformationByHandle: function(hFile: THandle; var lpFileInformation: TByHandleFileInformation): BOOL; stdcall;
   beep: procedure(hz,dur: integer); stdcall; // for tests
 end;

function IPF_RemoteThread(var rec: TIPF_RemoteThreadRec): integer; stdcall;
var
 commited: integer;
 lockable: integer;
 addr: dword;
 finfo: TByHandleFileInformation;
 f: THandle;
begin
 //rec.beep(1000,100);exit; // test of execution :)
 rec.ProcessUsesFile := false;
 for f := rec.minHandleValue to rec.maxHandleValue do with rec do
 try
   if
     GetFileInformationByHandle(f, finfo) and
     (finfo.dwFileAttributes = targetFInfo.dwFileAttributes) and
     (finfo.ftCreationTime.dwLowDateTime = targetFInfo.ftCreationTime.dwLowDateTime) and
     (finfo.ftCreationTime.dwHighDateTime = targetFInfo.ftCreationTime.dwHighDateTime) and
     (finfo.ftLastAccessTime.dwLowDateTime = targetFInfo.ftLastAccessTime.dwLowDateTime) and
     (finfo.ftLastWriteTime.dwHighDateTime = targetFInfo.ftLastWriteTime.dwHighDateTime) and
     (finfo.dwVolumeSerialNumber = targetFInfo.dwVolumeSerialNumber) and
     (finfo.nFileSizeHigh = targetFInfo.nFileSizeHigh) and
     (finfo.nFileSizeLow = targetFInfo.nFileSizeLow) and
     (finfo.nNumberOfLinks = targetFInfo.nNumberOfLinks) and
     (finfo.nFileIndexHigh = targetFInfo.nFileIndexHigh) and
     (finfo.nFileIndexLow = targetFInfo.nFileIndexLow)
   then begin
     rec.ProcessUsesFile := true;
     exit;
   end;
 except
 end;
end;

function IsProcessUsingFile(pid: cardinal; f: THandle): boolean;
var
 name: string;
 tid: dword;
 hp,ht: THandle;
 sysinfo: TSystemInfo;
 threadRec: TIPF_RemoteThreadRec;
 user,kernel: HModule;
 addr: dword;
 dummy: dword;
 fm: THandle;
 dataaddr: pointer;
 datasize: integer;
 time: cardinal;
begin
 result := false;
 if not GetFileInformationByHandle(f, threadrec.targetFInfo) then
   RaiseLastOSErr;
{ connect to process }
 hp := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION or
   PROCESS_VM_OPERATION or PROCESS_VM_WRITE or PROCESS_VM_READ, false, pid);
 if hp = 0 then RaiseLastOSErr("Cannot open process "+name);
{ fill data record for locking thread }
 threadRec.hp := hp;
 GetSystemInfo(sysinfo);
 with threadRec do begin
   minappaddr := dword(sysinfo.lpMinimumApplicationAddress);
   maxappaddr := dword(sysinfo.lpMaximumApplicationAddress);
   pagesize := sysinfo.dwPageSize;
   minHandleValue := 1;
   maxHandleValue := 9999;
   // targetFInfo always setted
   ProcessUsesFile := false;
   kernel := GetModuleHandle(kernel32);
   user := GetModuleHandle(user32);
   GetFileInformationByHandle := GetProcAddress(kernel, "GetFileInformationByHandle");
   beep := GetProcAddress(kernel, "Beep");
 end;
{ alloc page }
 addr := dword(VirtualAllocEx(hp,nil,threadRec.pagesize, MEM_COMMIT, PAGE_EXECUTE_READWRITE));
 if addr = 0 then RaiseLastOsErr("Can`t alloc page in "+name);
{ write data }
 datasize := sizeof(TIPF_RemoteThreadRec);
 WriteProcessMemory(hp, pointer(addr), @threadRec, datasize, dummy);
{ write code }
 WriteProcessMemory(hp, pointer(addr+datasize), @IPF_RemoteThread, threadRec.pageSize-datasize, dummy);
{ execute remote thread }
 ht := CreateRemoteThread(hp, nil, 0, pointer(addr+datasize), pointer(addr), 0, tid);
 if ht = 0 then
   RaiseLastOSErr("Cannot create remote thread in "+name)
 else begin
   SetThreadPriority(ht, THREAD_PRIORITY_TIME_CRITICAL);
   time := 0;
   while ThreadStillActive(ht) do begin
     Sleep(100);
     inc(time);
     if time > 1000 then break;
     Application.ProcessMessages;
   end;
   CloseHandle(ht);
 { read data back }
   ReadProcessMemory(hp, pointer(addr), @threadRec, datasize, dummy);
   result := threadRec.ProcessUsesFile;
   VirtualFreeEx(hp,pointer(addr),threadRec.pagesize,MEM_FREE);
 end;
 CloseHandle(hp);
end;

type
 PFPUF_ThreadRec = ^TFPUF_ThreadRec;
 TFPUF_ThreadRec = record
   pid: cardinal;
   f: THandle;
   result: boolean;
   err: string;
 end;

procedure FPUF_Thread(params: PFPUF_ThreadRec); stdcall;
begin
 try
   params.result := IsProcessUsingFile(params.pid, params.f);
   params.err := "";
 except
   params.result := false;
   params.err := "Error";
 end;
end;

function FindProcessesUsingFile(f: THandle): TLongWordDynArray;
var
 i: integer;
 pids: TLongWordDynArray;
 pid: cardinal;
 ignore: cardinal;
 ht: cardinal;
 ThreadRec: array of TFPUF_ThreadRec;
 threads: array of cardinal;
 time: cardinal;
 done: boolean;
begin
 pids := GetProcessList;
 setlength(ThreadRec, length(pids));
 for i := 0 to high(pids) do begin
   ThreadRec[i].pid := pids[i];
   ThreadRec[i].f := f;
   ht := CreateThread(nil, 0, @FPUF_Thread, @ThreadRec[i], 0, ignore);
   threads := PushEl(threads, ht);
 end;
 time := GetTickCount;
 repeat
   done := true;
   for i := 0 to high(threads) do
     if threads[i] <> 0 then begin
       if not ThreadStillActive(threads[i]) then begin
         threads[i] := 0;
         if ThreadRec[i].result then
           result := PushEl(result, ThreadRec[i].pid);
       end;
       done := false;
     end;
   Application.ProcessMessages;
   Sleep(100);
 until done;
end;

type
 TPIDComment = record
   pid: dword;
   comment: string;
 end;
 TPIDsComments = array of TPIDComment;

function FindProcessesUsingFileEx(f: THandle): TPIDsComments;
var
 i: integer;
 pids: TLongWordDynArray;
 pid: cardinal;
 ignore: cardinal;
 ht: cardinal;
 ThreadRec: array of TFPUF_ThreadRec;
 threads: array of cardinal;
 time: cardinal;
 done: boolean;
{ ex }
 pidcmnt: TPidComment;
begin
 pids := GetProcessList;
 setlength(ThreadRec, length(pids));
 for i := 0 to high(pids) do begin
   ThreadRec[i].pid := pids[i];
   ThreadRec[i].f := f;
   ht := CreateThread(nil, 0, @FPUF_Thread, @ThreadRec[i], 0, ignore);
   threads := PushEl(threads, ht);
 end;
 time := GetTickCount;
 repeat
   done := true;
   for i := 0 to high(threads) do
     if threads[i] <> 0 then begin
       if not ThreadStillActive(threads[i]) then begin
         threads[i] := 0;
         if ThreadRec[i].result then begin
           pidcmnt.pid := ThreadRec[i].pid;
           pidcmnt.comment := "";
           result := PushEl(result, pidcmnt);
         end else if ThreadRec[i].err <> "" then begin
           pidcmnt.pid := ThreadRec[i].pid;
           pidcmnt.comment := ThreadRec[i].err;
           result := PushEl(result, pidcmnt);
         end;
         continue;
       end;
       done := false;
     end;
   Application.ProcessMessages;
   Sleep(100);
 until done or (GetTickCount-time > length(pids)*500);
 if not done then
   for i := 0 to high(threads) do
     if not ThreadStillActive(threads[i]) then
       TerminateThread(threads[i], 0);
end;


 
ors_archangel ©   (2007-01-18 20:33) [6]

Вторая часть - менее важная:

procedure TMainForm.Button1Click(Sender: TObject);
var
 fname: string;
 f: THandle;
 finfo: TByHandleFileInformation;
 pids: TPIDsComments;
 i: integer;
begin
 ClientHeight := Button1.BoundsRect.Bottom + 5;
 fname := FileEdit1.FileName;
 f := CreateFile(PChar(fname), 0,
     0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
 try
   ClientHeight := Button3.BoundsRect.Bottom + 5;
   PListBox.Clear;
   Application.ProcessMessages;
   pids := FindProcessesUsingFileEx(f);
   if pids <> nil then begin
     for i := 0 to high(pids) do with pids[i] do begin
       PListBox.Items.Add(IntToStr(pid)+" ("+IntToHex(pid, 8)+"h) "+comment);
     end;
   end else begin
     MsgBox("Not found");
     ClientHeight := Button1.BoundsRect.Bottom + 5;      
   end;
 finally
   CloseHandle(f);
 end;
end;

Используются некоторые нестандартные функции, так что нужно подкручивать. Очень краткое описание: создаём в каждом (!) процессе системы удалённую нить, которая переберает в буквальном смысле возможные handle для нашего файла, который идентифицируется TByHandleFileInformation.


 
Leonid Troyanovsky ©   (2007-01-20 12:40) [7]


> ors_archangel ©   (18.01.07 20:33) [5]

> Сам написал, может не работь, а если работает, то долго :)

http://rsdn.ru/Forum/Message.aspx?mid=314506&only=1

--
Regards, LVT.



Страницы: 1 вся ветка

Текущий архив: 2007.03.18;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.05 c
15-1172356977
@!!ex
2007-02-25 01:42
2007.03.18
Столкновение двух машин.


3-1166496638
NigthSkif
2006-12-19 05:50
2007.03.18
Выполнение процедуры


2-1172069051
dmdel
2007-02-21 17:44
2007.03.18
Безопасность в FB


15-1172341327
Ricky
2007-02-24 21:22
2007.03.18
BSOD - помогите избавится


15-1172269747
Германн
2007-02-24 01:29
2007.03.18
Справка в BDS2006