Store Settings and Data After Any PE Section
Post date: Sep 14, 2010 8:47:53 PM
Following his research into storing settings and data directly after the PE header, Alternative Crypter, steve10120 coded this example detailing how to store data after any PE section.
Author: steve10120
Compiled: Delphi 2007
Builder:
program Builder;
// steve10120@ic0de.org
uses
Windows, uGenUtils;
{$R *.res}
var
pFile: Pointer;
dwFileSize: DWORD;
IDH: PImageDosHeader;
INH: PImageNtHeaders;
ISH: PImageSectionHeader;
i: WORD;
pData: Pointer;
dwDataSize: DWORD;
pPadding: Pointer;
dwPadSize: DWORD;
hFile: DWORD;
dwWritten: DWORD;
const
szData: string = 'http://ic0de.org'#0;
szOutput: string = 'output.exe'#0;
begin
if (FileToPtr('loader.exe', pFile, dwFileSize)) then
begin
IDH := PImageDosHeader(pFile);
if (IDH^.e_magic = IMAGE_DOS_SIGNATURE) then
begin
INH := PImageNtHeaders(DWORD(pFile) + IDH^._lfanew);
if (INH^.Signature = IMAGE_NT_SIGNATURE) then
begin
dwDataSize := Align(Length(szData), INH^.OptionalHeader.FileAlignment);
pData := VirtualAlloc(nil, dwDataSize, MEM_COMMIT, PAGE_READWRITE);
CopyMemory(pData, @szData[1], Length(szData));
hFile := CreateFileA(PChar(szOutput), GENERIC_WRITE, FILE_SHARE_WRITE, nil, CREATE_ALWAYS, 0, 0);
if (ValidHandle(hFile)) then
begin
SetFilePointer(hFile, 0, nil, FILE_BEGIN);
WriteFile(hFile, pFile^, IDH^._lfanew + 248, dwWritten, nil);
for i := 0 to INH^.FileHeader.NumberOfSections - 1 do
begin
ISH := PImageSectionHeader(DWORD(pFile) + IDH^._lfanew + 248 + (i * 40));
SetFilePointer(hFile, IDH^._lfanew + 248 + (i * 40), nil, FILE_BEGIN);
WriteFile(hFile, ISH^, 40, dwWritten, nil);
end;
dwPadSize := INH^.OptionalHeader.SizeOfHeaders - (IDH^._lfanew + 248 + (INH^.FileHeader.NumberOfSections * 40));
pPadding := VirtualAlloc(nil, dwPadSize, MEM_COMMIT, PAGE_READWRITE);
SetFilePointer(hFile, 0, nil, FILE_END);
WriteFile(hFile, pPadding^, dwPadSize, dwWritten, nil);
VirtualFree(pPadding, 0, MEM_RELEASE);
ISH := PImageSectionHeader(DWORD(pFile) + IDH^._lfanew + 248);
SetFilePointer(hFile, ISH^.PointerToRawData, nil, FILE_BEGIN);
WriteFile(hFile, Pointer(DWORD(pFile) + ISH^.PointerToRawData)^, ISH^.SizeOfRawData, dwWritten, nil);
SetFilePointer(hFile, 0, nil, FILE_END);
WriteFile(hFile, pData^, dwDataSize, dwWritten, nil);
for i := 1 to INH^.FileHeader.NumberOfSections - 1 do
begin
ISH := PImageSectionHeader(DWORD(pFile) + IDH^._lfanew + 248 + (i * 40));
SetFilePointer(hFile, 0, nil, FILE_END);
WriteFile(hFile, Pointer(DWORD(pFile) + ISH^.PointerToRawData)^, ISH^.SizeOfRawData, dwWritten, nil);
end;
for i := 1 to INH^.FileHeader.NumberOfSections - 1 do
begin
ISH := PImageSectionHeader(DWORD(pFile) + IDH^._lfanew + 248 + (i * 40));
Inc(ISH^.PointerToRawData, dwDataSize);
SetFilePointer(hFile, IDH^._lfanew + 248 + (i * 40), nil, FILE_BEGIN);
WriteFile(hFile, ISH^, 40, dwWritten, nil);
end;
VirtualFree(pFile, 0, MEM_RELEASE):
VirtualFree(pData, 0, MEM_RELEASE);
CloseHandle(hFile);
end;
end;
end;
end;
end.
Loader/Stub:
program loader;
// steve10120@ic0de.org
uses
Windows;
{$R *.res}
var
hFile: DWORD;
dwRead: DWORD;
IDH: TImageDosHeader;
INH: TImageNtHeaders;
ISH: TImageSectionHeader;
NextISH: TImageSectionHeader;
pData: Pointer;
dwDataSize: DWORD;
begin
hFile := CreateFileA(PChar(ParamStr(0)), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
if (hFile <> INVALID_HANDLE_VALUE) then
begin
SetFilePointer(hFile, 0, nil, FILE_BEGIN);
ReadFile(hFile, IDH, 64, dwRead, nil);
if (IDH.e_magic = IMAGE_DOS_SIGNATURE) then
begin
SetFilePointer(hFile, IDH._lfanew, nil, FILE_BEGIN);
ReadFile(hFile, INH, 248, dwRead, nil);
if (INH.Signature = IMAGE_NT_SIGNATURE) then
begin
SetFilePointer(hFile, IDH._lfanew + 248, nil, FILE_BEGIN);
ReadFile(hFile, ISH, 40, dwRead, nil);
SetFilePointer(hFile, IDH._lfanew + 248 + 40, nil, FILE_BEGIN);
ReadFile(hFile, NextISH, 40, dwRead, nil);
dwDataSize := NextISH.PointerToRawData - (ISH.PointerToRawData + ISH.SizeOfRawData);
if (dwDataSize > 0) then
begin
pData := VirtualAlloc(nil, dwDataSize, MEM_COMMIT, PAGE_READWRITE);
SetFilePointer(hFile, ISH.PointerToRawData + ISH.SizeOfRawData, nil, FILE_BEGIN);
ReadFile(hFile, pData^, dwDataSize, dwRead, nil);
MessageBoxA(0, PChar(pData), 'Server Builder', 0);
VirtualFree(pData, 0, MEM_RELEASE);
end;
end;
end;
CloseHandle(hFile);
end;
end.
Only Delphi source code is included in the archive.