rubyx/lib/intel/core_extensions.rb

86 lines
1.5 KiB
Ruby

require "fiddle"
class Integer
def m
address = Intel::Address.new
address.offset = self
address
end
def inspect
"0x#{to_s 16}"
end if $DEBUG
end
class Array
def second
self[1]
end
def push_D integer
self.push(*[integer].pack("V").unpack("C4"))
end
def push_B integer
self << (integer & 255)
end
def push_W integer
self.push((integer & 255), (integer >> 8 & 255))
end
end
ASM = []
class Object
def assemble arg_count = 0, &block
asm = Intel::MachineCodeX86.new
# TODO: enter?
asm.ebp.push
asm.ebp.mov asm.esp
size = asm.stream.size
asm.instance_eval(&block)
if asm.stream.size == size # return nil
warn "returning nil for #{self}##{name}"
asm.eax.mov 4
end
asm.leave
asm.ret
code = asm.stream.pack("C*")
if $DEBUG then
path = "#{$$}.obj"
File.open path, "wb" do |f|
f.write code
end
puts code.unpack("C*").map { |n| "%02X" % n }.join(' ')
system "ndisasm -u #{path}"
File.unlink path
end
code
end
@@asm = {}
def asm(name, *args, &block)
code = @@asm[name] ||= assemble(&block).to_ptr
return execute_asm(code) # code is the function pointer, wrapped
end
# defasm :execute_asm, :code do
# eax.mov ebp + 0x0c # grab code
# eax.mov eax + 0x10 # unwrap function pointer field
# eax.mov eax.m # dereference the pointer
# eax.call # call the function pointer
# end
end