#
# Ronin ASM - A Ruby DSL for crafting Assembly programs and Shellcode.
#
# Copyright (c) 2007-2013 Hal Brodigan (postmodern.mod3 at gmail.com)
#
# This file is part of Ronin ASM.
#
# Ronin is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ronin is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ronin. If not, see
#
require 'ronin/asm/register'
require 'ronin/asm/immediate_operand'
require 'ronin/asm/memory_operand'
module Ronin
module ASM
module Syntax
#
# Abstract base-class for all Assembly Syntax classes.
#
class Common
# Bit sizes for various architectures
BITS = {
x86: 32,
amd64: 64,
}
#
# Emits a keyword.
#
# @param [Symbol] name
# Name of the keyword.
#
# @return [String]
# The formatted keyword.
#
def self.emit_keyword(name)
name.to_s
end
#
# Emits a register.
#
# @param [Register] reg
#
# @return [String]
# The formatted register.
#
# @abstract
#
def self.emit_register(reg)
end
#
# Emits an integer.
#
# @param [Integer] value
# The integer.
#
# @return [String]
# The formatted integer.
#
def self.emit_integer(value)
if value >= 0 then "0x%x" % value
else "-0x%x" % value.abs
end
end
#
# Emits a floating point number.
#
# @param [Float] value
# The number.
#
# @return [String]
# The formatted float.
#
# @abstract
#
def self.emit_float(value)
end
#
# Emits an immediate operand.
#
# @param [ImmediateOperand] op
# The immediate operand.
#
# @return [String]
# The formatted immediate operand.
#
# @abstract
#
def self.emit_immediate_operand(op)
end
#
# Emits an memory operand.
#
# @param [MemoryOperand] op
# The memory operand.
#
# @return [String]
# The formatted memory operand.
#
# @abstract
#
def self.emit_memory_operand(op)
end
#
# Emits an operand.
#
# @param [ImmediateOperand, MemoryOperand, Register, Symbol] op
# The operand.
#
# @return [String]
# The formatted operand.
#
def self.emit_operand(op)
case op
when ImmediateOperand then emit_immediate_operand(op)
when MemoryOperand then emit_memory_operand(op)
when Register then emit_register(op)
when Symbol then emit_keyword(op)
end
end
#
# Emits multiple operands.
#
# @param [Array] ops
# The Array of operands.
#
# @return [String]
# The formatted operands.
#
def self.emit_operands(ops)
ops.map { |op| emit_operand(op) }.join(",\t")
end
#
# Emits a label.
#
# @param [Symbol] name
# The name of the label.
#
# @return [String]
# The formatted label.
#
def self.emit_label(name)
"#{name}:"
end
#
# Emits an instruction.
#
# @param [Instruction] ins
# The instruction.
#
# @return [String]
# The formatted instruction.
#
# @abstract
#
def self.emit_instruction(ins)
end
#
# Emits a section name.
#
# @param [Symbol] name
# The section name.
#
# @return [String]
# The formatted section name.
#
# @since 0.2.0
#
def self.emit_section(name)
end
#
# Emits the program's prologue.
#
# @param [Program] program
# The program.
#
# @return [String]
# The formatted prologue.
#
# @since 0.2.0
#
def self.emit_prologue(program)
end
#
# Emits a program.
#
# @param [Program] program
# The program.
#
# @return [String]
# The formatted program.
#
def self.emit_program(program)
lines = [
emit_prologue(program),
emit_section(:text),
emit_label(:_start)
].compact
program.instructions.each do |ins|
case ins
when Symbol then lines << emit_label(ins)
when Instruction then lines << "\t#{emit_instruction(ins)}"
end
end
lines << ''
return lines.join($/)
end
end
end
end
end