Wer sehr viel mit Windows arbeitet, hat bestimmt schon mal die Erfahrung gemacht, auf eine Datei zu stoßen, die vollkommen blockiert ist.
Sie lässt sich nicht verändern oder löschen und sogar nicht kopieren.
Wohl möglich, dass der User des Systems nicht der Inhaber dieser Datei ist und der eigentliche Inhaber jeglichen Zugriff auf diese Datei verweigert.
Das ist auf dem Windows-System möglich, denn selbst Microsoft hat Dateien, die für jeden User tabu sind.
Aber auch diese Dateien lassen sich vollkommen vom System trennen und den Zugriff ermöglichen.
Der folgende Code zeigt wie..
uses ShellApi, ComCtrls, tlHelp32
public
procedure WMDropFiles(var Msg: Tmessage); message WM_DROPFILES;
type
NTStatus = cardinal;
CONST
STATUS_SUCCESS = NTStatus($00000000);
STATUS_ACCESS_DENIED = NTStatus($C0000022);
STATUS_INFO_LENGTH_MISMATCH = NTStatus($C0000004);
SEVERITY_ERROR = NTStatus($C0000000);
ObjectNameInformation = 1;
type
PSYSTEM_HANDLE_INFORMATION = ^SYSTEM_HANDLE_INFORMATION;
SYSTEM_HANDLE_INFORMATION = packed record
ProcessId: dword;
ObjectTypeNumber: byte;
Flags: byte;
Handle: word;
pObject: pointer;
GrantedAccess: dword;
end;
PSYSTEM_HANDLE_INFORMATION_EX = ^SYSTEM_HANDLE_INFORMATION_EX;
SYSTEM_HANDLE_INFORMATION_EX = packed record
NumberOfHandles: dword;
Information: array [0 .. 0] of SYSTEM_HANDLE_INFORMATION;
end;
type
UNICODE_STRING = packed record
Length: word;
MaximumLength: word;
Buffer: PWideChar;
end;
type
OBJECT_NAME_INFORMATION = record
Name: UNICODE_STRING;
end;
PIO_STATUS_BLOCK = ^IO_STATUS_BLOCK;
IO_STATUS_BLOCK = packed record
Status: NTStatus;
Information: dword;
end;
PFILE_NAME_INFORMATION = ^FILE_NAME_INFORMATION;
FILE_NAME_INFORMATION = packed record
FileNameLength: ULONG;
FileName: array [0 .. MAX_PATH - 1] of WideChar;
end;
type
TInject = record
del: pointer;
FileName: dword;
end;
function NtQueryInformationFile(FileHandle: THandle;
IoStatusBlock: PIO_STATUS_BLOCK; FileInformation: pointer; Length: dword;
FileInformationClass: dword): NTStatus; stdcall; external 'ntdll.dll';
Function NtQuerySystemInformation(ASystemInformationClass: dword;
ASystemInformation: pointer; ASystemInformationLength: dword;
AReturnLength: PCardinal): NTStatus; stdcall; external 'ntdll.dll';
function NtQueryObject(ObjectHandle, ObjectInformationClass: Integer;
ObjectInformation: pointer; Length: Integer; var ResultLength: Integer)
: Integer; stdcall; external 'ntdll.dll';
//
function InjectedCode(param: pointer): dword; stdcall;
var
injected: TInject;
begin
injected := TInject(param^);
asm
push injected.filename;
call injected.del;
end;
Result := 0;
end;
procedure code_end;
begin
end;
procedure Unlock(PI: dword; hnd: dword);
var
trad, mdh, task: THandle;
dwCodeSize: dword;
thead, btwn: dword;
InjData: TInject;
injdataaddr, writeaddr: pointer;
begin
dwCodeSize := dword(@code_end) - dword(@InjectedCode);
task := OpenProcess(PROCESS_ALL_ACCESS, false, PI);
if task <> 0 then
begin
mdh := GetModuleHandle('kernel32.dll');
InjData.del := GetProcAddress(mdh, 'CloseHandle');
InjData.FileName := hnd;
injdataaddr := VirtualAllocEx(task, nil, SizeOf(InjData), MEM_COMMIT,
PAGE_READWRITE);
WriteProcessMemory(task, injdataaddr, @InjData, SizeOf(InjData), btwn);
writeaddr := VirtualAllocEx(task, nil, dwCodeSize, MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
WriteProcessMemory(task, writeaddr, @InjectedCode, dwCodeSize, btwn);
trad := CreateRemoteThread(task, nil, 0, writeaddr, injdataaddr, 0, thead);
if trad <> 0 then
ShowMessage('UNBLOCK!')
else
ShowMessage('Error :(');
end;
end;
function GetHandleTable: pointer;
var
memal: pointer;
res: cardinal;
sz: dword;
actualsize: dword;
begin
sz := $400;
memal := VirtualAlloc(nil, sz, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
NtQuerySystemInformation(16, memal, sz, @actualsize);
VirtualFree(memal, sz, MEM_RELEASE);
sz := actualsize;
memal := VirtualAlloc(nil, sz, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
res := NtQuerySystemInformation(16, memal, sz, @actualsize);
if res = STATUS_SUCCESS then
Result := memal
else
Result := nil;
end;
function GetFileNameFromHandle(const hFile: THandle): string;
var
IO_STATUSBLOCK: IO_STATUS_BLOCK;
FileNameInfo: FILE_NAME_INFORMATION;
szFile: String;
begin
FillChar(FileNameInfo.FileName, SizeOf(FileNameInfo.FileName), 0);
NtQueryInformationFile(hFile, @IO_STATUSBLOCK, @FileNameInfo, 500, 9);
szFile := WideCharToString(FileNameInfo.FileName);
Result := szFile;
end;
function GetNameFromPID(PID: dword): String;
var
PE32: TProcessEntry32;
snap: THandle;
res: String;
begin
PE32.dwSize := SizeOf(PE32);
snap := CreateToolHelp32SnapShot(TH32CS_SNAPALL, 0);
Process32First(snap, PE32);
repeat
if PE32.th32ProcessID = PID then
res := PE32.szExeFile;
until
Process32Next(snap, PE32) = false;
Result := res;
end;
procedure ListPids(srch: String);
var
HandlesInfo: PSYSTEM_HANDLE_INFORMATION_EX;
i: Integer;
tmpHandle, phand, myHandle: THandle;
szFl: String;
lstItem: TListItem;
begin
HandlesInfo := GetHandleTable;
if HandlesInfo = nil then
exit;
for i := 0 to HandlesInfo^.NumberOfHandles - 1 do
if HandlesInfo^.Information[i].ObjectTypeNumber = 28 then
begin
tmpHandle := HandlesInfo^.Information[i].Handle;
phand := OpenProcess(PROCESS_DUP_HANDLE, false,
HandlesInfo^.Information[i].ProcessId);
if phand <> 0 then
begin
DuplicateHandle(phand, tmpHandle, GetCurrentProcess, @myHandle, 0,
false, DUPLICATE_SAME_ACCESS);
szFl := GetFileNameFromHandle(myHandle);
if pos(srch, LowerCase(szFl)) > 0 then
begin
lstItem := Form1.ListView1.Items.Add;
lstItem.Caption := IntToStr(HandlesInfo^.Information[i].ProcessId);
lstItem.SubItems.Add
(GetNameFromPID(HandlesInfo^.Information[i].ProcessId));
lstItem.SubItems.Add(IntToStr(HandlesInfo^.Information[i].Handle));
end;
CloseHandle(myHandle);
end;
end;
if Form1.ListView1.Items.Count = 0 then
begin
lstItem := Form1.ListView1.Items.Add;
lstItem.Caption := ' - ';
lstItem.SubItems.Add(' - ');
lstItem.SubItems.Add(' - ');
end;
end;
procedure TForm1.WMDropFiles(var Msg: Tmessage);
var
buf: array [0 .. 255] of char;
szF: String;
icon: TIcon;
icoindex: word;
begin
ListView1.Items.Clear;
DragQueryFile(THandle(Msg.WParam), 0, @buf, SizeOf(buf));
szF := buf;
Edit1.Text := szF;
icon := TIcon.Create;
icoindex := 0;
icon.Handle := ExtractAssociatedIcon(Handle, Pchar(szF), icoindex);
Image1.Picture.icon.Handle := icon.Handle;
ListPids(ExtractFileName(LowerCase(szF)));
DragFinish(THandle(Msg.WParam));
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
DragAcceptFiles(Handle, true);
end;
procedure term(dwPI: dword);
var
ph: THandle;
begin
ph := OpenProcess(PROCESS_TERMINATE, false, dwPI);
if TerminateProcess(ph, 0) = true then
ShowMessage('Procesul :' + IntToStr(dwPI) + ' TERMINATE!')
else
ShowMessage('ERROR :(');
end;
Prozess Terminieren :
procedure TForm1.SpeedButton4Click(Sender: TObject);
var
i: Integer;
PID: dword;
begin
for i := 0 to ListView1.Items.Count - 1 do
begin
try
PID := StrToInt(ListView1.Items.Item[i].Caption);
term(PID);
except
MessageDlg('You have no reason to unlocked', mtError, [mbOk], 0);
end;
end;
end;
Blockade aufheben :
procedure TForm1.SpeedButton2Click(Sender: TObject);
var
i: Integer;
PID: dword;
target: THandle;
begin
for i := 0 to ListView1.Items.Count - 1 do
begin
try
PID := StrToInt(ListView1.Items.Item[i].Caption);
target := StrToInt(ListView1.Items.Item[i].SubItems[1]);
Unlock(PID, target);
except
MessageDlg('You have no reason to unlocked', mtError, [mbOk], 0);
end;
end;
end;
Datei löschen :
procedure TForm1.SpeedButton3Click(Sender: TObject);
var
i: Integer;
PID: dword;
target: THandle;
begin
for i := 0 to ListView1.Items.Count - 1 do
begin
try
PID := StrToInt(ListView1.Items.Item[i].Caption);
target := StrToInt(ListView1.Items.Item[i].SubItems[1]);
Unlock(PID, target);
Sleep(100);
DeleteFile(Edit1.Text);
except
MessageDlg('You have no reason to unlocked', mtError, [mbOk], 0);
end;
end;
end;
Fazit :Man sollte vorsichtig sein und genau wissen, ob es sich um eine Systemdatei handelt, um nicht einen System-Crash zu verursachen.
Keine Kommentare:
Kommentar veröffentlichen