Module: Ocran::EdIcon

Extended by:
Fiddle::Importer
Includes:
Fiddle::Win32Types
Defined in:
lib/ocran/ed_icon.rb

Overview

Changes the Icon in a PE executable.

Defined Under Namespace

Modules: Successive Classes: GroupIcon, IconFile

Constant Summary collapse

IconHeader =

Icon file header

struct(
  [
    "WORD Reserved",
    "WORD ResourceType",
    "WORD ImageCount"
  ]
).include(Successive)
IconDirectoryEntry =

Icon File directory entry structure

struct(icon_info + ["DWORD ImageOffset"]).include(Successive)
IconDirResEntry =

Group Icon Resource directory entry structure

struct(icon_info + ["WORD ResourceID"]).include(Successive)
MAKEINTRESOURCE =
-> (i) { Fiddle::Pointer.new(i) }
RT_ICON =
MAKEINTRESOURCE.(3)
RT_GROUP_ICON =
MAKEINTRESOURCE.(RT_ICON.to_i + 11)
MAKELANGID =
-> (p, s) { s << 10 | p }
LANG_NEUTRAL =
0x00
SUBLANG_DEFAULT =
0x01
LANGID =
MAKELANGID.(LANG_NEUTRAL, SUBLANG_DEFAULT)

Class Method Summary collapse

Class Method Details

.update_icon(executable_filename, icon_filename) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/ocran/ed_icon.rb', line 111

def update_icon(executable_filename, icon_filename)
  update_resource(executable_filename) do |handle|
    icon_file = IconFile.new(icon_filename)
    icon_entries = icon_file.entries

    # Create the RT_ICON resources
    icon_entries.each_with_index do |entry, i|
      if UpdateResourceW(handle, RT_ICON, 101 + i, LANGID, icon_file.to_i + entry.ImageOffset, entry.ImageSize) == 0
        raise "failed to UpdateResource(#{GetLastError()})"
      end
    end

    # Create the RT_GROUP_ICON structure
    group_icon = GroupIcon.new(icon_file.ImageCount, icon_file.ResourceType)
    group_icon.entries.zip(icon_entries).each_with_index do |(res, icon), i|
      res.Width = icon.Width
      res.Height = icon.Height
      res.Colors = icon.Colors
      res.Reserved = icon.Reserved
      res.Planes = icon.Planes
      res.BitsPerPixel = icon.BitsPerPixel
      res.ImageSize = icon.ImageSize
      res.ResourceID = 101 + i
    end

    # Save the RT_GROUP_ICON resource
    if UpdateResourceW(handle, RT_GROUP_ICON, 100, LANGID, group_icon, group_icon.size) == 0
      raise "Failed to create group icon(#{GetLastError()})"
    end
  end
end

.update_resource(executable_filename) {|handle| ... } ⇒ Object

Yields:

  • (handle)


143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/ocran/ed_icon.rb', line 143

def update_resource(executable_filename)
  handle = BeginUpdateResourceW(executable_filename.encode("UTF-16LE"), 0)
  if handle == Fiddle::NULL
    raise "Failed to BeginUpdateResourceW(#{GetLastError()})"
  end

  yield(handle)

  if EndUpdateResourceW(handle, 0) == 0
    raise "Failed to EndUpdateResourceW(#{GetLastError()})"
  end
end