Class: AppInfo::PE

Inherits:
File
  • Object
show all
Extended by:
Forwardable
Includes:
Helper::Archive, Helper::HumanFileSize
Defined in:
lib/app_info/pe.rb

Overview

Windows PE parser

Defined Under Namespace

Classes: VersionInfo

Constant Summary collapse

ARCH =
{
  0x014c => 'x86',
  0x0200 => 'Intel Itanium',
  0x8664 => 'x64',
  0x1c0 => 'arm',
  0xaa64 => 'arm64',
  0x5032 => 'RISC-v 32',
  0x5064 => 'RISC-v 64',
  0x5128 => 'RISC-v 128'
}.freeze

Constants included from Helper::HumanFileSize

Helper::HumanFileSize::FILE_SIZE_UNITS

Instance Attribute Summary

Attributes inherited from File

#file, #logger

Instance Method Summary collapse

Methods included from Helper::Archive

#tempdir, #unarchive

Methods included from Helper::HumanFileSize

#file_to_human_size, #number_to_human_size

Methods inherited from File

#format, #initialize, #not_implemented_error!

Constructor Details

This class inherits a constructor from AppInfo::File

Instance Method Details

#archsString Also known as: architectures

Returns:

  • (String)


115
116
117
# File 'lib/app_info/pe.rb', line 115

def archs
  ARCH[image_file_header.Machine] || 'unknown'
end

#assembly_versionString

Returns:

  • (String)

See Also:



96
97
98
# File 'lib/app_info/pe.rb', line 96

def_delegators :version_info, :product_name, :product_version, :company_name, :assembly_version,
:file_version, :file_description, :copyright, :special_build, :private_build,
:original_filename, :internal_name, :legal_trademarks

#binary_fileString

Returns binary_file path.

Returns:

  • (String)

    binary_file path



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/app_info/pe.rb', line 189

def binary_file
  @binary_file ||= lambda {
    file_io = ::File.open(@file, 'rb')
    return @file unless file_io.read(100) =~ AppInfo::ZIP_RETGEX

    zip_file = Zip::File.open(@file)
    zip_entry = zip_file.glob('*.exe').first
    raise NotFoundError, 'Not found .exe file in archive file' if zip_entry.nil?

    exe_file = tempdir(zip_entry.name, prefix: 'pe-exe', system: true)
    zip_entry.extract(exe_file)
    zip_file.close

    return exe_file
  }.call
end

#binary_size(human_size: false) ⇒ Object



55
56
57
# File 'lib/app_info/pe.rb', line 55

def binary_size(human_size: false)
  file_to_human_size(binary_file, human_size: human_size)
end

#build_versionString?

Returns:

  • (String, nil)


110
111
112
# File 'lib/app_info/pe.rb', line 110

def build_version
  special_build || private_build || assembly_version
end

#clear!Object



181
182
183
184
185
186
# File 'lib/app_info/pe.rb', line 181

def clear!
  @io = nil
  @pe = nil
  @icons = nil
  @imports = nil
end

#company_nameString

Returns:

  • (String)

See Also:



96
97
98
# File 'lib/app_info/pe.rb', line 96

def_delegators :version_info, :product_name, :product_version, :company_name, :assembly_version,
:file_version, :file_description, :copyright, :special_build, :private_build,
:original_filename, :internal_name, :legal_trademarks

Returns:

  • (String)
  • (String)

See Also:



96
97
98
# File 'lib/app_info/pe.rb', line 96

def_delegators :version_info, :product_name, :product_version, :company_name, :assembly_version,
:file_version, :file_description, :copyright, :special_build, :private_build,
:original_filename, :internal_name, :legal_trademarks

#deviceSymbol

Returns Device.

Returns:



38
39
40
# File 'lib/app_info/pe.rb', line 38

def device
  Device::WINDOWS
end

#file_descriptionString

Returns:

  • (String)

See Also:



96
97
98
# File 'lib/app_info/pe.rb', line 96

def_delegators :version_info, :product_name, :product_version, :company_name, :assembly_version,
:file_version, :file_description, :copyright, :special_build, :private_build,
:original_filename, :internal_name, :legal_trademarks

#file_versionString

Returns:

  • (String)

See Also:



96
97
98
# File 'lib/app_info/pe.rb', line 96

def_delegators :version_info, :product_name, :product_version, :company_name, :assembly_version,
:file_version, :file_description, :copyright, :special_build, :private_build,
:original_filename, :internal_name, :legal_trademarks

#iconsArray{String}

Returns icons paths of bmp image icons.

Returns:

  • (Array{String})

    icons paths of bmp image icons



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/app_info/pe.rb', line 128

def icons
  @icons ||= lambda {
    # Fetch the largest size icon
    files = []
    pe.resources&.find_all do |res|
      next unless res.type == 'ICON'

      filename = "#{::File.basename(file, '.*')}-#{res.type}-#{res.id}.bmp"
      icon_file = tempdir(filename, prefix: 'pe', system: true)
      mask_icon_file = icon_file.sub('.bmp', '.mask.bmp')

      begin
        ::File.open(icon_file, 'wb') do |f|
          f << res.restore_bitmap(io)
        end

        if res.bitmap_mask(io)
          mask_icon_file = icon_file.sub('.bmp', '.mask.bmp')
          ::File.open(mask_icon_file, 'wb') do |f|
            f << res.bitmap_mask(io)
          end
        end
      rescue StandardError => e
        # ignore pedump throws any exception.
        raise e unless e.backtrace.first.include?('pedump')

        FileUtils.rm_f(icon_file)
      ensure
        next unless ::File.exist?(icon_file)

        mask_file = ::File.exist?(mask_icon_file) ? mask_icon_file : nil
        files << (icon_file, mask_file: mask_file)
      end
    end

    files
  }.call
end

#importsHash{String => String}

Returns imports imports of libraries.

Returns:

  • (Hash{String => String})

    imports imports of libraries



121
122
123
124
125
# File 'lib/app_info/pe.rb', line 121

def imports
  @imports ||= pe.imports.each_with_object({}) do |import, obj|
    obj[import.module_name] = import.first_thunk.map(&:name).compact
  end
end

#internal_nameString

Returns:

  • (String)

See Also:



96
97
98
# File 'lib/app_info/pe.rb', line 96

def_delegators :version_info, :product_name, :product_version, :company_name, :assembly_version,
:file_version, :file_description, :copyright, :special_build, :private_build,
:original_filename, :internal_name, :legal_trademarks

Returns:

  • (String)

See Also:



96
97
98
# File 'lib/app_info/pe.rb', line 96

def_delegators :version_info, :product_name, :product_version, :company_name, :assembly_version,
:file_version, :file_description, :copyright, :special_build, :private_build,
:original_filename, :internal_name, :legal_trademarks

#manufacturerSymbol

Returns Manufacturer.

Returns:



28
29
30
# File 'lib/app_info/pe.rb', line 28

def manufacturer
  Manufacturer::MICROSOFT
end

#original_filenameString

Returns:

  • (String)

See Also:



96
97
98
# File 'lib/app_info/pe.rb', line 96

def_delegators :version_info, :product_name, :product_version, :company_name, :assembly_version,
:file_version, :file_description, :copyright, :special_build, :private_build,
:original_filename, :internal_name, :legal_trademarks

#pePEdump

Returns:

  • (PEdump)


168
169
170
171
172
173
174
# File 'lib/app_info/pe.rb', line 168

def pe
  @pe ||= lambda {
    pe = PEdump.new(io)
    pe.logger.level = Logger::FATAL # ignore :warn logger output
    pe
  }.call
end

#platformSymbol

Returns:



33
34
35
# File 'lib/app_info/pe.rb', line 33

def platform
  Platform::WINDOWS
end

#private_buildString

Returns:

  • (String)

See Also:



96
97
98
# File 'lib/app_info/pe.rb', line 96

def_delegators :version_info, :product_name, :product_version, :company_name, :assembly_version,
:file_version, :file_description, :copyright, :special_build, :private_build,
:original_filename, :internal_name, :legal_trademarks

#product_nameString Also known as: name

Returns:

  • (String)

See Also:



96
97
98
# File 'lib/app_info/pe.rb', line 96

def_delegators :version_info, :product_name, :product_version, :company_name, :assembly_version,
:file_version, :file_description, :copyright, :special_build, :private_build,
:original_filename, :internal_name, :legal_trademarks

#product_versionString

Returns:

  • (String)

See Also:



96
97
98
# File 'lib/app_info/pe.rb', line 96

def_delegators :version_info, :product_name, :product_version, :company_name, :assembly_version,
:file_version, :file_description, :copyright, :special_build, :private_build,
:original_filename, :internal_name, :legal_trademarks

#release_versionString?

Find #product_version then fallback to #file_version

Returns:

  • (String, nil)


104
105
106
# File 'lib/app_info/pe.rb', line 104

def release_version
  product_version || file_version
end

#size(human_size: false) ⇒ Integer, String

return file size

Examples:

Read file size in integer

aab.size                    # => 3618865

Read file size in human readabale

aab.size(human_size: true)  # => '3.45 MB'

Parameters:

  • human_size (Boolean) (defaults to: false)

    Convert integer value to human readable.

Returns:

  • (Integer, String)


51
52
53
# File 'lib/app_info/pe.rb', line 51

def size(human_size: false)
  file_to_human_size(@file, human_size: human_size)
end

#special_buildString

Returns:

  • (String)

See Also:



96
97
98
# File 'lib/app_info/pe.rb', line 96

def_delegators :version_info, :product_name, :product_version, :company_name, :assembly_version,
:file_version, :file_description, :copyright, :special_build, :private_build,
:original_filename, :internal_name, :legal_trademarks

#version_infoVersionInfo

Returns:



177
178
179
# File 'lib/app_info/pe.rb', line 177

def version_info
  @version_info ||= VersionInfo.new(pe.version_info)
end