Class: Metasm::Shellcode

Inherits:
ExeFormat show all
Defined in:
lib/metasm/exe_format/shellcode.rb

Overview

a shellcode is a simple sequence of instructions

Instance Attribute Summary collapse

Attributes inherited from ExeFormat

#cpu, #cursource, #disassembler, #encoded, #filename, #unique_labels_cache

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from ExeFormat

assemble, assemble_file, #assemble_resolve, #assemble_sequence, autoexe_load, #c_set_default_entrypoint, #compile_c, compile_c, compile_c_file, #curencoded, decode, decode_file, decode_file_header, decode_header, #decode_strz, #disassemble, #disassemble_fast_deep, #encode_file, #encode_string, #get_xrefs_rw, #get_xrefs_x, #label_at, load, load_file, #locallabels_bkw, #locallabels_fwd, #new_label, #parse, #parse_data, #parse_data_data, #parse_new_label, #read_c_attrs, #share_namespace, #shortname, #tune_cparser, #tune_prepro

Methods included from ExeFormat::IntToHash

#bits_from_hash, #bits_to_hash, #int_from_hash, #int_to_hash

Constructor Details

#initialize(cpu = nil, base_addr = nil) ⇒ Shellcode

Returns a new instance of Shellcode.



17
18
19
20
21
# File 'lib/metasm/exe_format/shellcode.rb', line 17

def initialize(cpu=nil, base_addr=nil)
  @base_addr = base_addr
  @source = []
  super(cpu)
end

Instance Attribute Details

#base_addrObject

the base address of the shellcode (nil if unspecified)



15
16
17
# File 'lib/metasm/exe_format/shellcode.rb', line 15

def base_addr
  @base_addr
end

#sourceObject

the array of source elements (Instr/Data etc)



13
14
15
# File 'lib/metasm/exe_format/shellcode.rb', line 13

def source
  @source
end

Class Method Details

.disassemble(cpu, str, eip = 0) ⇒ Object



85
86
87
88
# File 'lib/metasm/exe_format/shellcode.rb', line 85

def self.disassemble(cpu, str, eip=0)
  sc = decode(str, cpu)
  sc.disassemble(eip)
end

.withcpu(cpu) ⇒ Object

returns a virtual subclass of Shellcode whose cpu_from_headers will return cpu



108
109
110
111
112
# File 'lib/metasm/exe_format/shellcode.rb', line 108

def self.withcpu(cpu)
  c = Class.new(self)
  c.send(:define_method, :cpu_from_headers) { cpu }
  c
end

Instance Method Details

#addr_to_fileoff(addr) ⇒ Object



55
56
57
# File 'lib/metasm/exe_format/shellcode.rb', line 55

def addr_to_fileoff(addr)
  addr - (base_addr || 0)
end

#assemble(*a) ⇒ Object

encodes the source found in self.source appends it to self.encoded clears self.source the optional parameter may contain a binding used to fixup! self.encoded uses self.base_addr if it exists



68
69
70
71
72
73
# File 'lib/metasm/exe_format/shellcode.rb', line 68

def assemble(*a)
  parse(*a) if not a.empty?
  @encoded << assemble_sequence(@source, @cpu)
  @source.clear
  encode
end

#compile_setsection(src, section) ⇒ Object



96
97
# File 'lib/metasm/exe_format/shellcode.rb', line 96

def compile_setsection(src, section)
end

#decodeObject



82
83
# File 'lib/metasm/exe_format/shellcode.rb', line 82

def decode
end

#dump_section_header(addr, edata) ⇒ Object



99
100
101
# File 'lib/metasm/exe_format/shellcode.rb', line 99

def dump_section_header(addr, edata)
  ''
end

#each_section {|@encoded, (@base_addr || 0)| ... } ⇒ Object

Yields:



51
52
53
# File 'lib/metasm/exe_format/shellcode.rb', line 51

def each_section
  yield @encoded, (@base_addr || 0)
end

#encode(binding = {}) ⇒ Object



75
76
77
78
79
80
# File 'lib/metasm/exe_format/shellcode.rb', line 75

def encode(binding={})
  @encoded.fixup! binding
  @encoded.fixup @encoded.binding(@base_addr)
  @encoded.fill @encoded.rawsize
  self
end

#fileoff_to_addr(foff) ⇒ Object



59
60
61
# File 'lib/metasm/exe_format/shellcode.rb', line 59

def fileoff_to_addr(foff)
  foff + (base_addr || 0)
end

#get_default_entrypointsObject



103
104
105
# File 'lib/metasm/exe_format/shellcode.rb', line 103

def get_default_entrypoints
  [@base_addr || 0]
end

#get_section_at(addr) ⇒ Object



41
42
43
44
45
46
47
48
49
# File 'lib/metasm/exe_format/shellcode.rb', line 41

def get_section_at(addr)
  base = @base_addr || 0
  if not addr.kind_of? Integer
    [@encoded, addr] if @encoded.ptr = @encoded.export[addr]
  elsif addr >= base and addr < base + @encoded.virtsize
    @encoded.ptr = addr - base
    [@encoded, addr]
  end
end

#init_disassemblerObject



90
91
92
93
94
# File 'lib/metasm/exe_format/shellcode.rb', line 90

def init_disassembler
  d = super()
  d.function[:default] = @cpu.disassembler_default_func
  d
end

#parse_initObject



23
24
25
26
# File 'lib/metasm/exe_format/shellcode.rb', line 23

def parse_init
  @cursource = @source
  super()
end

#parse_parser_instruction(instr) ⇒ Object

allows definition of the base address



29
30
31
32
33
34
35
36
37
38
39
# File 'lib/metasm/exe_format/shellcode.rb', line 29

def parse_parser_instruction(instr)
  case instr.raw.downcase
  when '.base', '.baseaddr', '.base_addr'
    # ".base_addr <expression>"
    # expression should #reduce to integer
    @lexer.skip_space
    raise instr, 'syntax error' if not @base_addr = Expression.parse(@lexer).reduce
    raise instr, 'syntax error' if tok = @lexer.nexttok and tok.type != :eol
  else super(instr)
  end
end