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.