![]() |
Alle Resourcen aus fremder EXE richtig entfernen
Hi,
wie kann ich alle Resourcen eiener fremden EXE Datei entfernen? Mittels BeginUpdateResource(Filename, true) geht dies zwar, allerdings ist die Datei noch genau so groß wie vorher, wenn auch die Resourcen nicht mehr da sind. Kann man irgendwie die komplette Resourcen Section entfernen oder sowas? Florian |
Re: Alle Resourcen aus fremder EXE richtig entfernen
*push*
|
Re: Alle Resourcen aus fremder EXE richtig entfernen
Downloade dir madshi's madRes herunter (ist OpenSource) und dann benutze folgendenen Code um eine Resource aus der Anwendung zu löschen.
Delphi-Quellcode:
var
hUpdate: THandle; begin hUpdate := madres.BeginUpdateResourceW(PWideChar(WideString(sFilename)), False); if hUpdate <> INVALID_HANDLE_VALUE then begin madres.UpdateResourceW(hUpdate, 'TYP', 'NAME', 0, nil, 0); madres.EndUpdateResourceW(hUpdate, False); end; |
Re: Alle Resourcen aus fremder EXE richtig entfernen
Ah vielen Dank, das geht wunderbar! :thumb:
|
Re: Alle Resourcen aus fremder EXE richtig entfernen
Mh wie mache ich es, dass alle Resourcen einer Datei entfernt werden. Ich liste die auf mit EnumResourceNames. Allerdings wird dort ein PChar Wert übergeben und kein PWideChar. Zudem kann der PChar ein Pointer auf einen Integer aber auch auf einen String Wert sein ..
|
Re: Alle Resourcen aus fremder EXE richtig entfernen
schaue dir das Beispiel weiter unten an, das habe ich einmal gemacht um alle Icons zu extrahieren, hat auch mit Namen und Nummern funktioniert, sollte nicht schwer sein das umzuschreiben.
![]() |
Re: Alle Resourcen aus fremder EXE richtig entfernen
Florian, um sie zu entfernen, musst du selbstverfreilich die PE-Datei selber modifizieren. Lies dich dazu in den entsprechenden Dokus von MS und Luevelsmeyer erstmal schlau. Danach musst du entscheiden, ob du die Ressourcen nur ausnullen oder wirklich entfernen willst (letzteres ist zu empfehlen). Was unter Umstaenden bedeutet, dass du Sektionen der PE verschieben und RVAs anpassen musst usw. Alles in allem absolut nicht trivial.
Die entsprechenden "Update"-Funktionen existieren nur fuer NT und, soweit ich mich entsinne, erlauben auch nur das ausnullen, wenn man Ressourcen entfernen will. |
Re: Alle Resourcen aus fremder EXE richtig entfernen
Ah mist .. ist wohl zu kompliziert, dafür, dass ich das ohne Beispielcode hinbekommen würde .. und die Update Funktionen tun wirklich nur ausnullen.
Die aus der madRes bekommen es sogar hin, dass einige z.B. RCDATA richtig entfernt werden, aber auch nciht alle. @ErazerZ: So mach ichs auch, nur will mein Code nicht recht, warum weiß ich leider auch nicht. |
Re: Alle Resourcen aus fremder EXE richtig entfernen
Zitat:
|
Re: Alle Resourcen aus fremder EXE richtig entfernen
Aufgeben nicht, nein .. allerdings habe ich z.B. einen Beispielcode gefunden, wie man die .reloc Section entfernen kann. Allerdings scheint dies recht kompliziert, zumal es zu Fehlern im Programm kommt, wenn man einfach die .rsrc Section komplett tilgt.
|
Re: Alle Resourcen aus fremder EXE richtig entfernen
Zitat:
|
Re: Alle Resourcen aus fremder EXE richtig entfernen
Ich kann morgen ein Beispiel dazu machen, mal schauen ob ich weiter komme, aber wenn es überhaupt nicht geht (sollte eigentlich, weil madRes auch die Sektionen löscht) kannst du die Anwendung im Speicher laden, NtHeaders auslesen, danach den FileOffset von der Resourcen Sektion und die größe auslesen (ist alles in DataDirectory/RVA) und danach mit einer funktion von dem FileOffset bis zum FileOffset + Größe ausschneiden (ich habe bereits eine Funktion länger her gemacht um Dateien auszuschneiden, funktioniert sowie Delete jedoch mit Dateien), danach kommts erst die schwere Arbeit, du musst danach alle nachfolgenden Sektionen anpassen und du musst auf FileAlign achten, auf alles achten, das ist eine menge Arbeit. Und ob die Anwendung noch überhaupt funktioniert wenns einfach so die Resourcensektion löscht.
|
Re: Alle Resourcen aus fremder EXE richtig entfernen
Irgendwas rausgefunden?
|
Re: Alle Resourcen aus fremder EXE richtig entfernen
Ja also, ich hab mal heute das gemacht, getestet habe ich es nur mit meinem kleinen nonVCL programm, das einfach einen text aus einer Resource ladet und in einer MessageBox ausgibt. Die funktion die ich gemacht habe, entfernt dabei die ganze Sektionen aus einer PE-Datei. Und hier ist der ganze Code.
Delphi-Quellcode:
Falls irgendjemand irgendwelche Fehler findet oder Verbesserungsvorschläge dann schreibt mir eine mail oder postet es hier!
{
Friday, 2nd February 2007 (15:00 - 22:30) by ErazerZ ( ErazerZ[at]gmail[dot]com ) Music listening while coding: Bishop Lamont Busta Rhymes: The Big Bang Dr. Dre - 2001 Eminem - Marshall Mathers LP } program SectionEraser; uses Windows; function ShellExecute(hWnd: HWND; Operation, FileName, Parameters, Directory: PChar; ShowCmd: Integer): HINST; stdcall; external 'shell32.dll' name 'ShellExecuteA'; function RemoveSection(sFilename: String; wSection: Word): Boolean; function Align(Value, Align: Cardinal): Cardinal; begin if ((Value mod Align) = 0) then Result := Value else Result := ((Value + Align - 1) div Align) * Align; end; function RvaToFileOffset(Address: Cardinal; NtHeaders: PImageNtHeaders): Cardinal; var i: Word; Section: PImageSectionHeader; begin Result := 0; Section := PImageSectionHeader(Cardinal(NtHeaders) + sizeof(TImageNtHeaders)); for i := 0 to NtHeaders^.FileHeader.NumberOfSections -1 do begin if (Address >= Section^.VirtualAddress) and (Address <= Section^.VirtualAddress + Section^.SizeOfRawData) then begin Result := Address - Section^.VirtualAddress + Section^.PointerToRawData; Break; end; Inc(Section); end; end; function FileOffsetToRva(Address: Cardinal; NtHeaders: PImageNtHeaders): Cardinal; var i: Word; Section: PImageSectionHeader; begin Result := 0; Section := PImageSectionHeader(Cardinal(NtHeaders) + sizeof(TImageNtHeaders)); for i := 0 to NtHeaders^.FileHeader.NumberOfSections -1 do begin if (Address >= Section^.PointerToRawData) and (Address <= Section^.PointerToRawData + Section^.SizeOfRawData) then begin Result := Address + Section^.PointerToRawData + Section^.VirtualAddress + NtHeaders^.OptionalHeader.ImageBase; Break; end; Inc(Section); end; end; function CutFile(hFile: THandle; FromOffset, Count: Cardinal): Cardinal; var dwSize, dwCopyFrom, dwCopyLength, lpNumberOfBytesRead: Cardinal; lpBuffer: Pointer; begin Result := Cardinal(-1); if (hFile <> INVALID_HANDLE_VALUE) then begin dwSize := GetFileSize(hFile, nil); if (dwSize > (FromOffset + Count)) then begin dwCopyFrom := FromOffset + Count; dwCopyLength := dwSize - (FromOffset + Count); if dwCopyLength = 0 then begin SetFilePointer(hFile, FromOffset, nil, FILE_BEGIN); SetEndOfFile(hFile); Result := dwSize - Count; end else begin lpBuffer := VirtualAlloc(nil, dwCopyLength, MEM_COMMIT, PAGE_READWRITE); if (lpBuffer <> nil) then begin SetFilePointer(hFile, dwCopyFrom, nil, FILE_BEGIN); ReadFile(hFile, lpBuffer^, dwCopyLength, lpNumberOfBytesRead, nil); if (lpNumberOfBytesRead = dwCopyLength) then begin SetFilePointer(hFile, FromOffset, nil, FILE_BEGIN); SetEndOfFile(hFile); WriteFile(hFile, lpBuffer^, dwCopyLength, lpNumberOfBytesRead, nil); if (lpNumberOfBytesRead = dwCopyLength) then begin VirtualFree(lpBuffer, 0, MEM_RELEASE); Result := dwSize - Count; end; end; end; end; end else begin if (FromOffset < dwSize) then begin SetFilePointer(hFile, FromOffset, nil, FILE_BEGIN); SetEndOfFile(hFile); Result := FromOffset; end; end; end; end; var lpBuffer: Pointer; x: Word; { PE-Stuff } NtHeaders: PImageNtHeaders; Sections: array of TImageSectionHeader; SectionHeader: TImageSectionHeader; SectionOffset, SectionSize, // FileOffset of the Section ... SectionAlign: Cardinal; // Alignment of Section ImageSize: Cardinal; { Datei öffnen und laden } hFile: THandle; FileSize: Cardinal; lpNumberOfBytesWritten, lpNumberOfBytesRead: DWORD; begin Result := False; hFile := CreateFile(PChar(sFilename), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0); FileSize := GetFileSize(hFile, nil); GetMem(lpBuffer, FileSize); ReadFile(hFile, lpBuffer^, FileSize, lpNumberOfBytesRead, nil); if (lpBuffer = nil) then begin DeleteFile(PChar(sFilename)); ExitProcess(0); end; NtHeaders := PImageNtHeaders(Cardinal(lpBuffer) + Cardinal(PImageDosHeader(lpBuffer)._lfanew)); if NtHeaders.Signature <> IMAGE_NT_SIGNATURE then begin DeleteFile(PChar(sFilename)); ExitProcess(0); end else begin if (wSection >= NtHeaders^.FileHeader.NumberOfSections) then begin DeleteFile(PChar(sFilename)); ExitProcess(0); end; // alle TImageSectionHeaders zwischenspeichern (leichter und übersichtlicher) SetLength(Sections, NtHeaders^.FileHeader.NumberOfSections); for x := 0 to NtHeaders^.FileHeader.NumberOfSections -1 do CopyMemory(@Sections[x], Pointer(Cardinal(NtHeaders) + SizeOf(TImageNtHeaders) + (SizeOf(TImageSectionHeader) * x)), SizeOf(TImageSectionHeader)); SectionHeader := Sections[wSection]; SectionOffset := SectionHeader.PointerToRawData; SectionSize := SectionHeader.SizeOfRawData; SectionAlign := NtHeaders^.OptionalHeader.SectionAlignment; if (CutFile(hFile, SectionOffset, SectionSize) <> Cardinal(-1)) then begin // Sektionen die danach sind anpassen, also deren PointerToRawData updaten // es müssen keine berechnungen durchgeführt werden da sowieso bei einer ausführbaren datei alles bereits berechnet ist // wir müssen einfach nur abziehen for x := 0 to wSection -1 do begin Sections[x].Misc.VirtualSize := Align(Sections[x].Misc.VirtualSize, SectionAlign); // Ich weiß es auch nicht warum der aufeinmal so will und nicht anders .. if (x = wSection -1) then Sections[x].Misc.VirtualSize := Align(Sections[x].Misc.VirtualSize + SectionAlign, SectionAlign); SetFilePointer(hFile, PImageDosHeader(lpBuffer)._lfanew + SizeOf(TImageNtHeaders) + (SizeOf(TImageSectionHeader) * x), nil, FILE_BEGIN); WriteFile(hFile, Sections[x], SizeOf(TImageSectionHeader), lpNumberOfBytesWritten, nil); end; // Die danach folgenden Sektionen anpassen, VirtualSize muss nicht geupdated werden, anscheinend .. // nur PointerToRawData updaten, einfach die größe der zu löschendenen Sektion abziehen // wir müssen nichts berechnen weil es bereits vom compiler getan wurde .. for x := wSection +1 to (NtHeaders^.FileHeader.NumberOfSections -1) do begin Sections[x].PointerToRawData := Sections[x].PointerToRawData - SectionSize; SetFilePointer(hFile, PImageDosHeader(lpBuffer)._lfanew + SizeOf(TImageNtHeaders) + (SizeOf(TImageSectionHeader) * (x -1)), nil, FILE_BEGIN); WriteFile(hFile, Sections[x], SizeOf(TImageSectionHeader), lpNumberOfBytesWritten, nil); end; // Directorys müssen nicht abgezogen werden, nur die wenns z.b. Resource ist dann auf 0 setzen for x := 0 to IMAGE_NUMBEROF_DIRECTORY_ENTRIES -1 do begin if (NtHeaders^.OptionalHeader.DataDirectory[x].VirtualAddress <> 0) and (NtHeaders^.OptionalHeader.DataDirectory[x].Size <> 0) then begin if (RvaToFileOffset(NtHeaders^.OptionalHeader.DataDirectory[x].VirtualAddress, NtHeaders) = SectionOffset) then begin NtHeaders^.OptionalHeader.DataDirectory[x].VirtualAddress := 0; NtHeaders^.OptionalHeader.DataDirectory[x].Size := 0; break; end; end; end; // ImageSize anpassen if (NtHeaders^.OptionalHeader.SizeOfHeaders mod SectionAlign = 0) then ImageSize := NtHeaders^.OptionalHeader.SizeOfHeaders else ImageSize := Align(NtHeaders^.OptionalHeader.SizeOfHeaders, SectionAlign); for x := 0 to NtHeaders^.FileHeader.NumberOfSections -1 do begin if (x <> wSection) then begin ImageSize := ImageSize + Align(Sections[x].Misc.VirtualSize, SectionAlign) end; end; NtHeaders^.OptionalHeader.SizeOfImage := ImageSize; Dec(NtHeaders^.FileHeader.NumberOfSections); // NtHeader noch updaten .. SetFilePointer(hFile, PImageDosHeader(lpBuffer)._lfanew, nil, FILE_BEGIN); WriteFile(hFile, NtHeaders^, SizeOf(TImageNtHeaders), lpNumberOfBytesWritten, nil); if (lpNumberOfBytesWritten = SizeOf(TImageNtHeaders)) then Result := True; end; end; CloseHandle(hFile); FreeMem(lpBuffer, FileSize); // Testen ob es läuft .. ShellExecute(0, 'open', PChar(sFilename), nil, nil, SW_SHOWNORMAL); end; function ExtractFilePath(s: string): string; var i: Integer; begin i := Length(s); while ((s[i] <> '\') and (s[i] <> '/')) do if (i > 0) then Dec(i) else Break; if i > 0 then Result := Copy(s, 1, i); end; const SectionToRemove = 6; var sFilename: String; begin sFilename := ExtractFilePath(ParamStr(0)); sFilename := sFilename + 'Resource_Test.exe'; DeleteFile(PChar(sFilename + '_.exe')); CopyFile(PChar(sFilename), PChar(sFilename + '_.exe'), False); sFilename := sFilename + '_.exe'; if not RemoveSection(sFilename, SectionToRemove) then MessageBox(HWND_DESKTOP, 'Die Sektion konnte nicht entfernt werden!', 'Fehler', MB_ICONERROR); end. |
Re: Alle Resourcen aus fremder EXE richtig entfernen
Vielen Dank schonmal .. ich werd mir das schnellstmöglich mal ansehen.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:54 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz