We don't display ads so we rely on your Bitcoin donations to 1KWEk9QaiJb2NwP5YFmR24LyUBa4JyuKqZ
Post date: Jul 17, 2010 5:40:26 PM
This code adds a new section to the pe file, so when its run the file its decrypted and loaded in memory
program PeLoader;
{
Example of a Pe Loader by ErazerZ
3rd May 2006
}
uses
Windows,
Dialogs,
untPeFile; { PE File Unit by ErazerZ }
var
Pe: TPeFile;
Open: TOpenDialog;
procedure AddExeLoader;
procedure _load_iat; stdcall; forward;
procedure _load_code(lpLoadLibrary, lpGetProcAddress: Pointer; lpSectionBegin: DWORD); stdcall; forward;
procedure _loader; stdcall;
asm
call _load_iat
call _load_code
end;
procedure _load_iat;
asm
pop eax
mov edx, eax
mov edx, eax
and eax, $fffff000
push eax
add eax, $55
lea eax, [eax]
push [eax]
lea eax, [eax+4]
push [eax]
push edx
end;
procedure _load_code(
lpLoadLibrary,
lpGetProcAddress: Pointer;
lpSectionBegin: DWORD); stdcall;
var
xLoadLibraryA: function(lpLibFileName: PChar): HMODULE; stdcall;
xGetProcAddress: function(hModule: HMODULE; lpProcName: LPCSTR): FARPROC; stdcall;
ImageBase, OldEntryPoint, OldIAT, EncryptStart, EncryptEnd, EncryptCounter: DWORD;
ImportDesc: PImageImportDescriptor;
lpDllName: PChar;
hDll: THandle;
ImageThunk: ^PImageThunkData;
ImageThunkWrite: ^Pointer;
begin
@xLoadLibraryA := lpLoadLibrary;
@xGetProcAddress := lpGetProcAddress;
ImageBase := DWORD(Pointer(DWORD(lpSectionBegin + $61))^);
OldEntryPoint := DWORD(Pointer(DWORD(lpSectionBegin + $65))^) + ImageBase;
OldIAT := DWORD(Pointer(DWORD(lpSectionBegin + $69))^) + ImageBase;
EncryptStart := DWORD(Pointer(DWORD(lpSectionBegin + $6D))^) + ImageBase;
EncryptEnd := DWORD(Pointer(DWORD(lpSectionBegin + $71))^) + ImageBase;
for EncryptCounter := EncryptStart to EncryptEnd do
begin
PByte(EncryptCounter)^ := PByte(EncryptCounter)^ xor $FF;
end;
ImportDesc := PImageImportDescriptor(OldIAT);
while (ImportDesc^.Name <> 0) do
begin
lpDllName := PChar(ImportDesc^.Name + ImageBase);
hDll := xLoadLibraryA(lpDllName);
if (ImportDesc^.OriginalFirstThunk <> 0) then
ImageThunk := Pointer(ImportDesc^.OriginalFirstThunk + ImageBase)
else
ImageThunk := Pointer(ImportDesc^.FirstThunk + ImageBase);
ImageThunkWrite := Pointer(ImportDesc^.FirstThunk + ImageBase);
while (ImageThunk^ <> nil) do
begin
if ((Cardinal(ImageThunk^) and $80000000) <> 0) then
ImageThunkWrite^ := xGetProcAddress(hDll, PChar(Cardinal(ImageThunk^) and $FFFF))
else
ImageThunkWrite^ := xGetProcAddress(hDll, PChar(ImageBase + Cardinal(ImageThunk^) + SizeOf(Word)));
Inc(ImageThunk);
Inc(ImageThunkWrite);
end;
Inc(ImportDesc);
end;
asm
jmp OldEntryPoint
end;
end;
procedure _loader_end; begin end;
var
dwOldIATVA, lsPointerToRawData, lpTemp, EncryptCounter, EncryptStart, EncryptEnd: Cardinal;
ImportDescriptor: TImageImportDescriptor;
ImageThunk: array[0..1] of TImageThunkData;
x: Word;
const
szIAT_DLL_KERNEL: string = 'kernel32.dll'#0;
szIAT_FUNC_GETPROCADDR: string = #0#0'GetProcAddress'#0;
szIAT_FUNC_LOADLIBRARY: string = #0#0'LoadLibraryA'#0;
begin
dwOldIATVA := Pe.ImageNtHeaders^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
if Pe.AddSection('.edi', $200) then
begin
FillChar(ImportDescriptor, SizeOf(TImageImportDescriptor), #0);
FillChar(ImageThunk, SizeOf(TImageThunkData), #0);
lsPointerToRawData := Pe.ImageSections[High(Pe.ImageSections)].PointerToRawData;
lpTemp := 0;
Pe.CopyMemoryBuffer(lsPointerToRawData + lpTemp, Pointer(szIAT_DLL_KERNEL), Length(szIAT_DLL_KERNEL));
ImportDescriptor.Name := Pe.FileOffsetToRva(lsPointerToRawData);
Inc(lpTemp, Length(szIAT_DLL_KERNEL));
Pe.CopyMemoryBuffer(lsPointerToRawData + lpTemp, Pointer(szIAT_FUNC_GETPROCADDR), Length(szIAT_FUNC_GETPROCADDR));
ImageThunk[0].Name := Pe.FileOffsetToRva(lsPointerToRawData + lpTemp);
Inc(lpTemp, Length(szIAT_FUNC_GETPROCADDR));
Pe.CopyMemoryBuffer(lsPointerToRawData + lpTemp, Pointer(szIAT_FUNC_LOADLIBRARY), Length(szIAT_FUNC_LOADLIBRARY));
ImageThunk[1].Name := Pe.FileOffsetToRva(lsPointerToRawData + lpTemp);
Inc(lpTemp, Length(szIAT_FUNC_LOADLIBRARY));
ImportDescriptor.FirstThunk := Pe.FileOffsetToRva(lsPointerToRawData + lpTemp + (SizeOf(TImageImportDescriptor) * 2));
Pe.CopyMemoryBuffer(lsPointerToRawData + lpTemp, @ImportDescriptor, SizeOf(TImageImportDescriptor));
Pe.ImageNtHeaders^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress := Pe.FileOffsetToRva(lsPointerToRawData + lpTemp);
Inc(lpTemp, SizeOf(TImageImportDescriptor) * 2);
Pe.CopyMemoryBuffer((lsPointerToRawData + lpTemp), @ImageThunk, SizeOf(ImageThunk));
Inc(lpTemp, SizeOf(ImageThunk) + SizeOf(TImageThunkData));
Pe.ImageNtHeaders^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size := lpTemp;
Pe.CopyMemoryBuffer((lsPointerToRawData + lpTemp), PDWORD(@Pe.ImageNtHeaders^.OptionalHeader.ImageBase), SizeOf(DWORD));
Inc(lpTemp, SizeOf(DWORD));
Pe.CopyMemoryBuffer((lsPointerToRawData + lpTemp), PDWORD(@Pe.ImageNtHeaders^.OptionalHeader.AddressOfEntryPoint), SizeOf(DWORD));
Inc(lpTemp, SizeOf(DWORD));
Pe.CopyMemoryBuffer((lsPointerToRawData + lpTemp), PDWORD(@dwOldIATVA), SizeOf(DWORD));
Inc(lpTemp, SizeOf(DWORD));
EncryptStart := Pe.ImageSections[Pe.GetCodeSection].VirtualAddress;
Pe.CopyMemoryBuffer((lsPointerToRawData + lpTemp), PDWORD(@EncryptStart), SizeOf(DWORD));
Inc(lpTemp, SizeOf(DWORD));
EncryptEnd := EncryptStart + Pe.ImageSections[Pe.GetCodeSection].Misc.VirtualSize;
Pe.CopyMemoryBuffer(lsPointerToRawData + lpTemp, PDWORD(@EncryptEnd), SizeOf(DWORD));
Inc(lpTemp, SizeOf(DWORD));
EncryptStart := Pe.RvaToVa(EncryptStart);
EncryptEnd := Pe.RvaToVa(EncryptEnd);
for EncryptCounter := EncryptStart to EncryptEnd do
begin
PByte(EncryptCounter)^ := PByte(EncryptCounter)^ xor $FF;
end;
Pe.ImageNtHeaders^.OptionalHeader.AddressOfEntryPoint := Pe.FileOffsetToRva(lsPointerToRawData + lpTemp);
Pe.CopyMemoryBuffer(lsPointerToRawData + lpTemp, @_loader, DWORD(@_loader_end) - DWORD(@_loader));
for x := Low(Pe.ImageSections) to High(Pe.ImageSections) do
Pe.ImageSections[x].Characteristics := Pe.ImageSections[x].Characteristics or IMAGE_SCN_MEM_WRITE;
Pe.ImageNtHeaders^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress := 0;
Pe.ImageNtHeaders^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size := 0;
Pe.ImageNtHeaders^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress := 0;
Pe.ImageNtHeaders^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size := 0;
Pe.ImageNtHeaders^.OptionalHeader.BaseOfCode := lsPointerToRawData;
Pe.ImageNtHeaders^.OptionalHeader.BaseOfData := lsPointerToRawData;
end;
end;
begin
Pe := TPeFile.Create;
Open := TOpenDialog.Create(Self);
if OpenDialog.Execute then
begin
Pe.LoadFromFile(Open.FileName);
AddExeLoader;
Pe.SaveToFile(Open.FileName);
end;
Open.Free;
Pe.Free;
end.