- Windows’ EXE- und DLL-Dateien haben das selbe Format: Portable Executable (PE).
- PE ist abwärtskompatibel zu MS-DOS. (Bei Microsoft ist immer alles abwärtskompatibel.) Das bedeutet nicht, dass die tatsächlichen Programme auf MS-DOS laufen. Das bedeutet nur, dass MS-DOS moderne EXEs/DLLs lesen und starten kann.
- Um das zu gewährleisten, wird PE tatsächlich in DOS-Executables (MZ) eingebettet. Das kleine MS-DOS-MZ, in das der moderne Code eingebettet wird, nennt sich MS-DOS Stub. Man *kann* es selber definieren, aber üblicherweise wird es von Compiler erzeugt.
- Visual C++ erzeugt einen Stub, der – wird die EXE auf MS-DOS gestartet – den folgenden Text ausgibt und dann das Programm beendet: This program cannot be run in DOS mode.
- Visual C++ kodiert außerdem die verwendete Toolset-Version in das ungenutzte Padding hinter dem MS-DOS-Stub in der PE. Entschlüsselt man das, kann man rekonstruieren, mit welcher Version von Visual C++ die EXE kompiliert wurde.
- Offensichtlich kann man das Stub nicht einfach rausschmeißen, weil die PE in die MZ eingebettet ist, und ohne MZ kann Windows die PE nicht mehr laden. Mann kann es aber minimieren, zu einem leeren Stub.
- Die Linker-Informationen stehen im Padding, und auch das ist nötigerweise da. Man kann es aber nullen.
- herunterladen
- installieren
- CFF Explorer starten
- EXE öffnen
- ganz links „Rebuilder“ auswählen
Nun hat der Entwickler von CFF Explorer in seinem Artikel über den MS-DOS-Stub auch ein Skript für den CFF Explorer bereitgestellt, das das gleiche tut, ohne die Ausrichtung zu überschreiben. Dummerweise löscht es das Debug-Verzeichnis und Strong Name Signature mit. Wenn man das alles rausschmeißt, erhält man:
Code: Alles auswählen
-- updated by Krishty 2018
-- do not remove debug directory (I want that for debugging)
-- do not remove strong name signature
-- fixed file name
-- © 2008 Daniel Pistelli. All rights reserved.
-- Header Pack Script Version: 1.0.0.1
-- This neat little script does the following:
--
-- packs the dos header + PE header + section headers
-- removes useless things like the Rich Signature
-- removes linker references inside the PE header
-- strips the debug information (if any) from the PE
-- if it's a .NET, removes Strong Name Signature
-- updates checksum
-- shows an invalid PE Msgbox
function InvPEMsg()
MsgBox("The current file seems to be an invalid PE. Cannot proceed!",
strScriptName, MB_ICONEXCLAMATION)
end
-- --------------------------------------------------
-- the main code starts here
-- --------------------------------------------------
strScriptName = "Header Pack Script 1.0.0.1 - by Daniel Pistelli"
filename = @"test.exe"
local hPE = OpenFile(filename)
if hPE == null then
MsgBox("Couldn't open file.", "Error", MB_ICONEXCLAMATION)
return
end
local OptHdrOffset = GetOffset(hPE, PE_OptionalHeader)
if OptHdrOffset == null then
InvPEMsg()
return
end
-- --------------------------------------------------
-- START PROCESSING
-- --------------------------------------------------
-- PACK HEADERS
do
local SecrHdrsOffset = GetOffset(hOriginalPE, PE_SectionHeaders)
local SizeOfSections = GetNumberOfSections(hPE)
* IMAGE_SIZEOF_SECTION_HEADER
local FileHdrOffset = GetOffset(hPE, PE_FileHeader)
local SizeOfOptionalHdr = ReadWord(hPE, FileHdrOffset + 16)
local SizeOfPEHeader = 4 + 20 + SizeOfOptionalHdr;
local PEHdrOffset = GetOffset(hPE, PE_NtHeaders)
-- we assume that the PE header comes right after
-- the Dos header, this is a normal PE
FillBytes(hPE, 0x40, PEHdrOffset - 0x40, 0)
-- move headers
local HeadersSize = SizeOfPEHeader + SizeOfSections
local PEHdrAndSects = ReadBytes(hPE, PEHdrOffset, HeadersSize)
FillBytes(hPE, PEHdrOffset, HeadersSize, 0)
WriteBytes(hPE, 0x40, PEHdrAndSects, HeadersSize)
-- e_lfanew
WriteDword(hPE, 0x3C, 0x40)
OptHdrOffset = GetOffset(hPE, PE_OptionalHeader)
end
-- REMOVE LINKER REF
do
WriteWord(hPE, OptHdrOffset + 2, 0x0000)
end
-- UPDATE CHECKSUM
UpdateChecksum(hPE)
-- SAVE FILE
SaveFile(hPE)
- in Zeile 30 test.exe durch euren tatsächlichen Dateinamen ersetzen
- den CFF Explorer mit dem Skript als Parameter aufrufen