lib/pwnlib/shellcraft/generators/x86/linux/ls.rb
# encoding: ASCII-8BIT
# frozen_string_literal: true
require 'pwnlib/shellcraft/generators/x86/common/pushstr'
require 'pwnlib/shellcraft/generators/x86/linux/linux'
require 'pwnlib/shellcraft/generators/x86/linux/syscall'
module Pwnlib
module Shellcraft
module Generators
module X86
module Linux
# List files.
#
# @param [String] dir
# The relative path to be listed.
#
# @example
# context.arch = 'amd64'
# puts shellcraft.ls
# # /* push ".\x00" */
# # push 0x2e
# # /* call open("rsp", 0, 0) */
# # push 2 /* (SYS_open) */
# # pop rax
# # mov rdi, rsp
# # xor esi, esi /* 0 */
# # cdq /* rdx=0 */
# # syscall
# # /* call getdents("rax", "rsp", 4096) */
# # mov rdi, rax
# # push 0x4e /* (SYS_getdents) */
# # pop rax
# # mov rsi, rsp
# # xor edx, edx
# # mov dh, 0x1000 >> 8
# # syscall
# # /* call write(1, "rsp", "rax") */
# # push 1
# # pop rdi
# # mov rsi, rsp
# # mov rdx, rax
# # push 1 /* (SYS_write) */
# # pop rax
# # syscall
# #=> nil
#
# @note
# This shellcode will output the binary data returned by syscall +getdents+.
# Use {Pwnlib::Util::Getdents.parse} to parse the output.
def ls(dir = '.')
abi = ::Pwnlib::ABI::ABI.syscall
cat Common.pushstr(dir)
cat Linux.syscall('SYS_open', abi.stack_pointer, 0, 0)
# In x86, return value register is same as sysnr register.
ret = abi.register_arguments.first
# XXX(david942j): Will fixed size 0x1000 be an issue?
cat Linux.syscall('SYS_getdents', ret, abi.stack_pointer, 0x1000) # getdents(fd, buf, sz)
# Just write all the shits out
cat Linux.syscall('SYS_write', 1, abi.stack_pointer, ret)
end
end
end
end
end
end