![]() |
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:55 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