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.
Files changed (60) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +4 -3
  3. data/Rakefile +3 -1
  4. data/lib/pwnlib/asm.rb +172 -2
  5. data/lib/pwnlib/constants/constants.rb +10 -3
  6. data/lib/pwnlib/context.rb +1 -3
  7. data/lib/pwnlib/elf/elf.rb +3 -3
  8. data/lib/pwnlib/errors.rb +30 -0
  9. data/lib/pwnlib/ext/helper.rb +1 -1
  10. data/lib/pwnlib/logger.rb +140 -2
  11. data/lib/pwnlib/pwn.rb +3 -0
  12. data/lib/pwnlib/reg_sort.rb +1 -1
  13. data/lib/pwnlib/shellcraft/generators/amd64/common/infloop.rb +9 -3
  14. data/lib/pwnlib/shellcraft/generators/amd64/common/pushstr_array.rb +6 -2
  15. data/lib/pwnlib/shellcraft/generators/amd64/common/setregs.rb +6 -2
  16. data/lib/pwnlib/shellcraft/generators/amd64/linux/cat.rb +23 -0
  17. data/lib/pwnlib/shellcraft/generators/amd64/linux/execve.rb +6 -4
  18. data/lib/pwnlib/shellcraft/generators/amd64/linux/exit.rb +23 -0
  19. data/lib/pwnlib/shellcraft/generators/amd64/linux/ls.rb +6 -2
  20. data/lib/pwnlib/shellcraft/generators/amd64/linux/open.rb +23 -0
  21. data/lib/pwnlib/shellcraft/generators/amd64/linux/sh.rb +6 -2
  22. data/lib/pwnlib/shellcraft/generators/amd64/linux/syscall.rb +6 -4
  23. data/lib/pwnlib/shellcraft/generators/i386/common/infloop.rb +9 -3
  24. data/lib/pwnlib/shellcraft/generators/i386/common/pushstr_array.rb +6 -2
  25. data/lib/pwnlib/shellcraft/generators/i386/common/setregs.rb +6 -2
  26. data/lib/pwnlib/shellcraft/generators/i386/linux/cat.rb +23 -0
  27. data/lib/pwnlib/shellcraft/generators/i386/linux/execve.rb +8 -4
  28. data/lib/pwnlib/shellcraft/generators/i386/linux/exit.rb +23 -0
  29. data/lib/pwnlib/shellcraft/generators/i386/linux/ls.rb +6 -2
  30. data/lib/pwnlib/shellcraft/generators/i386/linux/open.rb +23 -0
  31. data/lib/pwnlib/shellcraft/generators/i386/linux/sh.rb +6 -2
  32. data/lib/pwnlib/shellcraft/generators/i386/linux/syscall.rb +8 -4
  33. data/lib/pwnlib/shellcraft/generators/x86/linux/cat.rb +53 -0
  34. data/lib/pwnlib/shellcraft/generators/x86/linux/exit.rb +33 -0
  35. data/lib/pwnlib/shellcraft/generators/x86/linux/open.rb +46 -0
  36. data/lib/pwnlib/shellcraft/shellcraft.rb +3 -2
  37. data/lib/pwnlib/timer.rb +5 -2
  38. data/lib/pwnlib/tubes/process.rb +153 -0
  39. data/lib/pwnlib/tubes/serialtube.rb +112 -0
  40. data/lib/pwnlib/tubes/sock.rb +24 -25
  41. data/lib/pwnlib/tubes/tube.rb +191 -39
  42. data/lib/pwnlib/util/packing.rb +3 -9
  43. data/lib/pwnlib/version.rb +1 -1
  44. data/test/asm_test.rb +85 -2
  45. data/test/constants/constants_test.rb +2 -2
  46. data/test/data/echo.rb +2 -7
  47. data/test/elf/elf_test.rb +10 -15
  48. data/test/files/use_pwn.rb +2 -6
  49. data/test/logger_test.rb +38 -0
  50. data/test/shellcraft/linux/cat_test.rb +86 -0
  51. data/test/shellcraft/linux/syscalls/exit_test.rb +56 -0
  52. data/test/shellcraft/linux/syscalls/open_test.rb +86 -0
  53. data/test/shellcraft/shellcraft_test.rb +5 -4
  54. data/test/test_helper.rb +22 -2
  55. data/test/timer_test.rb +19 -1
  56. data/test/tubes/process_test.rb +99 -0
  57. data/test/tubes/serialtube_test.rb +165 -0
  58. data/test/tubes/sock_test.rb +20 -21
  59. data/test/tubes/tube_test.rb +86 -16
  60. metadata +75 -13
@@ -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 OpenTest < 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.open('/etc/passwd'))
18
+ /* push "/etc/passwd\x00" */
19
+ push 0x1010101 ^ 0x647773
20
+ xor dword ptr [rsp], 0x1010101
21
+ mov rax, 0x7361702f6374652f
22
+ push rax
23
+ /* call open("rsp", "O_RDONLY", 0) */
24
+ push 2 /* (SYS_open) */
25
+ pop rax
26
+ mov rdi, rsp
27
+ xor esi, esi /* (O_RDONLY) */
28
+ cdq /* rdx=0 */
29
+ syscall
30
+ EOS
31
+
32
+ assert_equal(<<-'EOS', @shellcraft.open('/etc/passwd', 0x40, 0o750)) # O_CREAT = 0x40
33
+ /* push "/etc/passwd\x00" */
34
+ push 0x1010101 ^ 0x647773
35
+ xor dword ptr [rsp], 0x1010101
36
+ mov rax, 0x7361702f6374652f
37
+ push rax
38
+ /* call open("rsp", 64, 488) */
39
+ push 2 /* (SYS_open) */
40
+ pop rax
41
+ mov rdi, rsp
42
+ push 0x40
43
+ pop rsi
44
+ xor edx, edx
45
+ mov dx, 0x1e8
46
+ syscall
47
+ EOS
48
+ end
49
+ end
50
+
51
+ def test_i386
52
+ context.local(arch: 'i386') do
53
+ assert_equal(<<-'EOS', @shellcraft.open('/etc/passwd'))
54
+ /* push "/etc/passwd\x00" */
55
+ push 0x1010101
56
+ xor dword ptr [esp], 0x1657672 /* 0x1010101 ^ 0x647773 */
57
+ push 0x7361702f
58
+ push 0x6374652f
59
+ /* call open("esp", "O_RDONLY", 0) */
60
+ push 5 /* (SYS_open) */
61
+ pop eax
62
+ mov ebx, esp
63
+ xor ecx, ecx /* (O_RDONLY) */
64
+ cdq /* edx=0 */
65
+ int 0x80
66
+ EOS
67
+
68
+ assert_equal(<<-'EOS', @shellcraft.open('/etc/passwd', 'O_CREAT', 0o750))
69
+ /* push "/etc/passwd\x00" */
70
+ push 0x1010101
71
+ xor dword ptr [esp], 0x1657672 /* 0x1010101 ^ 0x647773 */
72
+ push 0x7361702f
73
+ push 0x6374652f
74
+ /* call open("esp", "O_CREAT", 488) */
75
+ push 5 /* (SYS_open) */
76
+ pop eax
77
+ mov ebx, esp
78
+ push 0x40 /* (O_CREAT) */
79
+ pop ecx
80
+ xor edx, edx
81
+ mov dx, 0x1e8
82
+ int 0x80
83
+ EOS
84
+ end
85
+ end
86
+ end
@@ -15,14 +15,15 @@ class ShellcraftTest < MiniTest::Test
15
15
  def test_respond
16
16
  context.local(arch: 'amd64') do
17
17
  # Check respond_to_missing? is well defined
18
- assert @shellcraft.respond_to?(:mov)
19
- assert @shellcraft.method(:sh)
18
+ assert(@shellcraft.respond_to?(:mov))
19
+ assert(@shellcraft.method(:sh))
20
20
  end
21
- refute @shellcraft.respond_to?(:linux)
21
+ refute(@shellcraft.respond_to?(:linux))
22
22
  assert_raises(NoMethodError) { @shellcraft.meow }
23
23
 
24
24
  context.local(arch: 'arm') do
25
- refute @shellcraft.respond_to?(:mov)
25
+ err = assert_raises(::Pwnlib::Errors::UnsupportedArchError) { @shellcraft.respond_to?(:mov) }
26
+ assert_equal("Can't use shellcraft under architecture \"arm\".", err.message)
26
27
  end
27
28
  end
28
29
  end
@@ -1,9 +1,8 @@
1
- require 'codeclimate-test-reporter'
2
1
  require 'rainbow'
3
2
  require 'simplecov'
4
3
 
5
4
  SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(
6
- [SimpleCov::Formatter::HTMLFormatter, CodeClimate::TestReporter::Formatter]
5
+ [SimpleCov::Formatter::HTMLFormatter]
7
6
  )
8
7
  SimpleCov.start do
9
8
  add_filter '/test/'
@@ -20,5 +19,26 @@ module MiniTest
20
19
  # Default to disable coloring for easier testing.
21
20
  Rainbow.enabled = false
22
21
  end
22
+
23
+ # Methods for hooking logger,
24
+ # require 'pwnlib/logger' before using these methods.
25
+
26
+ def log_null(&block)
27
+ File.open(File::NULL, 'w') { |f| log_hook(f, &block) }
28
+ end
29
+
30
+ def log_stdout(&block)
31
+ log_hook($stdout, &block)
32
+ end
33
+
34
+ def log_hook(obj)
35
+ old = ::Pwnlib::Logger.log.instance_variable_get(:@logdev)
36
+ ::Pwnlib::Logger.log.instance_variable_set(:@logdev, obj)
37
+ begin
38
+ yield
39
+ ensure
40
+ ::Pwnlib::Logger.log.instance_variable_set(:@logdev, old)
41
+ end
42
+ end
23
43
  end
24
44
  end
@@ -12,12 +12,30 @@ class TimerTest < MiniTest::Test
12
12
  refute(t.started?)
13
13
  refute(t.active?)
14
14
  assert_equal('DARKHH QQ', t.countdown(0.1) { 'DARKHH QQ' })
15
+
15
16
  exception = assert_raises(RuntimeError) { t.countdown(0.1) { t.countdown(0.1) {} } }
16
17
  assert_equal('Nested countdown not permitted', exception.message)
18
+
17
19
  t.timeout = 0.514
18
- exception = assert_raises(RuntimeError) { t.countdown(0.1) { t.timeout = :forever } }
20
+ exception = assert_raises(RuntimeError) do
21
+ t.countdown(0.1) { t.timeout = :forever }
22
+ end
19
23
  assert_equal("Can't change timeout when countdown", exception.message)
24
+
20
25
  t.countdown(0.1) { assert(t.started?) }
21
26
  t.countdown(0.1) { assert(t.active?) }
27
+
28
+ assert_raises(::Pwnlib::Errors::TimeoutError) do
29
+ t.countdown(0.1) { sleep(0.2) }
30
+ end
31
+ end
32
+
33
+ # Check #115 fixed
34
+ def test_nested_countdown_false_positve_115
35
+ t = Timer.new
36
+ assert_raises(::Pwnlib::Errors::TimeoutError) do
37
+ t.countdown(0.01) { sleep(0.02) }
38
+ end
39
+ t.countdown(0.01) {}
22
40
  end
23
41
  end
@@ -0,0 +1,99 @@
1
+ # encoding: ASCII-8BIT
2
+
3
+ require 'socket'
4
+ require 'tty-platform'
5
+
6
+ require 'test_helper'
7
+
8
+ require 'pwnlib/context'
9
+ require 'pwnlib/errors'
10
+ require 'pwnlib/tubes/process'
11
+
12
+ class ProcessTest < MiniTest::Test
13
+ include ::Pwnlib::Context
14
+
15
+ def setup
16
+ skip 'Skip on Windows' if TTY::Platform.new.windows?
17
+ end
18
+
19
+ def test_io
20
+ cat = ::Pwnlib::Tubes::Process.new('cat')
21
+ cat.puts('HAHA')
22
+ assert_equal("HAHA\n", cat.gets)
23
+ assert_raises(::Pwnlib::Errors::TimeoutError) { cat.gets(timeout: 0.1) }
24
+ cat.puts('HAHA2')
25
+ assert_equal("HAHA2\n", cat.gets)
26
+ end
27
+
28
+ def test_env
29
+ data = ::Pwnlib::Tubes::Process.new('env').read
30
+ assert_match('PATH=', data)
31
+ data = ::Pwnlib::Tubes::Process.new('env', env: { 'FOO' => 'BAR' }).read
32
+ assert_equal("FOO=BAR\n", data)
33
+ end
34
+
35
+ def test_aslr
36
+ skip 'Only tested on linux' unless TTY::Platform.new.linux?
37
+ map1 = ::Pwnlib::Tubes::Process.new('cat /proc/self/maps', aslr: false).read
38
+ map2 = ::Pwnlib::Tubes::Process.new(['cat', '/proc/self/maps'], aslr: false).read
39
+ assert_match('/bin/cat', map1) # make sure it read something
40
+ assert_equal(map1, map2)
41
+ end
42
+
43
+ def test_eof
44
+ ls = ::Pwnlib::Tubes::Process.new(['ls', '-la'])
45
+ assert_match(/total/, ls.gets)
46
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { ls.write('anything') }
47
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { loop { ls.gets } }
48
+ end
49
+
50
+ def test_shutdown
51
+ cat = ::Pwnlib::Tubes::Process.new('cat')
52
+ assert_raises(::Pwnlib::Errors::TimeoutError) { cat.recvn(1, timeout: 0.1) }
53
+ cat.shutdown(:write) # This should cause `cat` dead
54
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { cat.recvn(1, timeout: 0.1) }
55
+ cat.shutdown
56
+
57
+ cat = ::Pwnlib::Tubes::Process.new('cat')
58
+ cat.shutdown(:read)
59
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { cat.recvn(1) }
60
+ cat.shutdown
61
+ assert_raises(ArgumentError) { cat.shutdown(:zz) }
62
+ end
63
+
64
+ def test_kill
65
+ cat = ::Pwnlib::Tubes::Process.new('cat')
66
+ cat.kill
67
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { cat.recvn(1) }
68
+ end
69
+
70
+ def test_tty
71
+ tty_test = proc do |*args, raw: true|
72
+ in_, out = args.map { |v| v ? :pty : :pipe }
73
+ process = ::Pwnlib::Tubes::Process.new('ruby -e "p [STDIN.tty?, STDOUT.tty?]"',
74
+ in: in_, out: out, raw: raw)
75
+ process.gets
76
+ end
77
+ assert_equal("[false, false]\n", tty_test.call(false, false))
78
+ assert_equal("[true, false]\n", tty_test.call(true, false))
79
+ assert_equal("[false, true]\n", tty_test.call(false, true))
80
+ assert_equal("[false, true]\r\n", tty_test.call(false, true, raw: false))
81
+
82
+ cat = ::Pwnlib::Tubes::Process.new('cat', in: :pty, out: :pty, raw: false)
83
+ cat.puts('Hi')
84
+ # In cooked mode, tty should echo the input, so we can gets twice.
85
+ assert_equal("Hi\r\n", cat.gets)
86
+ assert_equal("Hi\r\n", cat.gets)
87
+ cat.close
88
+ end
89
+
90
+ def test_interact
91
+ ls = ::Pwnlib::Tubes::Process.new('ls Gemfile*')
92
+ saved = $stdin
93
+ # prevents stdin being closed
94
+ $stdin = UDPSocket.new
95
+ assert_output("Gemfile\nGemfile.lock\n") { context.local(log_level: :fatal) { ls.interact } }
96
+ $stdin.close
97
+ $stdin = saved
98
+ end
99
+ end
@@ -0,0 +1,165 @@
1
+ # encoding: ASCII-8BIT
2
+
3
+ require 'open3'
4
+
5
+ require 'test_helper'
6
+
7
+ require 'pwnlib/tubes/serialtube'
8
+
9
+ module Pwnlib
10
+ module Tubes
11
+ class SerialTube
12
+ def break_encapsulation
13
+ @conn.close
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ class SerialTest < MiniTest::Test
20
+ include ::Pwnlib::Tubes
21
+
22
+ def skip_windows
23
+ skip 'Not test tube/serialtube on Windows' if TTY::Platform.new.windows?
24
+ end
25
+
26
+ def open_pair
27
+ Open3.popen3('socat -d -d pty,raw,echo=0 pty,raw,echo=0') do |_i, _o, stderr, thread|
28
+ devs = []
29
+ 2.times do
30
+ devs << stderr.readline.chomp.split.last
31
+ # First pattern matches Linux, second is macOS
32
+ raise IOError, 'Could not create serial crosslink' if devs.last !~ %r{^(/dev/pts/[0-9]+|/dev/ttys[0-9]+)$}
33
+ end
34
+ # To ensure socat have finished setup
35
+ stderr.gets('starting data transfer loop')
36
+
37
+ serial = SerialTube.new devs[1], convert_newlines: false
38
+
39
+ begin
40
+ File.open devs[0], 'r+' do |file|
41
+ file.set_encoding 'default'.encoding
42
+ yield file, serial, thread
43
+ end
44
+ ensure
45
+ ::Process.kill('SIGTERM', thread.pid) if thread.alive?
46
+ end
47
+ end
48
+ end
49
+
50
+ def random_string(length)
51
+ Random.rand(36**length).to_s(36).rjust(length, '0')
52
+ end
53
+
54
+ def test_raise
55
+ skip_windows
56
+ open_pair do |_file, serial, thread|
57
+ ::Process.kill('SIGTERM', thread.pid)
58
+ # ensure the process has been killed
59
+ thread.value
60
+ assert_raises(Pwnlib::Errors::EndOfTubeError) { serial.puts('a') }
61
+ end
62
+ open_pair do |_file, serial|
63
+ serial.break_encapsulation
64
+ assert_raises(Pwnlib::Errors::EndOfTubeError) { serial.recv(1, timeout: 2) }
65
+ end
66
+ end
67
+
68
+ def test_recv
69
+ skip_windows
70
+ open_pair do |file, serial|
71
+ # recv, recvline
72
+ rs = random_string 24
73
+ file.puts rs
74
+ result = serial.recv 8, timeout: 1
75
+
76
+ assert_equal(rs[0...8], result)
77
+ result = serial.recv 8
78
+ assert_equal(rs[8...16], result)
79
+ result = serial.recvline.chomp
80
+ assert_equal(rs[16..-1], result)
81
+
82
+ assert_raises(Pwnlib::Errors::TimeoutError) { serial.recv(1, timeout: 0.2) }
83
+
84
+ # recvpred
85
+ rs = random_string 12
86
+ file.print rs
87
+ result = serial.recvpred do |data|
88
+ data[-6..-1] == rs[-6..-1]
89
+ end
90
+ assert_equal rs, result
91
+
92
+ assert_raises(Pwnlib::Errors::TimeoutError) { serial.recv(1, timeout: 0.2) }
93
+
94
+ # recvn
95
+ rs = random_string 6
96
+ file.print rs
97
+ result = ''
98
+ assert_raises(Pwnlib::Errors::TimeoutError) do
99
+ result = serial.recvn 120, timeout: 1
100
+ end
101
+ assert_empty result
102
+ file.print rs
103
+ result = serial.recvn 12
104
+ assert_equal rs * 2, result
105
+
106
+ assert_raises(Pwnlib::Errors::TimeoutError) { serial.recv(1, timeout: 0.2) }
107
+
108
+ # recvuntil
109
+ rs = random_string 12
110
+ file.print rs + '|'
111
+ result = serial.recvuntil('|').chomp('|')
112
+ assert_equal rs, result
113
+
114
+ assert_raises(Pwnlib::Errors::TimeoutError) { serial.recv(1, timeout: 0.2) }
115
+
116
+ # gets
117
+ rs = random_string 24
118
+ file.puts rs
119
+ result = serial.gets 12
120
+ assert_equal rs[0...12], result
121
+ result = serial.gets.chomp
122
+ assert_equal rs[12..-1], result
123
+
124
+ assert_raises(Pwnlib::Errors::TimeoutError) { serial.recv(1, timeout: 0.2) }
125
+ end
126
+ end
127
+
128
+ def test_send
129
+ skip_windows
130
+ open_pair do |file, serial|
131
+ # send, sendline
132
+ rs = random_string 24
133
+ # rubocop:disable Style/Send
134
+ # Justification: This isn't Object#send, false positive.
135
+ serial.send rs[0...12]
136
+ # rubocop:enable Style/Send
137
+ serial.sendline rs[12...24]
138
+ result = file.readline.chomp
139
+ assert_equal rs, result
140
+
141
+ # puts
142
+ r1 = random_string 4
143
+ r2 = random_string 4
144
+ r3 = random_string 4
145
+ serial.puts r1, r2, r3
146
+ result = ''
147
+ 3.times do
148
+ result += file.readline.chomp
149
+ end
150
+ assert_equal r1 + r2 + r3, result
151
+ end
152
+ end
153
+
154
+ def test_close
155
+ skip_windows
156
+ open_pair do |_file, serial|
157
+ serial.close
158
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { serial.puts(514) }
159
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { serial.puts(514) }
160
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { serial.recv }
161
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { serial.recv }
162
+ assert_raises(ArgumentError) { serial.close(:hh) }
163
+ end
164
+ end
165
+ end
@@ -9,46 +9,45 @@ require 'pwnlib/tubes/sock'
9
9
  class SockTest < MiniTest::Test
10
10
  include ::Pwnlib::Tubes
11
11
  ECHO_FILE = File.expand_path('../data/echo.rb', __dir__)
12
- BIND_PORT = 31_337
13
12
 
14
13
  def popen_echo(data)
15
- Open3.popen2("bundle exec ruby #{ECHO_FILE} #{BIND_PORT}") do |_i, o, _t|
16
- o.gets
17
- s = Sock.new('localhost', BIND_PORT)
14
+ Open3.popen2("ruby #{ECHO_FILE}") do |_i, o, _t|
15
+ port = o.gets.split.last.to_i
16
+ s = Sock.new('127.0.0.1', port)
18
17
  yield s, data, o
19
18
  end
20
19
  end
21
20
 
22
- def test_io
21
+ def test_sock
23
22
  popen_echo('DARKHH') do |s, data, _o|
24
- s.io.puts(data)
25
- rs, = IO.select([s.io])
23
+ s.sock.puts(data)
24
+ rs, = IO.select([s.sock])
26
25
  refute_nil(rs)
27
- assert_equal(data, s.io.readpartial(data.size))
26
+ assert_equal(data, s.sock.readpartial(data.size))
28
27
  end
29
28
  end
30
29
 
31
- def test_sock
30
+ def test_eof
32
31
  popen_echo('DARKHH') do |s, data, o|
33
32
  s.puts(data)
34
33
  assert_equal(data + "\n", s.gets)
35
34
  o.gets
36
35
  s.puts(514)
37
36
  sleep(0.1) # Wait for connection reset
38
- assert_raises(EOFError) { s.puts(514) }
39
- assert_raises(EOFError) { s.puts(514) }
40
- assert_raises(EOFError) { s.recv }
41
- assert_raises(EOFError) { s.recv }
37
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.puts(514) }
38
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.puts(514) }
39
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.recv }
40
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.recv }
42
41
  end
43
42
  end
44
43
 
45
44
  def test_close
46
45
  popen_echo('DARKHH') do |s, _data, _o|
47
46
  s.close
48
- assert_raises(EOFError) { s.puts(514) }
49
- assert_raises(EOFError) { s.puts(514) }
50
- assert_raises(EOFError) { s.recv }
51
- assert_raises(EOFError) { s.recv }
47
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.puts(514) }
48
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.puts(514) }
49
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.recv }
50
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.recv }
52
51
  assert_raises(ArgumentError) { s.close(:hh) }
53
52
  end
54
53
 
@@ -57,10 +56,10 @@ class SockTest < MiniTest::Test
57
56
  3.times { s.close(:recv) }
58
57
  3.times { s.close(:send) }
59
58
  3.times { s.close(:write) }
60
- assert_raises(EOFError) { s.puts(514) }
61
- assert_raises(EOFError) { s.puts(514) }
62
- assert_raises(EOFError) { s.recv }
63
- assert_raises(EOFError) { s.recv }
59
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.puts(514) }
60
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.puts(514) }
61
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.recv }
62
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.recv }
64
63
  3.times { s.close }
65
64
  assert_raises(ArgumentError) { s.close(:shik) }
66
65
  end