lib/pwnlib/shellcraft/generators/x86/linux/syscall.rb
# encoding: ASCII-8BIT
# frozen_string_literal: true
require 'pwnlib/shellcraft/generators/x86/common/setregs'
require 'pwnlib/shellcraft/generators/x86/linux/linux'
require 'pwnlib/util/ruby'
module Pwnlib
module Shellcraft
module Generators
module X86
module Linux
# Assembly of +syscall+.
#
# @example
# context.arch = 'i386'
# puts shellcraft.syscall('SYS_open', 'esp', 0, 0)
# # /* call open("esp", 0, 0) */
# # push 5 /* (SYS_open) */
# # pop eax
# # mov ebx, esp
# # xor ecx, ecx /* 0 */
# # cdq /* edx=0 */
# # int 0x80
# #=> nil
def syscall(*arguments)
abi = ::Pwnlib::ABI::ABI.syscall
registers = abi.register_arguments
reg_ctx = registers.zip(arguments).to_h
syscall = arguments.first
if syscall.to_s.start_with?('SYS_')
fmt = "#{syscall.to_s[4..-1]}(%s)"
args = []
else
fmt = 'syscall(%s)'
args = [syscall ? syscall.inspect : '?']
end
# arg0 to arg5
1.upto(6) do |i|
args.push(arguments[i] ? arguments[i].inspect : '?')
end
args.pop while args.last == '?'
cat "/* call #{format(fmt, args.join(', '))} */"
cat Common.setregs(reg_ctx) if arguments.any? { |v| !v.nil? }
cat abi.syscall_str
end
end
end
end
end
end