Store Settings and Data After Any PE Section

posted 14 Sep 2010, 13:47 by Danny Rancher
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.
ċ
StoreSettingsandDataAfterAnyPESection.rar
(6k)
Danny Rancher,
14 Sep 2010, 15:09
Comments