pwntools 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +4 -3
- data/Rakefile +3 -1
- data/lib/pwnlib/asm.rb +172 -2
- data/lib/pwnlib/constants/constants.rb +10 -3
- data/lib/pwnlib/context.rb +1 -3
- data/lib/pwnlib/elf/elf.rb +3 -3
- data/lib/pwnlib/errors.rb +30 -0
- data/lib/pwnlib/ext/helper.rb +1 -1
- data/lib/pwnlib/logger.rb +140 -2
- data/lib/pwnlib/pwn.rb +3 -0
- data/lib/pwnlib/reg_sort.rb +1 -1
- data/lib/pwnlib/shellcraft/generators/amd64/common/infloop.rb +9 -3
- data/lib/pwnlib/shellcraft/generators/amd64/common/pushstr_array.rb +6 -2
- data/lib/pwnlib/shellcraft/generators/amd64/common/setregs.rb +6 -2
- data/lib/pwnlib/shellcraft/generators/amd64/linux/cat.rb +23 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/execve.rb +6 -4
- data/lib/pwnlib/shellcraft/generators/amd64/linux/exit.rb +23 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/ls.rb +6 -2
- data/lib/pwnlib/shellcraft/generators/amd64/linux/open.rb +23 -0
- data/lib/pwnlib/shellcraft/generators/amd64/linux/sh.rb +6 -2
- data/lib/pwnlib/shellcraft/generators/amd64/linux/syscall.rb +6 -4
- data/lib/pwnlib/shellcraft/generators/i386/common/infloop.rb +9 -3
- data/lib/pwnlib/shellcraft/generators/i386/common/pushstr_array.rb +6 -2
- data/lib/pwnlib/shellcraft/generators/i386/common/setregs.rb +6 -2
- data/lib/pwnlib/shellcraft/generators/i386/linux/cat.rb +23 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/execve.rb +8 -4
- data/lib/pwnlib/shellcraft/generators/i386/linux/exit.rb +23 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/ls.rb +6 -2
- data/lib/pwnlib/shellcraft/generators/i386/linux/open.rb +23 -0
- data/lib/pwnlib/shellcraft/generators/i386/linux/sh.rb +6 -2
- data/lib/pwnlib/shellcraft/generators/i386/linux/syscall.rb +8 -4
- data/lib/pwnlib/shellcraft/generators/x86/linux/cat.rb +53 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/exit.rb +33 -0
- data/lib/pwnlib/shellcraft/generators/x86/linux/open.rb +46 -0
- data/lib/pwnlib/shellcraft/shellcraft.rb +3 -2
- data/lib/pwnlib/timer.rb +5 -2
- data/lib/pwnlib/tubes/process.rb +153 -0
- data/lib/pwnlib/tubes/serialtube.rb +112 -0
- data/lib/pwnlib/tubes/sock.rb +24 -25
- data/lib/pwnlib/tubes/tube.rb +191 -39
- data/lib/pwnlib/util/packing.rb +3 -9
- data/lib/pwnlib/version.rb +1 -1
- data/test/asm_test.rb +85 -2
- data/test/constants/constants_test.rb +2 -2
- data/test/data/echo.rb +2 -7
- data/test/elf/elf_test.rb +10 -15
- data/test/files/use_pwn.rb +2 -6
- data/test/logger_test.rb +38 -0
- data/test/shellcraft/linux/cat_test.rb +86 -0
- data/test/shellcraft/linux/syscalls/exit_test.rb +56 -0
- data/test/shellcraft/linux/syscalls/open_test.rb +86 -0
- data/test/shellcraft/shellcraft_test.rb +5 -4
- data/test/test_helper.rb +22 -2
- data/test/timer_test.rb +19 -1
- data/test/tubes/process_test.rb +99 -0
- data/test/tubes/serialtube_test.rb +165 -0
- data/test/tubes/sock_test.rb +20 -21
- data/test/tubes/tube_test.rb +86 -16
- metadata +75 -13
data/lib/pwnlib/util/packing.rb
CHANGED
@@ -71,9 +71,7 @@ module Pwnlib
|
|
71
71
|
end
|
72
72
|
else
|
73
73
|
if is_all
|
74
|
-
if number < 0
|
75
|
-
raise ArgumentError, "Can't pack negative number with bits='all' and signed=false"
|
76
|
-
end
|
74
|
+
raise ArgumentError, "Can't pack negative number with bits='all' and signed=false" if number < 0
|
77
75
|
bits = number.zero? ? 8 : ((number.bit_length - 1) | 7) + 1
|
78
76
|
end
|
79
77
|
|
@@ -136,9 +134,7 @@ module Pwnlib
|
|
136
134
|
signed = context.signed
|
137
135
|
bytes = (bits + 7) / 8
|
138
136
|
|
139
|
-
unless data.size == bytes
|
140
|
-
raise ArgumentError, "data.size=#{data.size} does not match with bits=#{bits}"
|
141
|
-
end
|
137
|
+
raise ArgumentError, "data.size=#{data.size} does not match with bits=#{bits}" unless data.size == bytes
|
142
138
|
|
143
139
|
data = data.reverse if endian == 'little'
|
144
140
|
data = data.unpack('C*')
|
@@ -200,9 +196,7 @@ module Pwnlib
|
|
200
196
|
|
201
197
|
bytes = bits / 8
|
202
198
|
|
203
|
-
if data.size % bytes != 0
|
204
|
-
raise ArgumentError, "data.size=#{data.size} must be a multiple of bytes=#{bytes}"
|
205
|
-
end
|
199
|
+
raise ArgumentError, "data.size=#{data.size} must be a multiple of bytes=#{bytes}" if data.size % bytes != 0
|
206
200
|
ret = []
|
207
201
|
(data.size / bytes).times do |idx|
|
208
202
|
x1 = idx * bytes
|
data/lib/pwnlib/version.rb
CHANGED
data/test/asm_test.rb
CHANGED
@@ -10,11 +10,19 @@ class AsmTest < MiniTest::Test
|
|
10
10
|
Asm = ::Pwnlib::Asm
|
11
11
|
|
12
12
|
def setup
|
13
|
-
skip 'Not test asm/disasm on Windows' if TTY::Platform.new.windows?
|
14
13
|
@shellcraft = ::Pwnlib::Shellcraft::Shellcraft.instance
|
15
14
|
end
|
16
15
|
|
16
|
+
def skip_windows
|
17
|
+
skip 'Not test asm/disasm on Windows' if TTY::Platform.new.windows?
|
18
|
+
end
|
19
|
+
|
20
|
+
def linux_only
|
21
|
+
skip 'ELF can only be executed on Linux' unless TTY::Platform.new.linux?
|
22
|
+
end
|
23
|
+
|
17
24
|
def test_i386_asm
|
25
|
+
skip_windows
|
18
26
|
context.local(arch: 'i386') do
|
19
27
|
assert_equal("\x90", Asm.asm('nop'))
|
20
28
|
assert_equal("\xeb\xfe", Asm.asm(@shellcraft.infloop))
|
@@ -26,6 +34,7 @@ class AsmTest < MiniTest::Test
|
|
26
34
|
end
|
27
35
|
|
28
36
|
def test_amd64_asm
|
37
|
+
skip_windows
|
29
38
|
context.local(arch: 'amd64') do
|
30
39
|
assert_equal("\x90", Asm.asm('nop'))
|
31
40
|
assert_equal("\xeb\xfe", Asm.asm(@shellcraft.infloop))
|
@@ -36,6 +45,7 @@ class AsmTest < MiniTest::Test
|
|
36
45
|
end
|
37
46
|
|
38
47
|
def test_i386_disasm
|
48
|
+
skip_windows
|
39
49
|
context.local(arch: 'i386') do
|
40
50
|
str = Asm.disasm("h\x01\x01\x01\x01\x814$ri\x01\x011\xd2"\
|
41
51
|
"Rj\x04Z\x01\xe2R\x89\xe2jhh///sh/binj\x0bX\x89\xe3\x89\xd1\x99\xcd\x80")
|
@@ -66,6 +76,7 @@ class AsmTest < MiniTest::Test
|
|
66
76
|
end
|
67
77
|
|
68
78
|
def test_amd64_disasm
|
79
|
+
skip_windows
|
69
80
|
context.local(arch: 'amd64') do
|
70
81
|
str = Asm.disasm("hri\x01\x01\x814$\x01\x01\x01\x011\xd2" \
|
71
82
|
"Rj\x08ZH\x01\xe2RH\x89\xe2jhH\xb8/bin///sPj;XH\x89\xe7H\x89\xd6\x99\x0f\x05", vma: 0xfff)
|
@@ -98,7 +109,79 @@ class AsmTest < MiniTest::Test
|
|
98
109
|
|
99
110
|
# To ensure coverage
|
100
111
|
def test_require
|
101
|
-
err = assert_raises(
|
112
|
+
err = assert_raises(::Pwnlib::Errors::DependencyError) do
|
113
|
+
Asm.__send__(:require_message, 'no_such_lib', 'meow')
|
114
|
+
end
|
102
115
|
assert_match(/meow/, err.message)
|
103
116
|
end
|
117
|
+
|
118
|
+
def make_elf_file(*args)
|
119
|
+
elf = Asm.make_elf(*args)
|
120
|
+
stream = StringIO.new(elf)
|
121
|
+
[elf, ::ELFTools::ELFFile.new(stream)]
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_make_elf
|
125
|
+
# create ELF and use ELFTools to test it
|
126
|
+
data = 'not important'
|
127
|
+
elf, elf_file = make_elf_file(data)
|
128
|
+
assert_equal('Intel 80386', elf_file.machine)
|
129
|
+
# check entry point contains data
|
130
|
+
assert_equal(data, elf[elf_file.header.e_entry - 0x08048000, data.size])
|
131
|
+
segment = elf_file.segments.first
|
132
|
+
assert(segment.readable? && segment.executable?)
|
133
|
+
|
134
|
+
# test to_file
|
135
|
+
temp_path = Asm.make_elf(data, to_file: true)
|
136
|
+
assert_equal(elf, IO.binread(temp_path))
|
137
|
+
File.unlink(temp_path)
|
138
|
+
|
139
|
+
# test block form
|
140
|
+
temp_path = Asm.make_elf(data) do |path|
|
141
|
+
assert(File.file?(path))
|
142
|
+
path
|
143
|
+
end
|
144
|
+
# check file removed
|
145
|
+
refute(File.exist?(temp_path))
|
146
|
+
|
147
|
+
# test vma
|
148
|
+
custom_base = 0x1234000
|
149
|
+
_, elf_file = make_elf_file(data, vma: custom_base)
|
150
|
+
assert_equal(custom_base, elf_file.segments.first.header.p_vaddr)
|
151
|
+
|
152
|
+
context.local(arch: :arm) do
|
153
|
+
_, elf_file = make_elf_file(data)
|
154
|
+
assert_equal(32, elf_file.header.elf_class)
|
155
|
+
assert_equal('ARM', elf_file.machine)
|
156
|
+
assert_equal(0x8000, elf_file.segments.first.header.p_vaddr)
|
157
|
+
end
|
158
|
+
|
159
|
+
context.local(arch: :vax) do
|
160
|
+
err = assert_raises(::Pwnlib::Errors::UnsupportedArchError) do
|
161
|
+
Asm.make_elf('')
|
162
|
+
end
|
163
|
+
assert_equal('Unknown machine type of architecture "vax".', err.message)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
# this test can be removed after method +run_shellcode+ being implemented
|
168
|
+
def test_make_elf_and_run
|
169
|
+
# run the ELF we created to make sure it works.
|
170
|
+
linux_only
|
171
|
+
|
172
|
+
# test supported architecture
|
173
|
+
{
|
174
|
+
i386: /08048000-08049000 r-xp/,
|
175
|
+
amd64: /00400000-00401000 r-xp/
|
176
|
+
}.each do |arch, regexp|
|
177
|
+
context.local(arch: arch) do
|
178
|
+
data = Asm.asm(@shellcraft.cat('/proc/self/maps') + @shellcraft.syscall('SYS_exit', 0))
|
179
|
+
Asm.make_elf(data) do |path|
|
180
|
+
Open3.popen2(path) do |_i, o, _t|
|
181
|
+
assert_match(regexp, o.gets)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
104
187
|
end
|
@@ -15,8 +15,8 @@ class ConstantsTest < MiniTest::Test
|
|
15
15
|
assert_equal('__NR_arch_prctl', Constants.__NR_arch_prctl.to_s)
|
16
16
|
assert_equal('Constant("(O_CREAT)", 0x40)', Constants.eval('O_CREAT').inspect)
|
17
17
|
assert_equal('Constant("(O_CREAT | O_WRONLY)", 0x41)', Constants.eval('O_CREAT | O_WRONLY').inspect)
|
18
|
-
err = assert_raises(
|
19
|
-
assert_equal('
|
18
|
+
err = assert_raises(::Pwnlib::Errors::ConstantNotFoundError) { Constants.eval('rax + rbx') }
|
19
|
+
assert_equal('Undefined constant(s): rax, rbx', err.message)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
data/test/data/echo.rb
CHANGED
@@ -2,14 +2,9 @@
|
|
2
2
|
|
3
3
|
require 'socket'
|
4
4
|
|
5
|
-
|
6
|
-
puts "Usage #{__FILE__} port"
|
7
|
-
exit 1
|
8
|
-
end
|
5
|
+
server = TCPServer.open('127.0.0.1', 0)
|
9
6
|
|
10
|
-
|
11
|
-
|
12
|
-
STDOUT.puts 'Start!'
|
7
|
+
STDOUT.puts "Start with port #{server.addr[1]}"
|
13
8
|
STDOUT.flush
|
14
9
|
|
15
10
|
client = server.accept
|
data/test/elf/elf_test.rb
CHANGED
@@ -6,11 +6,13 @@ require 'pwnlib/elf/elf'
|
|
6
6
|
require 'pwnlib/logger'
|
7
7
|
|
8
8
|
class ELFTest < MiniTest::Test
|
9
|
-
include ::Pwnlib::Logger
|
10
|
-
|
11
9
|
def setup
|
12
10
|
@path_of = ->(file) { File.join(__dir__, '..', 'data', 'elfs', file) }
|
13
|
-
@elf =
|
11
|
+
@elf = to_elf_silent('i386.prelro.elf')
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_elf_silent(filename)
|
15
|
+
log_null { ::Pwnlib::ELF::ELF.new(@path_of.call(filename), checksec: false) }
|
14
16
|
end
|
15
17
|
|
16
18
|
# check stdout when loaded
|
@@ -43,7 +45,7 @@ NX: NX enabled
|
|
43
45
|
PIE: No PIE (0x8048000)
|
44
46
|
EOS
|
45
47
|
|
46
|
-
nrelro_elf =
|
48
|
+
nrelro_elf = to_elf_silent('amd64.nrelro.elf')
|
47
49
|
assert_equal(<<-EOS.strip, nrelro_elf.checksec)
|
48
50
|
RELRO: No RELRO
|
49
51
|
Stack: Canary found
|
@@ -51,7 +53,7 @@ NX: NX enabled
|
|
51
53
|
PIE: No PIE (0x400000)
|
52
54
|
EOS
|
53
55
|
|
54
|
-
frelro_elf =
|
56
|
+
frelro_elf = to_elf_silent('amd64.frelro.elf')
|
55
57
|
assert_equal(<<-EOS.strip, frelro_elf.checksec)
|
56
58
|
RELRO: Full RELRO
|
57
59
|
Stack: Canary found
|
@@ -78,7 +80,7 @@ PIE: No PIE (0x400000)
|
|
78
80
|
assert_same(0x80483b0, @elf.plt.printf)
|
79
81
|
assert_same(0x80483f0, @elf.plt[:scanf])
|
80
82
|
|
81
|
-
elf =
|
83
|
+
elf = to_elf_silent('amd64.frelro.pie.elf')
|
82
84
|
assert_nil(elf.plt)
|
83
85
|
end
|
84
86
|
|
@@ -90,7 +92,7 @@ PIE: No PIE (0x400000)
|
|
90
92
|
@elf.address = new_address
|
91
93
|
assert_equal(old_main - old_address + new_address, @elf.symbols.main)
|
92
94
|
|
93
|
-
elf =
|
95
|
+
elf = to_elf_silent('i386.frelro.pie.elf')
|
94
96
|
assert_equal(0, elf.address)
|
95
97
|
assert_same(0x6c2, elf.symbols.main)
|
96
98
|
elf.address = 0xdeadbeef0000
|
@@ -99,7 +101,7 @@ PIE: No PIE (0x400000)
|
|
99
101
|
end
|
100
102
|
|
101
103
|
def test_static
|
102
|
-
elf =
|
104
|
+
elf = to_elf_silent('amd64.static.elf')
|
103
105
|
assert_equal(<<-EOS.strip, elf.checksec)
|
104
106
|
RELRO: Partial RELRO
|
105
107
|
Stack: Canary found
|
@@ -124,11 +126,4 @@ PIE: No PIE (0x400000)
|
|
124
126
|
assert_equal([0x1234001, 0x1392613], elf.search('ELF').to_a)
|
125
127
|
assert_equal(0x138d00b, elf.find('/bin/sh').next)
|
126
128
|
end
|
127
|
-
|
128
|
-
def log_stdout
|
129
|
-
old = log.instance_variable_get(:@logdev)
|
130
|
-
log.instance_variable_set(:@logdev, $stdout)
|
131
|
-
yield
|
132
|
-
log.instance_variable_set(:@logdev, old)
|
133
|
-
end
|
134
129
|
end
|
data/test/files/use_pwn.rb
CHANGED
@@ -8,12 +8,8 @@ require 'pwn'
|
|
8
8
|
context[arch: 'amd64']
|
9
9
|
|
10
10
|
raise 'pack fail' unless pack(1) == "\x01\0\0\0\0\0\0\0"
|
11
|
-
unless ::Pwnlib::Util::Fiddling.__send__(:context).object_id == context.object_id
|
12
|
-
|
13
|
-
end
|
14
|
-
unless ::Pwnlib::Context.context.object_id == context.object_id
|
15
|
-
raise 'not unique context'
|
16
|
-
end
|
11
|
+
raise 'not unique context' unless ::Pwnlib::Util::Fiddling.__send__(:context).object_id == context.object_id
|
12
|
+
raise 'not unique context' unless ::Pwnlib::Context.context.object_id == context.object_id
|
17
13
|
|
18
14
|
# Make sure things aren't polluting Object
|
19
15
|
begin
|
data/test/logger_test.rb
CHANGED
@@ -58,4 +58,42 @@ class LoggerTest < MiniTest::Test
|
|
58
58
|
meowmeowmeow
|
59
59
|
EOS
|
60
60
|
end
|
61
|
+
|
62
|
+
def test_dump
|
63
|
+
x = 2
|
64
|
+
y = 3
|
65
|
+
assert_equal(<<-EOS, @logger.dump(x + y, x * y))
|
66
|
+
[DUMP] (x + y) = 5, (x * y) = 6
|
67
|
+
EOS
|
68
|
+
|
69
|
+
libc = 0x7fc0bdd13000
|
70
|
+
# check if source code parsing works good
|
71
|
+
msg = @logger.dump(
|
72
|
+
libc # comment is ok
|
73
|
+
.to_s(16),
|
74
|
+
libc - libc
|
75
|
+
)
|
76
|
+
assert_equal(<<-EOS, msg)
|
77
|
+
[DUMP] libc.to_s(16) = "7fc0bdd13000", (libc - libc) = 0
|
78
|
+
EOS
|
79
|
+
|
80
|
+
libc = 0x7fc0bdd13000
|
81
|
+
assert_equal(<<-EOS, @logger.dump { libc.to_s(16) })
|
82
|
+
[DUMP] libc.to_s(16) = "7fc0bdd13000"
|
83
|
+
EOS
|
84
|
+
|
85
|
+
res = @logger.dump do
|
86
|
+
libc = 12_345_678
|
87
|
+
libc <<= 12
|
88
|
+
# comments will be ignored
|
89
|
+
libc.to_s # dummy line
|
90
|
+
libc.to_s(16)
|
91
|
+
end
|
92
|
+
assert_equal(<<-EOS, res)
|
93
|
+
[DUMP] libc = 12345678
|
94
|
+
libc = (libc << 12)
|
95
|
+
libc.to_s
|
96
|
+
libc.to_s(16) = "bc614e000"
|
97
|
+
EOS
|
98
|
+
end
|
61
99
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# encoding: ASCII-8BIT
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
require 'pwnlib/context'
|
6
|
+
require 'pwnlib/shellcraft/shellcraft'
|
7
|
+
|
8
|
+
class CatTest < MiniTest::Test
|
9
|
+
include ::Pwnlib::Context
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@shellcraft = ::Pwnlib::Shellcraft::Shellcraft.instance
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_amd64
|
16
|
+
context.local(arch: 'amd64') do
|
17
|
+
assert_equal(<<-'EOS', @shellcraft.cat('flag'))
|
18
|
+
/* push "flag\x00" */
|
19
|
+
push 0x67616c66
|
20
|
+
/* call open("rsp", "O_RDONLY", 0) */
|
21
|
+
push 2 /* (SYS_open) */
|
22
|
+
pop rax
|
23
|
+
mov rdi, rsp
|
24
|
+
xor esi, esi /* (O_RDONLY) */
|
25
|
+
cdq /* rdx=0 */
|
26
|
+
syscall
|
27
|
+
/* call sendfile(1, "rax", 0, 2147483647) */
|
28
|
+
push 1
|
29
|
+
pop rdi
|
30
|
+
mov rsi, rax
|
31
|
+
push 0x28 /* (SYS_sendfile) */
|
32
|
+
pop rax
|
33
|
+
mov r10d, 0x7fffffff
|
34
|
+
cdq /* rdx=0 */
|
35
|
+
syscall
|
36
|
+
EOS
|
37
|
+
assert_equal(<<-'EOS', @shellcraft.cat('flag', fd: 2))
|
38
|
+
/* push "flag\x00" */
|
39
|
+
push 0x67616c66
|
40
|
+
/* call open("rsp", "O_RDONLY", 0) */
|
41
|
+
push 2 /* (SYS_open) */
|
42
|
+
pop rax
|
43
|
+
mov rdi, rsp
|
44
|
+
xor esi, esi /* (O_RDONLY) */
|
45
|
+
cdq /* rdx=0 */
|
46
|
+
syscall
|
47
|
+
/* call sendfile(2, "rax", 0, 2147483647) */
|
48
|
+
push 2
|
49
|
+
pop rdi
|
50
|
+
mov rsi, rax
|
51
|
+
push 0x28 /* (SYS_sendfile) */
|
52
|
+
pop rax
|
53
|
+
mov r10d, 0x7fffffff
|
54
|
+
cdq /* rdx=0 */
|
55
|
+
syscall
|
56
|
+
EOS
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_i386
|
61
|
+
context.local(arch: 'i386') do
|
62
|
+
assert_equal(<<-'EOS', @shellcraft.cat('flag'))
|
63
|
+
/* push "flag\x00" */
|
64
|
+
push 1
|
65
|
+
dec byte ptr [esp]
|
66
|
+
push 0x67616c66
|
67
|
+
/* call open("esp", "O_RDONLY", 0) */
|
68
|
+
push 5 /* (SYS_open) */
|
69
|
+
pop eax
|
70
|
+
mov ebx, esp
|
71
|
+
xor ecx, ecx /* (O_RDONLY) */
|
72
|
+
cdq /* edx=0 */
|
73
|
+
int 0x80
|
74
|
+
/* call sendfile(1, "eax", 0, 2147483647) */
|
75
|
+
push 1
|
76
|
+
pop ebx
|
77
|
+
mov ecx, eax
|
78
|
+
xor eax, eax
|
79
|
+
mov al, 0xbb /* (SYS_sendfile) */
|
80
|
+
mov esi, 0x7fffffff
|
81
|
+
cdq /* edx=0 */
|
82
|
+
int 0x80
|
83
|
+
EOS
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# encoding: ASCII-8BIT
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
require 'pwnlib/context'
|
6
|
+
require 'pwnlib/shellcraft/shellcraft'
|
7
|
+
|
8
|
+
class ExitTest < MiniTest::Test
|
9
|
+
include ::Pwnlib::Context
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@shellcraft = ::Pwnlib::Shellcraft::Shellcraft.instance
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_amd64
|
16
|
+
context.local(arch: 'amd64') do
|
17
|
+
assert_equal(<<-'EOS', @shellcraft.exit)
|
18
|
+
/* call exit(0) */
|
19
|
+
push 0x3c /* (SYS_exit) */
|
20
|
+
pop rax
|
21
|
+
xor edi, edi /* 0 */
|
22
|
+
syscall
|
23
|
+
EOS
|
24
|
+
|
25
|
+
assert_equal(<<-'EOS', @shellcraft.exit(1))
|
26
|
+
/* call exit(1) */
|
27
|
+
push 0x3c /* (SYS_exit) */
|
28
|
+
pop rax
|
29
|
+
push 1
|
30
|
+
pop rdi
|
31
|
+
syscall
|
32
|
+
EOS
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_i386
|
37
|
+
context.local(arch: 'i386') do
|
38
|
+
assert_equal(<<-'EOS', @shellcraft.exit)
|
39
|
+
/* call exit(0) */
|
40
|
+
push 1 /* (SYS_exit) */
|
41
|
+
pop eax
|
42
|
+
xor ebx, ebx /* 0 */
|
43
|
+
int 0x80
|
44
|
+
EOS
|
45
|
+
|
46
|
+
assert_equal(<<-'EOS', @shellcraft.exit(1))
|
47
|
+
/* call exit(1) */
|
48
|
+
push 1 /* (SYS_exit) */
|
49
|
+
pop eax
|
50
|
+
push 1
|
51
|
+
pop ebx
|
52
|
+
int 0x80
|
53
|
+
EOS
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|