Skip to content

Instantly share code, notes, and snippets.

@sergio-bobillier
Created March 26, 2025 18:37
Show Gist options
  • Save sergio-bobillier/635703d8de718d27736f777b7f5ac707 to your computer and use it in GitHub Desktop.
Save sergio-bobillier/635703d8de718d27736f777b7f5ac707 to your computer and use it in GitHub Desktop.
Getting an executable's version with Ruby
require 'fiddle'
require 'pry'
version_dll = Fiddle.dlopen('version.dll')
filename = 'C:/Tools/teraterm/ttermpro.exe'
get_file_version_info_size = Fiddle::Function.new(
version_dll['GetFileVersionInfoSize'],
[Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP],
Fiddle::TYPE_LONG
)
s = ''
vsize = get_file_version_info_size.call(filename, s)
puts [vsize, vsize.class]
buffer = "\x00" * vsize
get_file_version_info = Fiddle::Function.new(
version_dll['GetFileVersionInfo'],
[Fiddle::TYPE_VOIDP, Fiddle::TYPE_LONG, Fiddle::TYPE_LONG, Fiddle::TYPE_VOIDP],
Fiddle::TYPE_INT
)
result = get_file_version_info.call(filename, 0, vsize, buffer)
if !result.zero?
puts buffer
end
ver_query_value = Fiddle::Function.new(
version_dll['VerQueryValue'],
[Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP, Fiddle::TYPE_UINTPTR_T],
Fiddle::TYPE_INT
)
property = '\\'
address = '\x0' * Fiddle::SIZEOF_LONG
len = '\x0' * Fiddle::SIZEOF_INT
result = ver_query_value.call(buffer, property, Fiddle::Pointer.to_ptr(address), Fiddle::Pointer.to_ptr(len))
puts result
if !result.zero?
address = address.unpack('J').first
len = len.unpack('L').first
VS_FIXEDFILEINFO = Fiddle::CStructBuilder.create(
Fiddle::CStruct,
[Fiddle::TYPE_LONG] * 13,
[
'dwSignature', # DWORD
'dwStrucVersion', # DWORD
'dwFileVersionMS', # DWORD
'dwFileVersionLS', # DWORD
'dwProductVersionMS', # DWORD
'dwProductVersionLS', # DWORD
'dwFileFlagsMask', # DWORD
'dwFileFlags', # DWORD
'dwFileOS', # DWORD
'dwFileType', # DWORD
'dwFileSubtype', # DWORD
'dwFileDateMS', # DWORD
'dwFileDateLS' # DWORD
]
)
# TODO: Check that len == VS_FIXEDFILEINFO.size
struct = VS_FIXEDFILEINFO.new(address)
pv = struct.dwProductVersionMS
pv = pv << 32
pv = pv | struct.dwProductVersionLS
version = Array.new(4)
3.downto(0) do |index|
version[index] = pv & 0xffff
pv = pv >> 16
end
puts version.join('.')
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment