We don't display ads so we rely on your Bitcoin donations to 1KWEk9QaiJb2NwP5YFmR24LyUBa4JyuKqZ
Post date: Mar 15, 2010 10:05:52 PM
This unit enables you to strip the table of the base relocations (Fix-Up Table) from EXE files and saves space, making them smaller. As a rule, there's no need for an EXE to have a base relocation table. This is because EXEs are the first thing loaded into an address space, and therefore are guaranteed to load at the preferred load address. It is recommend that you do not strip relocations from all EXEs you come across, because while this may save space, it may cause some executables not to work properly. If you take a look at Windows Notepad.exe the relocation table has been stripped.
Read more: http://en.wikipedia.org/wiki/Relocation_table
{
Unit: uStripRelocs
Author: steve10120
Description: Delete the relocations from a PE file.
Website: http://hackhound.org
History: First try
}
unit uStripRelocs;
interface
uses Windows;
function StripRelocations(szFilePath:string; szDestFile:string):Boolean;
type
TByteArray = array of Byte;
implementation
function FileToBytes(sPath:string; var bFile:TByteArray):Boolean;
var
hFile: THandle;
dSize: DWORD;
dRead: DWORD;
begin
Result := FALSE;
hFile := CreateFile(PChar(sPath), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
if hFile <> 0 then
begin
dSize := GetFileSize(hFile, nil);
SetFilePointer(hFile, 0, nil, FILE_BEGIN);
SetLength(bFile, dSize);
if ReadFile(hFile, bFile[0], dSize, dRead, nil) then
Result := TRUE;
CloseHandle(hFile);
end;
end;
procedure BytesToFile(bData:TByteArray; sPath:string);
var
hFile: THandle;
dWritten: DWORD;
begin
hFile := CreateFile(PChar(sPath), GENERIC_WRITE, FILE_SHARE_WRITE, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if hFile <> 0 then
begin
SetFilePointer(hFile, 0, nil, FILE_BEGIN);
WriteFile(hFile, bData[0],Length(bData), dWritten, nil);
CloseHandle(hFile);
end;
end;
function StripRelocations(szFilePath:string; szDestFile:string):Boolean;
var
bFile: TByteArray;
IDH: TImageDosHeader;
INH: TImageNtHeaders;
ISH: TImageSectionHeader;
szSecName: array[0..7] of Char;
begin
Result := FALSE;
if FileToBytes(szFilePath, bFile) then
begin
CopyMemory(@IDH, @bFile[0], 64);
if IDH.e_magic = IMAGE_DOS_SIGNATURE then
begin
CopyMemory(@INH, @bFile[IDH._lfanew], 248);
if INH.Signature = IMAGE_NT_SIGNATURE then
begin
if (INH.OptionalHeader.DataDirectory[5].VirtualAddress > 0) and (INH.OptionalHeader.DataDirectory[5].Size > 0) then
begin
CopyMemory(@ISH, @bFile[IDH._lfanew + 248 + (INH.FileHeader.NumberOfSections - 1) * 40], 40);
CopyMemory(@szSecName[0], @ISH.Name[0], 8);
if szSecName = '.reloc' then
begin
SetLength(bFile, Length(bFile) - ISH.SizeOfRawData);
INH.OptionalHeader.DataDirectory[5].VirtualAddress := 0;
INH.OptionalHeader.DataDirectory[5].Size := 0;
FillChar(ISH, 40, #0);
CopyMemory(@bFile[IDH._lfanew + 248 + (INH.FileHeader.NumberOfSections - 1) * 40], @ISH, 40);
Dec(INH.FileHeader.NumberOfSections);
CopyMemory(@ISH, @bFile[IDH._lfanew + 248 + (INH.FileHeader.NumberOfSections - 1) * 40], 40);
INH.OptionalHeader.SizeOfImage := ISH.VirtualAddress + ISH.Misc.VirtualSize;
CopyMemory(@bFile[IDH._lfanew], @INH, 248);
BytesToFile(bFile, szDestFile);
Result := TRUE;
end;
end;
end;
end;
end;
end;
end.