|
Registriert seit: 27. Mai 2005 Ort: Baden 315 Beiträge Delphi 2007 Enterprise |
#14
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. |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |