We don't display ads so we rely on your Bitcoin donations to 1KWEk9QaiJb2NwP5YFmR24LyUBa4JyuKqZ
Post date: Mar 13, 2010 11:01:08 PM
When a PE file is generated, it is not usually known where in memory it will be loaded. The virtual address where the first byte of the file will be loaded is called ImageBase address. Default for delphi files is 40000.
{
Unit: uRebase
Author: steve10120
Description: Change the ImageBase of a PE. Needs a relocation table!
Credits: Author of BTMemoryModule: PerformBaseRelocation().
Release Date: 27th August 2009
Website: hackhound.org
History: First try
}
unit uRebase;interfaceuses Windows;function RebaseFile(szFilePath:string; szDestFile:string; dwNewImageBase:DWORD):Boolean;type PImageBaseRelocation = ^TImageBaseRelocation; TImageBaseRelocation = packed record VirtualAddress: DWORD; SizeOfBlock: DWORD; end;implementationfunction FileToMem(szFilePath:string; var pFile:Pointer; var dwSize:DWORD):Boolean;var hFile: DWORD; dwNull: DWORD;begin Result := FALSE; hFile := CreateFile(PChar(szFilePath), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); if hFile <> INVALID_HANDLE_VALUE then begin dwSize := GetFileSize(hFile, nil); if dwSize > 0 then begin GetMem(pFile, dwSize); SetFilePointer(hFile, 0, nil, FILE_BEGIN); ReadFile(hFile, pFile^, dwSize, dwNull, nil); CloseHandle(hFile); Result := TRUE; end; end;end;procedure MemToFile(pData:Pointer; sPath:string; dSize:DWORD);varhFile: THandle;dWritten: DWORD;begin hFile := CreateFile(PChar(sPath), GENERIC_WRITE, FILE_SHARE_WRITE, nil, CREATE_ALWAYS, 0, 0); if hFile <> 0 then begin SetFilePointer(hFile, 0, nil, FILE_BEGIN); WriteFile(hFile, pData^, dSize, dWritten, nil); FreeMem(pData, dSize); CloseHandle(hFile); end;end;procedure PerformBaseRelocation(f_module: Pointer; INH:PImageNtHeaders; f_delta: Cardinal); stdcall;var l_i: Cardinal; l_codebase: Pointer; l_relocation: PImageBaseRelocation; l_dest: Pointer; l_relInfo: ^Word; l_patchAddrHL: ^DWord; l_type, l_offset: integer;begin l_codebase := f_module; if INH^.OptionalHeader.DataDirectory[5].Size > 0 then begin l_relocation := PImageBaseRelocation(Cardinal(l_codebase) + INH^.OptionalHeader.DataDirectory[5].VirtualAddress); while l_relocation.VirtualAddress > 0 do begin l_dest := Pointer((Cardinal(l_codebase) + l_relocation.VirtualAddress)); l_relInfo := Pointer(Cardinal(l_relocation) + 8); for l_i := 0 to (trunc(((l_relocation.SizeOfBlock - 8) / 2)) - 1) do begin l_type := (l_relInfo^ shr 12); l_offset := l_relInfo^ and $FFF; if l_type = 3 then begin l_patchAddrHL := Pointer(Cardinal(l_dest) + Cardinal(l_offset)); l_patchAddrHL^ := l_patchAddrHL^ + f_delta; end; inc(l_relInfo); end; l_relocation := Pointer(cardinal(l_relocation) + l_relocation.SizeOfBlock); end; end;end;function AlignImage(pImage:Pointer):Pointer;var IDH: PImageDosHeader; INH: PImageNtHeaders; ISH: PImageSectionHeader; i: WORD;begin IDH := pImage; INH := Pointer(DWORD(pImage) + IDH^._lfanew); GetMem(Result, INH^.OptionalHeader.SizeOfImage); ZeroMemory(Result, INH^.OptionalHeader.SizeOfImage); CopyMemory(Result, pImage, INH^.OptionalHeader.SizeOfHeaders); for i := 0 to INH^.FileHeader.NumberOfSections - 1 do begin ISH := Pointer(DWORD(pImage) + IDH^._lfanew + 248 + i * 40); CopyMemory(Pointer(DWORD(Result) + ISH^.VirtualAddress), Pointer(DWORD(pImage) + ISH^.PointerToRawData), ISH^.SizeOfRawData); end;end;function RebuildImage(pImage:Pointer):Pointer;var IDH: PImageDosHeader; INH: PImageNtHeaders; ISH: PImageSectionHeader; i: WORD;begin IDH := pImage; INH := Pointer(DWORD(pImage) + IDH^._lfanew); ISH := Pointer(DWORD(pImage) + IDH^._lfanew + 248 + (INH.FileHeader.NumberOfSections - 1) * 40); GetMem(Result, (ISH.PointerToRawData + ISH.SizeOfRawData)); ZeroMemory(Result, INH^.OptionalHeader.SizeOfHeaders); CopyMemory(Result, pImage, INH^.OptionalHeader.SizeOfHeaders); for i := 0 to INH^.FileHeader.NumberOfSections - 1 do begin ISH := Pointer(DWORD(pImage) + IDH^._lfanew + 248 + i * 40); CopyMemory(Pointer(DWORD(Result) + ISH^.PointerToRawData), Pointer(DWORD(pImage) + ISH^.VirtualAddress), ISH^.SizeOfRawData); end;end;function RebaseFile(szFilePath:string; szDestFile:string; dwNewImageBase:DWORD):Boolean;var pFile: Pointer; dwSize: DWORD; IDH: PImageDosHeader; INH: PImageNtHeaders;begin Result := FALSE; if FileToMem(szFilePath, pFile, dwSize) then begin IDH := pFile; if IDH^.e_magic = IMAGE_DOS_SIGNATURE then begin INH := Pointer(DWORD(pFile) + IDH^._lfanew); if INH^.Signature = IMAGE_NT_SIGNATURE then begin pFile := AlignImage(pFile); if INH^.OptionalHeader.DataDirectory[5].Size > 0 then begin PerformBaseRelocation(pFile, INH, (dwNewImageBase - INH^.OptionalHeader.ImageBase)); INH^.OptionalHeader.ImageBase := dwNewImageBase; CopyMemory(Pointer(DWORD(pFile) + IDH^._lfanew), INH, 248); pFile := RebuildImage(pFile); MemToFile(pFile, szDestFile, dwSize); Result := TRUE; end; end; end; end;end;end.