class Metasm::MZ

Constants

MAGIC

Attributes

body[RW]

the EncodedData representing the content of the file

endianness[RW]
header[RW]
relocs[RW]

an array of Relocations - quite obscure

source[RW]

Public Class Methods

new(cpu=nil) click to toggle source
Calls superclass method Metasm::ExeFormat::new
# File metasm/exe_format/mz.rb, line 64
def initialize(cpu=nil)
        @endianness = cpu ? cpu.endianness : :little
        @relocs = []
        @header = Header.new
        @body = EncodedData.new
        @source = []
        super(cpu)
end

Public Instance Methods

assemble(*a) click to toggle source

assembles the source in the body, clears the source

# File metasm/exe_format/mz.rb, line 74
def assemble(*a)
        parse(*a) if not a.empty?
        @body << assemble_sequence(@source, @cpu)
        @body.fixup @body.binding
        # XXX should create @relocs here
        @source.clear
end
decode() click to toggle source
# File metasm/exe_format/mz.rb, line 156
def decode
        decode_header
        decode_relocs
        decode_body
end
decode_body() click to toggle source

decodes the main part of the program mostly defines the 'start' export, to point to the MZ entrypoint

# File metasm/exe_format/mz.rb, line 150
def decode_body
        @body = @encoded[@header.cparhdr*16...@header.cp*512+@header.cblp]
        @body.virtsize += @header.minalloc * 16
        @body.add_export 'start', @header.cs * 16 + @header.ip
end
decode_header() click to toggle source

decodes the MZ header from the current offset in self.encoded

# File metasm/exe_format/mz.rb, line 137
def decode_header
        @header.decode self
end
decode_relocs() click to toggle source

decodes the relocation table

# File metasm/exe_format/mz.rb, line 142
def decode_relocs
        @relocs.clear
        @encoded.ptr = @header.lfarlc
        @header.crlc.times { @relocs << Relocation.decode(self) }
end
decode_word(edata = @encoded) click to toggle source

decodes a 16bits word from self.encoded

# File metasm/exe_format/mz.rb, line 54
def decode_word(edata = @encoded) edata.decode_imm(:u16, @endianness) end
each_section() { |body, 0| ... } click to toggle source
# File metasm/exe_format/mz.rb, line 162
def each_section
        yield @body, 0
end
encode() click to toggle source

concats the header, relocation table and body

# File metasm/exe_format/mz.rb, line 116
def encode
        pre_encode.inject(@encoded) { |edata, pe| edata << pe }
        @encoded.fixup @encoded.binding
        encode_fix_checksum
end
encode_fix_checksum() click to toggle source

sets the file checksum (untested)

# File metasm/exe_format/mz.rb, line 123
def encode_fix_checksum
        @encoded.ptr = 0
        decode_header
        mzlen = @header.cp * 512 + @header.cblp
        @encoded.ptr = 0
        csum = -@header.csum
        (mzlen/2).times { csum += decode_word }
        csum &= 0xffff
        @header.csum = csum
        hdr = @header.encode(self, nil)
        @encoded[0, hdr.length] = hdr
end
encode_word(val) click to toggle source

encodes a word in 16 bits

# File metasm/exe_format/mz.rb, line 52
def encode_word(val)        Expression[val].encode(:u16, @endianness) end
parse_init() click to toggle source

sets up @cursource

Calls superclass method Metasm::ExeFormat#parse_init
# File metasm/exe_format/mz.rb, line 83
def parse_init
        @cursource = @source
        super()
end
parse_parser_instruction(instr) click to toggle source

defines the exe-specific parser instructions: .entrypoint [<label>]: defines the program entrypoint to label (or create a new label at this location)

# File metasm/exe_format/mz.rb, line 97
def parse_parser_instruction(instr)
        case instr.raw.downcase
        when '.entrypoint'
                # ".entrypoint <somelabel/expression>" or ".entrypoint" (here)
                @lexer.skip_space
                if tok = @lexer.nexttok and tok.type == :string
                        raise instr, 'syntax error' if not entrypoint = Expression.parse(@lexer)
                else
                        entrypoint = new_label('entrypoint')
                        @cursource << Label.new(entrypoint, instr.backtrace.dup)
                end
                @header.ip = Expression[entrypoint, :-, label_at(@body, 0, 'body')]
                @lexer.skip_space
                raise instr, 'eol expected' if t = @lexer.nexttok and t.type != :eol
        end
end
pre_encode() click to toggle source

encodes the header and the relocation table, return them in an array, with the body.

# File metasm/exe_format/mz.rb, line 89
def pre_encode
        relocs = @relocs.inject(EncodedData.new) { |edata, r| edata << r.encode(self) }
        header = @header.encode self, relocs
        [header, relocs, @body]
end
sizeof_word() click to toggle source
# File metasm/exe_format/mz.rb, line 55
def sizeof_word ; 2 ; end