Module: Pwnlib::Asm
- Included in:
- Pwn
- Defined in:
- lib/pwnlib/asm.rb
Overview
Convert assembly code to machine code and vice versa. Use two open-source projects keystone/capstone to asm/disasm.
Constant Summary collapse
- DEFAULT_VMA =
Default virtaul memory base address of architectures.
This address may be different by using different linker.
{ i386: 0x08048000, amd64: 0x400000, arm: 0x8000 }.freeze
Class Method Summary collapse
-
.asm(code, vma: 0) ⇒ String
Convert assembly code to machine code.
-
.disasm(data, vma: 0) ⇒ String
Disassembles a bytestring into human readable assembly.
-
.make_elf(data, vma: nil, to_file: false) {|path| ... } ⇒ String, Object
Builds an ELF file from executable code.
Class Method Details
.asm(code, vma: 0) ⇒ String
Convert assembly code to machine code.
107 108 109 110 |
# File 'lib/pwnlib/asm.rb', line 107 def asm(code, vma: 0) ('keystone_engine', install_keystone_guide) KeystoneEngine::Ks.new(ks_arch, ks_mode).asm(code, vma)[0] end |
.disasm(data, vma: 0) ⇒ String
Disassembles a bytestring into human readable assembly.
disasm depends on another open-source project - capstone, error will be raised if capstone is not intalled.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/pwnlib/asm.rb', line 62 def disasm(data, vma: 0) ('crabstone', install_crabstone_guide) # will raise error if require fail. cs = Crabstone::Disassembler.new(cs_arch, cs_mode) insts = cs.disasm(data, vma).map do |ins| [ins.address, ins.bytes, ins.mnemonic.to_s, ins.op_str.to_s] end max_dlen = format('%x', insts.last.first).size + 2 max_hlen = insts.map { |ins| ins[1].size }.max * 3 max_ilen = insts.map { |ins| ins[2].size }.max insts.reduce('') do |s, ins| hex_code = ins[1].map { |c| format('%02x', c) }.join(' ') inst = if ins[3].empty? ins[2] else format("%-#{max_ilen}s %s", ins[2], ins[3]) end s + format("%#{max_dlen}x: %-#{max_hlen}s %s\n", ins[0], hex_code, inst) end end |
.make_elf(data, vma: nil, to_file: false) {|path| ... } ⇒ String, Object
Builds an ELF file from executable code.
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/pwnlib/asm.rb', line 164 def make_elf(data, vma: nil, to_file: false) to_file ||= block_given? vma ||= DEFAULT_VMA[context.arch.to_sym] vma &= -0x1000 # ELF header # Program headers # <data> headers = create_elf_headers(vma) ehdr = headers[:elf_header] phdr = headers[:program_header] entry = ehdr.num_bytes + phdr.num_bytes ehdr.e_entry = entry + phdr.p_vaddr ehdr.e_phoff = ehdr.num_bytes phdr.p_filesz = phdr.p_memsz = entry + data.size elf = ehdr.to_binary_s + phdr.to_binary_s + data return elf unless to_file path = Dir::Tmpname.create(['pwn', '.elf']) do |temp| File.open(temp, 'wb', 0o750) { |f| f.write(elf) } end block_given? ? yield(path).tap { File.unlink(path) } : path end |