Skip to content

Instantly share code, notes, and snippets.

@shinh
Created October 24, 2024 02:02
Show Gist options
  • Save shinh/501a92de60eab88ca390a040a6cc5804 to your computer and use it in GitHub Desktop.
Save shinh/501a92de60eab88ca390a040a6cc5804 to your computer and use it in GitHub Desktop.
# http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html
require_relative 'binformat'
class FieldrefInfo < Binformat
endian :big
short :class_index
short :name_and_type_index
end
class MethodrefInfo < Binformat
endian :big
short :class_index
short :name_and_type_index
end
class InterfaceMethodrefInfo < Binformat
endian :big
short :class_index
short :name_and_type_index
end
class NameAndTypeInfo < Binformat
endian :big
short :name_index
short :descriptor_index
end
class Utf8Info < Binformat
endian :big
short :length
byte :bytes, :length
end
class CpInfo < Binformat
endian :big
CONSTANT_Class = 7
CONSTANT_Fieldref = 9
CONSTANT_Methodref = 10
CONSTANT_InterfaceMethodref = 11
CONSTANT_String = 8
CONSTANT_Integer = 3
CONSTANT_Float = 4
CONSTANT_Long = 5
CONSTANT_Double = 6
CONSTANT_NameAndType = 12
CONSTANT_Utf8 = 1
CONSTANT_NAMES = {
7 => 'Class',
9 => 'Fieldref',
10 => 'Methodref',
11 => 'InterfaceMethodref',
8 => 'String',
3 => 'Integer',
4 => 'Float',
5 => 'Long',
6 => 'Double',
12 => 'NameAndType',
1 => 'Utf8',
}
byte :tag
some {
$z = $z ? $z+1 : 1
puts "#$z: #{CONSTANT_NAMES[tag]}"
case tag
when CONSTANT_Class
short :class_info
when CONSTANT_Fieldref
struct FieldrefInfo, :fieldref_info
when CONSTANT_Methodref
struct MethodrefInfo, :methodref_info
when CONSTANT_InterfaceMethodref
struct InterfaceMethodrefInfo, :interfacemethodref_info
when CONSTANT_String
short :string_info
when CONSTANT_Integer
int :integer_info
when CONSTANT_Float
int :float_info
when CONSTANT_Long
byte :long_info, 8
when CONSTANT_Double
byte :double_info, 8
when CONSTANT_NameAndType
struct NameAndTypeInfo, :nameandtype_info
when CONSTANT_Utf8
struct Utf8Info, :utf8_info
else
raise tag.to_s + ': unknown CpInfo tag'
end
}
end
class AttributeInfo < Binformat
endian :big
short :attribute_name_index
int :attribute_length
byte :info, :attribute_length
end
class FieldInfo < Binformat
endian :big
short :access_flags
short :name_index
short :descriptor_index
short :attributes_count
struct AttributeInfo, :attributes, :attributes_count
end
class MethodInfo < Binformat
endian :big
short :access_flags
short :name_index
short :descriptor_index
short :attributes_count
struct AttributeInfo, :attributes, :attributes_count
end
class ClassFile < Binformat
endian :big
byte :magic, 4
short :minor_version
short :major_version
short :constant_pool_count
struct CpInfo, :constant_pool, proc{ constant_pool_count-1 }
short :access_flags
short :this_class
short :super_class
short :interfaces_count
short :interfaces, :interfaces_count
short :fields_count
struct FieldInfo, :fields, :fields_count
short :methods_count
struct MethodInfo, :methods, :methods_count
short :attributes_count
struct AttributeInfo, :attributes, :attributes_count
end
$BINFORMAT_PROVIDE = ClassFile
if $0 == __FILE__
require 'yaml'
cf = ClassFile.new
# p cf.parse(ARGF)
r = cf.parse(ARGF)
puts r.to_yaml
puts 'rest:'
p ARGF.read
puts show_binary(r)
File.open('out', 'w') do |of|
of.print(cf.dump(r))
end
end
require 'binformat'
class Phdr < Binformat
int :type;
int :offset;
addr :vaddr;
addr :paddr;
int :filesz;
int :memsz;
int :flags;
int :align;
end
class Shdr < Binformat
int :name
int :type
int :flags
addr :addr
int :offset
int :size
int :link
int :info
int :addralign
int :entsize
end
class ELF < Binformat
byte :magic, 4
byte :ident_class
byte :ident_data
byte :ident_version
byte :ident_osabi
byte :ident_rest, 8
short :type
short :machine
int :version
addr :entry
int :phoff
int :shoff
int :flags
short :ehsize
short :phentsize
short :phnum
short :shentsize
short :shnum
short :shstrndx
seek :phoff
struct Phdr, :phdr, :phnum
seek :shoff
struct Shdr, :shdr, :shnum
end
$BINFORMAT_PROVIDE = ELF
if $0 == __FILE__
require 'yaml'
cf = ELF.new
# p cf.parse(ARGF)
r = cf.parse(ARGF)
puts r.to_yaml
puts 'rest:'
p ARGF.read
# File.open('out', 'w') do |of|
# of.print(cf.dump(r))
# end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment