lib/pedump/loader.rb
def export io
    @mz_hdr     ||= PEdump::MZ.new("MZ", *[0]*22)
    @dos_stub   ||= ''
    @pe_hdr     ||= PEdump::PE.new("PE\x00\x00")
    @pe_hdr.ioh ||=
      PEdump::IMAGE_OPTIONAL_HEADER32.read( StringIO.new("\x00" * 224) ).tap do |ioh|
        ioh.Magic               = 0x10b # 32-bit executable
        #ioh.NumberOfRvaAndSizes = 0x10
      end
    @pe_hdr.ifh ||= PEdump::IMAGE_FILE_HEADER.new(
      :Machine              => 0x14c,          # x86
      :NumberOfSections     => @sections.size,
      :TimeDateStamp        => 0,
      :PointerToSymbolTable => 0,
      :NumberOfSymbols      => 0,
      :SizeOfOptionalHeader => @pe_hdr.ioh.pack.size,
      :Characteristics      => 0x102           # EXECUTABLE_IMAGE | 32BIT_MACHINE
    )

    if @pe_hdr.ioh.FileAlignment.to_i == 0
      # default file align = 512 bytes
      @pe_hdr.ioh.FileAlignment = 0x200
    end
    if @pe_hdr.ioh.SectionAlignment.to_i == 0
      # default section align = 4k
      @pe_hdr.ioh.SectionAlignment = 0x1000
    end

    mz_size = @mz_hdr.pack.size
    raise "odd mz_size #{mz_size}" if mz_size % 0x10 != 0
    @mz_hdr.header_paragraphs = mz_size / 0x10              # offset of dos_stub
    @mz_hdr.lfanew = mz_size + @dos_stub.size               # offset of PE hdr
    io.write @mz_hdr.pack
    io.write @dos_stub
    io.write @pe_hdr.pack
    io.write @pe_hdr.ioh.DataDirectory.map(&:pack).join

    section_tbl_offset = io.tell # store offset for 2nd write of section table
    io.write section_table

    align = @pe_hdr.ioh.FileAlignment
    @sections.each do |section|
      io.seek(align - (io.tell % align), IO::SEEK_CUR) if io.tell % align != 0
      section.hdr.PointerToRawData = io.tell  # fix raw_ptr
      io.write(section.data)
    end

    eof = io.tell

    # 2nd write of section table with correct raw_ptr's
    io.seek section_tbl_offset
    io.write section_table

    io.seek eof
  end
# save a new PE file to specified IO
save a new PE file to specified IO
save a new PE file to specified IO
def export io
    @mz_hdr     ||= PEdump::MZ.new("MZ", *[0]*22)
    @dos_stub   ||= ''
    @pe_hdr     ||= PEdump::PE.new("PE\x00\x00")
    @pe_hdr.ioh ||=
      PEdump::IMAGE_OPTIONAL_HEADER32.read( StringIO.new("\x00" * 224) ).tap do |ioh|
        ioh.Magic               = 0x10b 
      end
    @pe_hdr.ifh ||= PEdump::IMAGE_FILE_HEADER.new(
      :Machine              => 0x14c,          
      :NumberOfSections     => @sections.size,
      :TimeDateStamp        => 0,
      :PointerToSymbolTable => 0,
      :NumberOfSymbols      => 0,
      :SizeOfOptionalHeader => @pe_hdr.ioh.pack.size,
      :Characteristics      => 0x102           
    )
    if @pe_hdr.ioh.FileAlignment.to_i == 0
      @pe_hdr.ioh.FileAlignment = 0x200
    end
    if @pe_hdr.ioh.SectionAlignment.to_i == 0
      @pe_hdr.ioh.SectionAlignment = 0x1000
    end
    mz_size = @mz_hdr.pack.size
    raise "odd mz_size #{mz_size}" if mz_size % 0x10 != 0
    @mz_hdr.header_paragraphs = mz_size / 0x10              
    @mz_hdr.lfanew = mz_size + @dos_stub.size               
    io.write @mz_hdr.pack
    io.write @dos_stub
    io.write @pe_hdr.pack
    io.write @pe_hdr.ioh.DataDirectory.map(&:pack).join
    section_tbl_offset = io.tell 
    io.write section_table
    align = @pe_hdr.ioh.FileAlignment
    @sections.each do |section|
      io.seek(align - (io.tell % align), IO::SEEK_CUR) if io.tell % align != 0
      section.hdr.PointerToRawData = io.tell  
      io.write(section.data)
    end
    eof = io.tell
    io.seek section_tbl_offset
    io.write section_table
    io.seek eof
  end
def export io @mz_hdr ||= PEdump :: MZ . new ( "MZ" , * [ 0 ] * 22 ) @dos_stub ||= '' @pe_hdr ||= PEdump :: PE . new ( "PE\x00\x00" ) @pe_hdr . ioh ||= PEdump :: IMAGE_OPTIONAL_HEADER32 . read ( StringIO . new ( "\x00" * 224 ) ) . tap do | ioh | ioh . Magic = 0x10b end @pe_hdr . ifh ||= PEdump :: IMAGE_FILE_HEADER . new ( :Machine => 0x14c , :NumberOfSections => @sections . size , :TimeDateStamp => 0 , :PointerToSymbolTable => 0 , :NumberOfSymbols => 0 , :SizeOfOptionalHeader => @pe_hdr . ioh . pack . size , :Characteristics => 0x102 ) if @pe_hdr . ioh . FileAlignment . to_i == 0 @pe_hdr . ioh . FileAlignment = 0x200 end if @pe_hdr . ioh . SectionAlignment . to_i == 0 @pe_hdr . ioh . SectionAlignment = 0x1000 end mz_size = @mz_hdr . pack . size raise "odd mz_size #{mz_size}" if mz_size % 0x10 != 0 @mz_hdr . header_paragraphs = mz_size / 0x10 @mz_hdr . lfanew = mz_size + @dos_stub . size io . write @mz_hdr . pack io . write @dos_stub io . write @pe_hdr . pack io . write @pe_hdr . ioh . DataDirectory . map ( & :pack ) . join section_tbl_offset = io . tell io . write section_table align = @pe_hdr . ioh . FileAlignment @sections . each do | section | io . seek ( align - ( io . tell % align ) , IO :: SEEK_CUR ) if io . tell % align != 0 section . hdr . PointerToRawData = io . tell io . write ( section . data ) end eof = io . tell io . seek section_tbl_offset io . write section_table io . seek eof end
save a new PE file to specified IO
save a new PE file to specified IO
# 32-bit executable #ioh.NumberOfRvaAndSizes = 0x10 # x86 # EXECUTABLE_IMAGE | 32BIT_MACHINE # default file align = 512 bytes # default section align = 4k # offset of dos_stub # offset of PE hdr # store offset for 2nd write of section table # fix raw_ptr # 2nd write of section table with correct raw_ptr's
io