Entwickler-Ecke
Dateizugriff - Löschen einer Datei auch wenn Sie geöffnet ist!!
Freeman1982 - Sa 02.04.05 20:43
Titel: Löschen einer Datei auch wenn Sie geöffnet ist!!
Hallo,
hBe eine Datei z.B Artikel.dat in der verschiedene daten gespeicht werden und geladen werden. Gib es ein Befehl wo datei löscht auch wenn das Programm noch darauf zugreifft. Oder Sie noch offfen ist??
MfG
Freeman 1982
MSCH - So 03.04.05 20:01
nein, die Sperrung führt das BS für dich durch. Es gibt keine (mir bekannte) Möglichkeit, eine geöffnete Datei on the fly zu löschen. Desgleichen trifft für Dateien die Anwendungen sind und grad laufen zu.
grez
msch
Delete - So 03.04.05 20:04
Autsch. Was würdest du dazu sagen, wenn eine andere Anwendung dir den Teppich unter den Füßen wegzieht? :roll:
MSCH - So 03.04.05 20:06
würde mich interessieren, wie diese dass schafft, meine laufende Anwendung zu löschen.
grez
msch
MSCH - So 03.04.05 20:36
jeap grosser mist, hihi, ein sich selbst ständig wiederholender Löschversuch.
Nett, wenn die CPU Auslastung auch noch voll ausschlägt. :-)
Selbst windows himself brauch für sowas einen neustart um geöffnete Dateien zu überschreiben.
grez
msch
MSCH - Mo 04.04.05 16:50
hallo, ich sagte laufende Anwendung!!!
Das geht nicht.
grez
msch
Sprint - Mo 04.04.05 18:46
MSCH hat folgendes geschrieben: |
hallo, ich sagte laufende Anwendung!!!
Das geht nicht. |
Link hab ich dir gepostet. Lesen musst du schon alleine.
MSCH - Di 05.04.05 16:10
wer lesen kann ist klar im Vorteil:
solche Sachen wie:
Quelltext
1: 2: 3: 4: 5:
| :Repeat del "C:\MYDIR\MYPROG.EXE" if exist "MYPROG.EXE" goto Repeat rmdir "C:\MYDIR" del "\DelUS.bat" |
löschen keine laufende Anwendung sondern versuchen dies, bis die Anwendung geschlossen ist, immer wieder.
Quelltext
1: 2: 3:
| BOOL MoveFileEx(LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName, DWORD dwFlags); This API call moves a file to a new location. When you pass NULL as the second parameter, this causes the file to be moved "nowhere", effectively deleting the file. Now, ordinarily this would fail if you tried this with the path to the current executable. However, if we specify MOVEFILE_DELAY_UNTIL_REBOOT in the dwFlags parameter, this tells Windows not to move (or delete) the file until the system is shutdown or rebooted. |
auch so ein "trick". Der nichts weiter macht, als beim nächsten Booten die Datei zu löschen - auch da darf sie nicht offen sein.
ES gibt keine Methode, nur pseudoanweisungen die sich nicht auf geöffnete Dateien beziehen.
grez
msch
Sprint - Di 05.04.05 21:40
MSCH hat folgendes geschrieben: |
| ES gibt keine Methode, nur pseudoanweisungen die sich nicht auf geöffnete Dateien beziehen. |
Warum hast du den Artikel nicht bis zum Ende gelesen?
opfer.der.genauigkeit - Di 05.04.05 22:16
Sprint hat folgendes geschrieben: |
MSCH hat folgendes geschrieben: | | ES gibt keine Methode, nur pseudoanweisungen die sich nicht auf geöffnete Dateien beziehen. |
Warum hast du den Artikel nicht bis zum Ende gelesen? |
MSCH meinte ja auch, daß es bei
geöffneten Dateien nicht geht.
Ich habe mal das Tutorial durchgelesen und überall wird der entsprechende
Prozess erst geschlossen, bevor die Binary gelöscht wird.
Macht auch Sinn und anders wirst du es auch nicht hinbekommen es sei denn, du machst
dir ernsthaft die Mühe und holst dir alle Beziehungen, die das Programm am Laufen
hat und löschst sie direkt, aber die Fehlermeldungen, möcht ich nicht lesen müßen. :mrgreen:
Vor allem, wie erklärst du das dem BS, bin mir nicht sicher ob es selbstständig merkt,
daß das von ihm geschütze Programm sich "auflöst". ;)
Es geht alles irgendwie.. Lazarus z.B. kann sich selbst Kompilieren.
Also die laufende IDE kompiliert sich selbst.. geht auch nur über einen Trick,
da Windows sowas nicht zuläßt.
//Edit: Eine interessante Variante, die mir grad eingefallen ist, wäre es ja
ein externes Deleteprogramm zu starten, daß nur in den Arbeitsspeicher geladen wird.
Das Deleteprogramm beendet das Hauptprogramm (aus dem es gestartet wurde) und löscht es. Danach beendet sich das Deleteprogramm. Wenn ich richtig liege, müßte es dann im Arbeitsspeicher als tot gelten und somit entweder vom nächsten Prozess, der geladen wird überschrieben werden oder das BS löscht es sofort.
Bin aber absolut nicht sicher, was mit dem Deleteprog. passiert. :dance:
uall@ogc - Di 05.04.05 22:51
@opfer.der.genauigkeit
genau das macht die letzte methode die in dem link von Sprint beschrieben wird
man müsste die doch theoretisch in der dateizuordnungtabelle löschen können oder net?
opfer.der.genauigkeit - Di 05.04.05 22:54
uall@ogc hat folgendes geschrieben: |
@opfer.der.genauigkeit
genau das macht die letzte methode die in dem link von Sprint beschrieben wird
|
Ja? Ok, dann hab ich auch nicht genau hingesehen. :roll:
uall@ogc hat folgendes geschrieben: |
man müsste die doch theoretisch in der dateizuordnungtabelle löschen können oder net?
|
Nicht nur theoretisch, aber wie weit will man denn für so ein Programm auf die Systemebene gehen?
Wobei ich mich frage, ob das nicht auch wieder nur ne unbekannte Anzahl von Fehlermeldungen ausgibt?
//Edit: letzter Satz bezieht sich natürlich auf Änderungen während das Programm läuft.
florian - Di 17.01.06 16:04
Hallo,
ist es möglich, das letzte Beispiel auch mit Delphi zu realisieren? Ich bin leider etwas eingerostet, weshalb ich sehr dankbar wäre, wenn mir einer mal unter die Arme greift! :)
Danke schonmal!
Gruß
Florian
F34r0fTh3D4rk - Di 17.01.06 16:45
das hier ?
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
| #include <windows.h>
#pragma comment(linker, "-export:CleanupA=_CleanupA@16")
extern "C" void CALLBACK CleanupA(HWND, HINSTANCE, PSTR, int) { static MEMORY_BASIC_INFORMATION mbi; VirtualQuery(&mbi, &mbi, sizeof mbi); PVOID module = mbi.AllocationBase;
CHAR buf[MAX_PATH]; GetModuleFileName(HMODULE(module), buf, sizeof buf);
__asm { lea eax, buf push 0 push 0 push eax push ExitProcess push module push DeleteFile push FreeLibrary ret } } |
florian - Di 17.01.06 21:15
nein, ich meine das hier:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159:
| #include <windows.h> #include <tchar.h>
#pragma pack(push, 1)
#define CODESIZE 0x200
typedef struct _SELFDEL { struct _SELFDEL *Arg0; BYTE opCodes[CODESIZE]; HANDLE hParent; FARPROC fnWaitForSingleObject; FARPROC fnCloseHandle; FARPROC fnDeleteFile; FARPROC fnSleep; FARPROC fnExitProcess; FARPROC fnRemoveDirectory; FARPROC fnGetLastError;
BOOL fRemDir;
TCHAR szFileName[MAX_PATH]; } SELFDEL;
#pragma pack(pop)
#ifdef _DEBUG #define FUNC_ADDR(func) (PVOID)(*(DWORD *)((BYTE *)func + 1) + (DWORD)((BYTE *)func + 5)) #else #define FUNC_ADDR(func) func #endif
static void remote_thread(SELFDEL *remote) { remote->fnWaitForSingleObject(remote->hParent, INFINITE); remote->fnCloseHandle(remote->hParent);
while(!remote->fnDeleteFile(remote->szFileName)) { remote->fnSleep(1000); }
remote->fnExitProcess(0); }
BOOL SelfDelete(BOOL fRemoveDirectory) { STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi;
CONTEXT context; DWORD oldProt; SELFDEL local; DWORD entrypoint;
TCHAR szExe[MAX_PATH] = _T("explorer.exe");
if(CreateProcess(0, szExe, 0, 0, 0, CREATE_SUSPENDED|IDLE_PRIORITY_CLASS, 0, 0, &si, &pi)) { local.fnWaitForSingleObject = (FARPROC)WaitForSingleObject; local.fnCloseHandle = (FARPROC)CloseHandle; local.fnDeleteFile = (FARPROC)DeleteFile; local.fnSleep = (FARPROC)Sleep; local.fnExitProcess = (FARPROC)ExitProcess; local.fnRemoveDirectory = (FARPROC)RemoveDirectory; local.fnGetLastError = (FARPROC)GetLastError;
local.fRemDir = fRemoveDirectory;
DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), pi.hProcess, &local.hParent, 0, FALSE, 0);
GetModuleFileName(0, local.szFileName, MAX_PATH);
memcpy(local.opCodes, FUNC_ADDR(remote_thread), CODESIZE);
context.ContextFlags = CONTEXT_INTEGER|CONTEXT_CONTROL; GetThreadContext(pi.hThread, &context);
entrypoint = (context.Esp - sizeof(SELFDEL)) & ~0x1F; local.Arg0 = (SELFDEL *)entrypoint;
context.Esp = entrypoint - 4; context.Eip = entrypoint + 4; VirtualProtectEx(pi.hProcess, (PVOID)entrypoint, sizeof(local), PAGE_EXECUTE_READWRITE, &oldProt); WriteProcessMemory(pi.hProcess, (PVOID)entrypoint, &local, sizeof(local), 0);
FlushInstructionCache(pi.hProcess, (PVOID)entrypoint, sizeof(local));
SetThreadContext(pi.hThread, &context);
ResumeThread(pi.hThread); CloseHandle(pi.hThread); CloseHandle(pi.hProcess);
return TRUE; }
return FALSE; }
int main(void) { SelfDelete(TRUE); return 0; } |
Gruß
Florian
galagher - Di 17.01.06 21:19
Man müsste Windows vorgaukeln, dass das zu löschenden Programm nicht geöffnet ist, selbst, wenn es das ist. Oder, auch möglich, man versetzt es von aussen in einen Zustand, der dem "Hängen" eines Programmes entspricht. Windows wird bemerken, dass das Program nicht reagiert und wird es beenden bzw. zumindest einen Dialog öffnen, damit der User es beendet. Dann kann man es auch löschen.
Bleibt nur noch eine lästige Kleinigkeit: Wie? :mrgreen:
Coder - Di 17.01.06 22:44
Er will doch eine Datei löschen?
Da gibt es doch beim Öffnen mit einem Stream einen Parameter mit dem man IMHO auch steuern kann das andere Programme schreibrechte haben.
galagher - Di 17.01.06 23:10
Coder hat folgendes geschrieben: |
| Er will doch eine Datei löschen? |
Ja. Sorry!
wolke - Di 17.01.06 23:58
hallo?
habt ihr auch verstanden was die letzte methode macht?
auch die löscht die datei natürlich erst, nachdem der prozess beendet wurde.
| Zitat: |
- The injected code waits for the parent-process to exit.
- The parent-process is then deleted. |
das einzige was natürlih (von aussen) möglich ist: feststellen wer die datei nutzt, diesen aus dem speicher werfen (freundlich oder unfreundlich), um dann die datei zu löschen.
uall@ogc - Mi 18.01.06 18:28
Hab hier mal was gemacht, womit man keine Batch Dateien braucht.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113:
| procedure AsmBegin; asm NOP NOP NOP PUSH $64 CALL DWORD PTR [$00000000] PUSH DWORD PTR [$00000018] PUSH 0 PUSH PROCESS_ALL_ACCESS CALL DWORD PTR [$00000004] TEST EAX, EAX JZ @@Terminated PUSH EAX CALL DWORD PTR [$00000008] TEST EAX, EAX POP EAX CALL DWORD PTR [$0000000C] PUSH 1000 CALL DWORD PTR [$00000000] @@Terminated: PUSH [$0000001C] CALL [$00000010] PUSH 0 CALL [$00000014] RET end; procedure AsmEnd; asm end;
procedure CloseAndDeleteMe; var pTempMem: Pointer; pTargetMem: Pointer; sFile: String; dwMemSize: DWord; dwAsmSize: DWord; lpStartupInfo: TStartupInfo; lpProcessInformation: TProcessInformation;
pSleep: Pointer; pOpenProcess: Pointer; pTerminateProcess: Pointer; pCloseHandle: Pointer; pDeleteFileA: Pointer; pExitProcess: Pointer;
dwKernelHandle: DWord; dwBytesWritten: DWord; dwThreadID: DWord; begin dwKernelHandle := GetModuleHandle('kernel32.dll');
pSleep := GetProcAddress(dwKernelHandle,'Sleep'); pOpenProcess := GetProcAddress(dwKernelHandle,'OpenProcess'); pTerminateProcess := GetProcAddress(dwKernelHandle,'TerminateProcess'); pCloseHandle := GetProcAddress(dwKernelHandle,'CloseHandle'); pDeleteFileA := GetProcAddress(dwKernelHandle,'DeleteFileA'); pExitProcess := GetProcAddress(dwKernelHandle,'ExitProcess');
sFile := Paramstr(0);
dwAsmSize := DWord(@AsmEnd)-DWord(@AsmBegin); dwMemSize := dwAsmSize+DWord(Length(sFile))+1+$20*Sizeof(DWord); ZeroMemory(@lpStartupInfo,SizeOf(lpStartupInfo)); lpStartupInfo.cb := SizeOf(lpStartupInfo); if CreateProcessA(nil,'explorer',nil,nil,false,CREATE_SUSPENDED,nil, nil,lpStartupInfo,lpProcessInformation) then begin pTempMem := VirtualAlloc(nil,dwMemSize,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE); if (pTempMem = nil) then Exit; pTargetMem := VirtualAllocEx(lpProcessInformation.hProcess,nil,dwMemSize,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE); if (pTargetMem = nil) then begin VirtualFree(pTempMem,dwMemSize,MEM_RELEASE); Exit; end; CopyMemory(pTempMem,@AsmBegin,dwAsmSize); CopyMemory(Pointer(DWord(pTempMem)+$20+dwAsmSize),@sFile[1],Length(sFile));
PPointer(DWord(pTempMem)+dwAsmSize+$00)^ := pSleep; PPointer(DWord(pTempMem)+dwAsmSize+$04)^ := pOpenProcess; PPointer(DWord(pTempMem)+dwAsmSize+$08)^ := pTerminateProcess; PPointer(DWord(pTempMem)+dwAsmSize+$0C)^ := pCloseHandle; PPointer(DWord(pTempMem)+dwAsmSize+$10)^ := pDeleteFileA; PPointer(DWord(pTempMem)+dwAsmSize+$14)^ := pExitProcess; PDWord(DWord(pTempMem)+dwAsmSize+$18)^ := GetCurrentProcessID; PDWord(DWord(pTempMem)+dwAsmSize+$1C)^ := DWord(pTargetMem)+dwAsmSize+$20;
PDWord(DWord(pTempMem)+07)^ := DWord(pTargetMem)+dwAsmSize+$00; PDWord(DWord(pTempMem)+26)^ := DWord(pTargetMem)+dwAsmSize+$04; PDWord(DWord(pTempMem)+37)^ := DWord(pTargetMem)+dwAsmSize+$08; PDWord(DWord(pTempMem)+46)^ := DWord(pTargetMem)+dwAsmSize+$0C; PDWord(DWord(pTempMem)+57)^ := DWord(pTargetMem)+dwAsmSize+$00; PDWord(DWord(pTempMem)+69)^ := DWord(pTargetMem)+dwAsmSize+$10; PDWord(DWord(pTempMem)+77)^ := DWord(pTargetMem)+dwAsmSize+$14;
PDWord(DWord(pTempMem)+13)^ := DWord(pTargetMem)+dwAsmSize+$18; PDWord(DWord(pTempMem)+63)^ := DWord(pTargetMem)+dwAsmSize+$1C;
if WriteProcessMemory(lpProcessInformation.hProcess,pTargetMem,pTempMem,dwMemSize,dwBytesWritten) and (dwBytesWritten = dwMemSize) then CreateRemoteThread(lpProcessInformation.hProcess,nil,0,pTargetMem,nil,0,dwThreadID); ExitProcess(0); end; end;
procedure TForm1.Button1Click(Sender: TObject); begin CloseAndDeleteMe; end; |
florian - Mo 23.01.06 08:27
Danke, werde das daheim dann gleich mal ausprobieren. :)
AXMD - Mo 23.01.06 09:38
Reicht es nicht, dem Prozess, dem die Datei gehört, einfach das entsprechende Handle wegzunehmen? Process Explorer ([url]
http://www.sysinternals.com[/url]) macht das IIRC so - hab aber keine Ahnung wie.
AXMD
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!