pwntools 0.1.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (168) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +96 -15
  3. data/Rakefile +8 -2
  4. data/lib/pwn.rb +10 -7
  5. data/lib/pwnlib/abi.rb +61 -0
  6. data/lib/pwnlib/asm.rb +357 -0
  7. data/lib/pwnlib/constants/constant.rb +19 -3
  8. data/lib/pwnlib/constants/constants.rb +46 -20
  9. data/lib/pwnlib/constants/linux/amd64.rb +32 -1
  10. data/lib/pwnlib/constants/linux/i386.rb +2 -0
  11. data/lib/pwnlib/context.rb +128 -27
  12. data/lib/pwnlib/dynelf.rb +122 -54
  13. data/lib/pwnlib/elf/elf.rb +340 -0
  14. data/lib/pwnlib/errors.rb +31 -0
  15. data/lib/pwnlib/ext/array.rb +2 -1
  16. data/lib/pwnlib/ext/helper.rb +6 -5
  17. data/lib/pwnlib/ext/integer.rb +2 -1
  18. data/lib/pwnlib/ext/string.rb +3 -2
  19. data/lib/pwnlib/logger.rb +245 -0
  20. data/lib/pwnlib/memleak.rb +59 -29
  21. data/lib/pwnlib/pwn.rb +27 -9
  22. data/lib/pwnlib/reg_sort.rb +109 -110
  23. data/lib/pwnlib/runner.rb +53 -0
  24. data/lib/pwnlib/shellcraft/generators/amd64/common/common.rb +16 -0
  25. data/lib/pwnlib/shellcraft/generators/amd64/common/infloop.rb +24 -0
  26. data/lib/pwnlib/shellcraft/generators/amd64/common/memcpy.rb +35 -0
  27. data/lib/pwnlib/shellcraft/generators/amd64/common/mov.rb +131 -0
  28. data/lib/pwnlib/shellcraft/generators/amd64/common/nop.rb +18 -0
  29. data/lib/pwnlib/shellcraft/generators/amd64/common/popad.rb +28 -0
  30. data/lib/pwnlib/shellcraft/generators/amd64/common/pushstr.rb +66 -0
  31. data/lib/pwnlib/shellcraft/generators/amd64/common/pushstr_array.rb +24 -0
  32. data/lib/pwnlib/shellcraft/generators/amd64/common/ret.rb +33 -0
  33. data/lib/pwnlib/shellcraft/generators/amd64/common/setregs.rb +24 -0
  34. data/lib/pwnlib/shellcraft/generators/amd64/linux/cat.rb +24 -0
  35. data/lib/pwnlib/shellcraft/generators/amd64/linux/execve.rb +24 -0
  36. data/lib/pwnlib/shellcraft/generators/amd64/linux/exit.rb +24 -0
  37. data/lib/pwnlib/shellcraft/generators/amd64/linux/linux.rb +16 -0
  38. data/lib/pwnlib/shellcraft/generators/amd64/linux/ls.rb +24 -0
  39. data/lib/pwnlib/shellcraft/generators/amd64/linux/open.rb +24 -0
  40. data/lib/pwnlib/shellcraft/generators/amd64/linux/sh.rb +24 -0
  41. data/lib/pwnlib/shellcraft/generators/amd64/linux/sleep.rb +24 -0
  42. data/lib/pwnlib/shellcraft/generators/amd64/linux/syscall.rb +24 -0
  43. data/lib/pwnlib/shellcraft/generators/helper.rb +115 -0
  44. data/lib/pwnlib/shellcraft/generators/i386/common/common.rb +16 -0
  45. data/lib/pwnlib/shellcraft/generators/i386/common/infloop.rb +24 -0
  46. data/lib/pwnlib/shellcraft/generators/i386/common/memcpy.rb +34 -0
  47. data/lib/pwnlib/shellcraft/generators/i386/common/mov.rb +93 -0
  48. data/lib/pwnlib/shellcraft/generators/i386/common/nop.rb +18 -0
  49. data/lib/pwnlib/shellcraft/generators/i386/common/pushstr.rb +41 -0
  50. data/lib/pwnlib/shellcraft/generators/i386/common/pushstr_array.rb +24 -0
  51. data/lib/pwnlib/shellcraft/generators/i386/common/setregs.rb +24 -0
  52. data/lib/pwnlib/shellcraft/generators/i386/linux/cat.rb +24 -0
  53. data/lib/pwnlib/shellcraft/generators/i386/linux/execve.rb +24 -0
  54. data/lib/pwnlib/shellcraft/generators/i386/linux/exit.rb +24 -0
  55. data/lib/pwnlib/shellcraft/generators/i386/linux/linux.rb +16 -0
  56. data/lib/pwnlib/shellcraft/generators/i386/linux/ls.rb +24 -0
  57. data/lib/pwnlib/shellcraft/generators/i386/linux/open.rb +24 -0
  58. data/lib/pwnlib/shellcraft/generators/i386/linux/sh.rb +24 -0
  59. data/lib/pwnlib/shellcraft/generators/i386/linux/sleep.rb +24 -0
  60. data/lib/pwnlib/shellcraft/generators/i386/linux/syscall.rb +24 -0
  61. data/lib/pwnlib/shellcraft/generators/x86/common/common.rb +29 -0
  62. data/lib/pwnlib/shellcraft/generators/x86/common/infloop.rb +24 -0
  63. data/lib/pwnlib/shellcraft/generators/x86/common/memcpy.rb +17 -0
  64. data/lib/pwnlib/shellcraft/generators/x86/common/mov.rb +17 -0
  65. data/lib/pwnlib/shellcraft/generators/x86/common/pushstr.rb +17 -0
  66. data/lib/pwnlib/shellcraft/generators/x86/common/pushstr_array.rb +86 -0
  67. data/lib/pwnlib/shellcraft/generators/x86/common/setregs.rb +84 -0
  68. data/lib/pwnlib/shellcraft/generators/x86/linux/cat.rb +54 -0
  69. data/lib/pwnlib/shellcraft/generators/x86/linux/execve.rb +72 -0
  70. data/lib/pwnlib/shellcraft/generators/x86/linux/exit.rb +34 -0
  71. data/lib/pwnlib/shellcraft/generators/x86/linux/linux.rb +16 -0
  72. data/lib/pwnlib/shellcraft/generators/x86/linux/ls.rb +67 -0
  73. data/lib/pwnlib/shellcraft/generators/x86/linux/open.rb +47 -0
  74. data/lib/pwnlib/shellcraft/generators/x86/linux/sh.rb +53 -0
  75. data/lib/pwnlib/shellcraft/generators/x86/linux/sleep.rb +52 -0
  76. data/lib/pwnlib/shellcraft/generators/x86/linux/syscall.rb +52 -0
  77. data/lib/pwnlib/shellcraft/registers.rb +148 -0
  78. data/lib/pwnlib/shellcraft/shellcraft.rb +73 -0
  79. data/lib/pwnlib/timer.rb +67 -0
  80. data/lib/pwnlib/tubes/buffer.rb +99 -0
  81. data/lib/pwnlib/tubes/process.rb +155 -0
  82. data/lib/pwnlib/tubes/serialtube.rb +114 -0
  83. data/lib/pwnlib/tubes/sock.rb +101 -0
  84. data/lib/pwnlib/tubes/tube.rb +442 -0
  85. data/lib/pwnlib/ui.rb +21 -0
  86. data/lib/pwnlib/util/cyclic.rb +97 -94
  87. data/lib/pwnlib/util/fiddling.rb +288 -220
  88. data/lib/pwnlib/util/getdents.rb +85 -0
  89. data/lib/pwnlib/util/hexdump.rb +116 -112
  90. data/lib/pwnlib/util/lists.rb +58 -0
  91. data/lib/pwnlib/util/packing.rb +223 -228
  92. data/lib/pwnlib/util/ruby.rb +19 -0
  93. data/lib/pwnlib/version.rb +3 -1
  94. data/test/abi_test.rb +22 -0
  95. data/test/asm_test.rb +177 -0
  96. data/test/constants/constant_test.rb +2 -0
  97. data/test/constants/constants_test.rb +5 -2
  98. data/test/context_test.rb +14 -3
  99. data/test/data/assembly/aarch64.s +19 -0
  100. data/test/data/assembly/amd64.s +21 -0
  101. data/test/data/assembly/arm.s +9 -0
  102. data/test/data/assembly/i386.s +21 -0
  103. data/test/data/assembly/mips.s +16 -0
  104. data/test/data/assembly/mips64.s +6 -0
  105. data/test/data/assembly/powerpc.s +18 -0
  106. data/test/data/assembly/powerpc64.s +36 -0
  107. data/test/data/assembly/sparc.s +33 -0
  108. data/test/data/assembly/sparc64.s +5 -0
  109. data/test/data/assembly/thumb.s +37 -0
  110. data/test/data/echo.rb +16 -0
  111. data/test/data/elfs/Makefile +24 -0
  112. data/test/data/elfs/amd64.frelro.elf +0 -0
  113. data/test/data/elfs/amd64.frelro.pie.elf +0 -0
  114. data/test/data/elfs/amd64.nrelro.elf +0 -0
  115. data/test/data/elfs/amd64.prelro.elf +0 -0
  116. data/test/data/elfs/amd64.static.elf +0 -0
  117. data/test/data/elfs/i386.frelro.pie.elf +0 -0
  118. data/test/data/elfs/i386.prelro.elf +0 -0
  119. data/test/data/elfs/source.cpp +19 -0
  120. data/test/data/flag +1 -0
  121. data/test/data/lib32/ld.so.2 +0 -0
  122. data/test/data/lib32/libc.so.6 +0 -0
  123. data/test/data/lib64/ld.so.2 +0 -0
  124. data/test/data/lib64/libc.so.6 +0 -0
  125. data/test/dynelf_test.rb +62 -25
  126. data/test/elf/elf_test.rb +147 -0
  127. data/test/ext_test.rb +4 -2
  128. data/test/files/use_pwn.rb +3 -6
  129. data/test/files/use_pwnlib.rb +2 -1
  130. data/test/full_file_test.rb +6 -0
  131. data/test/logger_test.rb +120 -0
  132. data/test/memleak_test.rb +5 -33
  133. data/test/reg_sort_test.rb +4 -1
  134. data/test/runner_test.rb +32 -0
  135. data/test/shellcraft/infloop_test.rb +27 -0
  136. data/test/shellcraft/linux/cat_test.rb +87 -0
  137. data/test/shellcraft/linux/ls_test.rb +109 -0
  138. data/test/shellcraft/linux/sh_test.rb +120 -0
  139. data/test/shellcraft/linux/sleep_test.rb +68 -0
  140. data/test/shellcraft/linux/syscalls/execve_test.rb +137 -0
  141. data/test/shellcraft/linux/syscalls/exit_test.rb +57 -0
  142. data/test/shellcraft/linux/syscalls/open_test.rb +87 -0
  143. data/test/shellcraft/linux/syscalls/syscall_test.rb +84 -0
  144. data/test/shellcraft/memcpy_test.rb +50 -0
  145. data/test/shellcraft/mov_test.rb +99 -0
  146. data/test/shellcraft/nop_test.rb +27 -0
  147. data/test/shellcraft/popad_test.rb +30 -0
  148. data/test/shellcraft/pushstr_array_test.rb +92 -0
  149. data/test/shellcraft/pushstr_test.rb +109 -0
  150. data/test/shellcraft/registers_test.rb +33 -0
  151. data/test/shellcraft/ret_test.rb +31 -0
  152. data/test/shellcraft/setregs_test.rb +63 -0
  153. data/test/shellcraft/shellcraft_test.rb +30 -0
  154. data/test/test_helper.rb +61 -2
  155. data/test/timer_test.rb +42 -0
  156. data/test/tubes/buffer_test.rb +46 -0
  157. data/test/tubes/process_test.rb +105 -0
  158. data/test/tubes/serialtube_test.rb +162 -0
  159. data/test/tubes/sock_test.rb +68 -0
  160. data/test/tubes/tube_test.rb +320 -0
  161. data/test/ui_test.rb +18 -0
  162. data/test/util/cyclic_test.rb +3 -1
  163. data/test/util/fiddling_test.rb +12 -3
  164. data/test/util/getdents_test.rb +33 -0
  165. data/test/util/hexdump_test.rb +9 -10
  166. data/test/util/lists_test.rb +22 -0
  167. data/test/util/packing_test.rb +5 -3
  168. metadata +357 -37
@@ -0,0 +1,68 @@
1
+ # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
3
+
4
+ require 'open3'
5
+
6
+ require 'test_helper'
7
+
8
+ require 'pwnlib/tubes/sock'
9
+
10
+ class SockTest < MiniTest::Test
11
+ include ::Pwnlib::Tubes
12
+ ECHO_FILE = File.expand_path('../data/echo.rb', __dir__)
13
+
14
+ def popen_echo(data)
15
+ Open3.popen2("ruby #{ECHO_FILE}") do |_i, o, _t|
16
+ port = o.gets.split.last.to_i
17
+ s = Sock.new('127.0.0.1', port)
18
+ yield s, data, o
19
+ end
20
+ end
21
+
22
+ def test_sock
23
+ popen_echo('DARKHH') do |s, data, _o|
24
+ s.sock.puts(data)
25
+ rs, = IO.select([s.sock])
26
+ refute_nil(rs)
27
+ assert_equal(data, s.sock.readpartial(data.size))
28
+ end
29
+ end
30
+
31
+ def test_eof
32
+ popen_echo('DARKHH') do |s, data, o|
33
+ s.puts(data)
34
+ assert_equal("#{data}\n", s.gets)
35
+ o.gets
36
+ s.puts(514)
37
+ sleep(0.1) # Wait for connection reset
38
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.puts(514) }
39
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.puts(514) }
40
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.recv }
41
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.recv }
42
+ end
43
+ end
44
+
45
+ def test_close
46
+ popen_echo('DARKHH') do |s, _data, _o|
47
+ s.close
48
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.puts(514) }
49
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.puts(514) }
50
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.recv }
51
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.recv }
52
+ assert_raises(ArgumentError) { s.close(:hh) }
53
+ end
54
+
55
+ popen_echo('DARKHH') do |s, _data, _o|
56
+ 3.times { s.close(:read) }
57
+ 3.times { s.close(:recv) }
58
+ 3.times { s.close(:send) }
59
+ 3.times { s.close(:write) }
60
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.puts(514) }
61
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.puts(514) }
62
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.recv }
63
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { s.recv }
64
+ 3.times { s.close }
65
+ assert_raises(ArgumentError) { s.close(:shik) }
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,320 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ # This test use UTF-8 encoding for strings since the output for hexdump contains lots of UTF-8 characters.
5
+
6
+ require 'test_helper'
7
+
8
+ require 'pwnlib/context'
9
+ require 'pwnlib/logger'
10
+ require 'pwnlib/tubes/tube'
11
+
12
+ class TubeTest < MiniTest::Test
13
+ include ::Pwnlib::Context
14
+ include ::Pwnlib::Tubes
15
+
16
+ def setup
17
+ @old_log = ::Pwnlib::Logger.log.dup
18
+ @log = ::Pwnlib::Logger::LoggerType.new
19
+
20
+ class << @log
21
+ def clear
22
+ @logdev = StringIO.new
23
+ end
24
+
25
+ def string
26
+ @logdev.string
27
+ end
28
+ end
29
+
30
+ ::Pwnlib::Logger.instance_variable_set(:@log, @log)
31
+ end
32
+
33
+ def hello_tube
34
+ t = Tube.new
35
+
36
+ class << t
37
+ def buf
38
+ @buf ||= +''
39
+ end
40
+
41
+ private
42
+
43
+ def recv_raw(_n)
44
+ 'Hello, world'
45
+ end
46
+
47
+ def timeout_raw=(timeout)
48
+ @timeout = timeout == :forever ? nil : timeout
49
+ end
50
+
51
+ def send_raw(data)
52
+ buf << data
53
+ end
54
+ end
55
+
56
+ t
57
+ end
58
+
59
+ def basic_tube
60
+ t = Tube.new
61
+
62
+ class << t
63
+ def recv_raw(_n)
64
+ raise ::Pwnlib::Errors::EndOfTubeError if io.eof?
65
+
66
+ io.read
67
+ end
68
+
69
+ def send_raw(data)
70
+ io.write(data)
71
+ end
72
+
73
+ def timeout_raw=(timeout)
74
+ @timeout = timeout == :forever ? nil : timeout
75
+ end
76
+
77
+ def io
78
+ @io ||= Tempfile.new('pwntools_ruby_test')
79
+ end
80
+
81
+ def io_out
82
+ io
83
+ end
84
+ end
85
+
86
+ t
87
+ end
88
+
89
+ def test_not_implement
90
+ t = Tube.new
91
+ # io_out
92
+ assert_raises(NotImplementedError) { context.local(log_level: :fatal) { t.interact } }
93
+ # send_raw
94
+ assert_raises(NotImplementedError) { t.puts }
95
+ # timeout_raw=
96
+ assert_raises(NotImplementedError) { t.recv(timeout: 1) }
97
+ class << t
98
+ def timeout_raw=(_) end
99
+ end
100
+ # recv_raw
101
+ assert_raises(NotImplementedError) { t.gets }
102
+ end
103
+
104
+ def test_recv
105
+ t = hello_tube
106
+ assert_equal('Hello, world', t.recv)
107
+ assert_equal('Hello, world', t.recv)
108
+ t.unrecv('Woohoo')
109
+ assert_equal('Woohoo', t.recv)
110
+ assert_equal('Hello, world', t.recv)
111
+ assert_equal('H', t.recvn(1))
112
+ assert_equal('ello, w', t.recvn(7))
113
+ assert_equal('orldH', t.recvn(5))
114
+ assert_equal('ello, world', t.recv)
115
+
116
+ context.local(log_level: 'debug') do
117
+ @log.clear
118
+ t = hello_tube
119
+ assert_equal('Hello, world', t.recv)
120
+ assert_equal(<<-'EOS', @log.string.encode('UTF-8'))
121
+ [DEBUG] Received 0xc bytes:
122
+ 00000000 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 │Hell│o, w│orld│
123
+ 0000000c
124
+ EOS
125
+ end
126
+ end
127
+
128
+ def test_recvuntil
129
+ t = hello_tube
130
+ assert_equal('Hello, ', t.recvuntil(' '))
131
+ assert_equal('worldHello, ', t.recvuntil(' '))
132
+ t.unrecv('Hello, world!')
133
+ assert_equal('Hello,', t.recvuntil(' wor', drop: true))
134
+
135
+ # test timeout
136
+ assert_raises(::Pwnlib::Errors::TimeoutError) { t.recvuntil('DARKHH', drop: true, timeout: 0.1) }
137
+
138
+ t = basic_tube
139
+ t.unrecv('meow')
140
+ # test EOF
141
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { t.recvuntil('DARKHH') }
142
+ assert_equal('meow', t.recv)
143
+ end
144
+
145
+ def test_recvline
146
+ t = Tube.new
147
+ t.unrecv("Foo\nBar\r\nBaz\n")
148
+ assert_equal("Foo\n", t.recvline)
149
+ assert_equal("Bar\r\n", t.recvline)
150
+ assert_equal('Baz', t.recvline(drop: true))
151
+ context.local(newline: "\r\n") do
152
+ t = Tube.new
153
+ t.unrecv("Foo\nBar\r\nBaz\n")
154
+ assert_equal("Foo\nBar", t.recvline(drop: true))
155
+ end
156
+
157
+ t = basic_tube
158
+ t.unrecv('Hello, world')
159
+ # test EOF
160
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { assert_equal('', t.recvline) }
161
+ assert_equal('Hello, world', t.recv)
162
+ end
163
+
164
+ def test_gets
165
+ t = Tube.new
166
+ t.unrecv("Foo\nBar\r\nBaz\n")
167
+ assert_equal("Foo\n", t.gets)
168
+ assert_equal("Bar\r\n", t.gets)
169
+ assert_equal('Baz', t.gets(drop: true))
170
+
171
+ t = hello_tube
172
+ assert_equal('Hello,', t.gets(','))
173
+ assert_equal(' world', t.gets('H', drop: true))
174
+ assert_equal('ello', t.gets(4))
175
+ assert_raises(ArgumentError) { t.gets(t) }
176
+ end
177
+
178
+ def test_recvpred
179
+ t = hello_tube
180
+ r = /H.*w/
181
+ 10.times { assert_match(r, t.recvpred { |data| data =~ r }) }
182
+ r = /H.*W/
183
+
184
+ # test timeout
185
+ assert_raises(::Pwnlib::Errors::TimeoutError) { t.recvpred(timeout: 0.01) { |data| data =~ r } }
186
+ t = basic_tube
187
+ t.unrecv('darkhh')
188
+ # test EOF
189
+ assert_raises(::Pwnlib::Errors::EndOfTubeError) { t.recvpred { |data| data =~ r } }
190
+ end
191
+
192
+ def test_recvregex
193
+ t = hello_tube
194
+ r = /[aeiou]/
195
+ 5.times { assert_match(r, t.recvregex(r)) }
196
+ r = /[wl][aeiou]/
197
+ 5.times { assert_match(r, t.recvregex(r)) }
198
+ end
199
+
200
+ def test_recvall
201
+ t = basic_tube
202
+ t.unrecv('meow')
203
+ assert_equal('meow', t.recvall)
204
+ assert_equal('', t.recvall)
205
+ end
206
+
207
+ def test_send
208
+ t = hello_tube
209
+ assert_equal(6, t.write('DARKHH'))
210
+ assert_equal('DARKHH', t.buf)
211
+ assert_equal(3, t.write(' QQ'))
212
+ assert_equal('DARKHH QQ', t.buf)
213
+ assert_equal(3, t.write(333))
214
+ assert_equal('DARKHH QQ333', t.buf)
215
+
216
+ context.local(log_level: 'debug') do
217
+ @log.clear
218
+ data = (0..40).map(&:chr).join
219
+ t = hello_tube
220
+ t.write(data)
221
+ assert_equal(data, t.buf)
222
+ assert_equal(<<-'EOS', @log.string.encode('UTF-8'))
223
+ [DEBUG] Sent 0x29 bytes:
224
+ 00000000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f │····│····│····│····│
225
+ 00000010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f │····│····│····│····│
226
+ 00000020 20 21 22 23 24 25 26 27 28 │ !"#│$%&'│(│
227
+ 00000029
228
+ EOS
229
+
230
+ @log.clear
231
+ t.puts('meow')
232
+ assert_equal(<<-'EOS', @log.string.encode('UTF-8'))
233
+ [DEBUG] Sent 0x5 bytes:
234
+ 00000000 6d 65 6f 77 0a │meow│·│
235
+ 00000005
236
+ EOS
237
+ end
238
+ end
239
+
240
+ def test_sendline
241
+ t = hello_tube
242
+ t.write('DARKHH')
243
+ assert_equal('DARKHH', t.buf)
244
+ assert_equal(4, t.sendline(' QQ'))
245
+ assert_equal("DARKHH QQ\n", t.buf)
246
+ assert_equal(1, t.sendline(''))
247
+ assert_equal("DARKHH QQ\n\n", t.buf)
248
+ end
249
+
250
+ def test_puts
251
+ t = hello_tube
252
+ assert_equal(1, t.puts)
253
+ assert_equal("\n", t.buf)
254
+ assert_equal(17, t.puts("darkhh i4 so sad\n"))
255
+ assert_equal("\ndarkhh i4 so sad\n", t.buf)
256
+
257
+ t = hello_tube
258
+ assert_equal(14, t.puts('shik', 'hao', '', 123))
259
+ assert_equal("shik\nhao\n\n123\n", t.buf)
260
+
261
+ t = hello_tube
262
+ assert_equal(15, t.puts(['shik', '', "\n", 'hao', 123]))
263
+ assert_equal("shik\n\n\nhao\n123\n", t.buf)
264
+ assert_equal(0, t.puts([]))
265
+ assert_equal("shik\n\n\nhao\n123\n", t.buf)
266
+
267
+ t = hello_tube
268
+ assert_equal(20, t.puts(["darkhh\n\n", 'wei shi', 360]))
269
+ assert_equal("darkhh\n\nwei shi\n360\n", t.buf)
270
+
271
+ context.local(newline: '!!!') do
272
+ t = hello_tube
273
+ assert_equal(5, t.puts('hi'))
274
+ assert_equal('hi!!!', t.buf)
275
+ end
276
+ end
277
+
278
+ FLAG_FILE = File.expand_path('../data/flag', __dir__)
279
+ def test_interact_send
280
+ save_stdin = $stdin.dup
281
+ $stdin = File.new(FLAG_FILE, File::RDONLY)
282
+ @log.clear
283
+ begin
284
+ t = basic_tube
285
+ t.interact
286
+ rescue ::Pwnlib::Errors::EndOfTubeError
287
+ t.io.rewind
288
+ assert_equal(IO.binread(FLAG_FILE), t.io.read)
289
+ end
290
+ assert_equal("[INFO] Switching to interactive mode\n[INFO] Got EOF in interactive mode\n", @log.string)
291
+ $stdin.close
292
+ t.io.close
293
+ $stdin = save_stdin
294
+ end
295
+
296
+ def test_interact_recv
297
+ save_stdin = $stdin.dup
298
+ save_stdout = $stdout.dup
299
+ $stdin = UDPSocket.new
300
+ $stdout = Tempfile.new('pwntools_ruby_test')
301
+ @log.clear
302
+ begin
303
+ t = basic_tube
304
+ t.instance_variable_set(:@io, File.new(FLAG_FILE, File::RDONLY))
305
+ t.interact
306
+ rescue ::Pwnlib::Errors::EndOfTubeError
307
+ $stdout.rewind
308
+ assert_equal(IO.binread(FLAG_FILE), $stdout.read)
309
+ end
310
+ assert_equal("[INFO] Switching to interactive mode\n[INFO] Got EOF in interactive mode\n", @log.string)
311
+ $stdout.close
312
+ t.io.close
313
+ $stdin = save_stdin
314
+ $stdout = save_stdout
315
+ end
316
+
317
+ def teardown
318
+ ::Pwnlib::Logger.instance_variable_set(:@log, @old_log)
319
+ end
320
+ end
data/test/ui_test.rb ADDED
@@ -0,0 +1,18 @@
1
+ # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
3
+
4
+ require 'stringio'
5
+
6
+ require 'test_helper'
7
+
8
+ require 'pwnlib/ui'
9
+
10
+ class UITest < MiniTest::Test
11
+ def test_pause
12
+ hook_stdin(StringIO.new("\n")) do
13
+ assert_output(<<-EOS) { log_stdout { ::Pwnlib::UI.pause } }
14
+ [INFO] Paused (press enter to continue)
15
+ EOS
16
+ end
17
+ end
18
+ end
@@ -1,10 +1,12 @@
1
1
  # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'test_helper'
5
+
4
6
  require 'pwnlib/util/cyclic'
5
7
 
6
8
  class CyclicTest < MiniTest::Test
7
- include ::Pwnlib::Util::Cyclic::ClassMethods
9
+ include ::Pwnlib::Util::Cyclic
8
10
 
9
11
  def test_cyclic
10
12
  assert_equal('AAABAACABBABCACBACCBBBCBCCC', cyclic(alphabet: 'ABC', n: 3))
@@ -1,10 +1,12 @@
1
1
  # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'test_helper'
5
+
4
6
  require 'pwnlib/util/fiddling'
5
7
 
6
8
  class FiddlingTest < MiniTest::Test
7
- include ::Pwnlib::Util::Fiddling::ClassMethods
9
+ include ::Pwnlib::Util::Fiddling
8
10
 
9
11
  def test_enhex
10
12
  assert_equal('4141313233', enhex('AA123'))
@@ -38,11 +40,11 @@ class FiddlingTest < MiniTest::Test
38
40
  assert_equal('test A', urldecode('te%73t%20%41'))
39
41
  assert_equal("\x00\xff\x01\xfe", urldecode('%00%ff%01%fe'))
40
42
 
41
- assert_equal('%qq', urldecode('%qq', true))
43
+ assert_equal('%qq', urldecode('%qq', ignore_invalid: true))
42
44
  err = assert_raises(ArgumentError) { urldecode('%qq') }
43
45
  assert_match(/Invalid input to urldecode/, err.message)
44
46
 
45
- assert_equal('%%1z2%orz%%%%%#$!#)@%', urldecode('%%1z2%orz%%%%%#$!#)@%', true))
47
+ assert_equal('%%1z2%orz%%%%%#$!#)@%', urldecode('%%1z2%orz%%%%%#$!#)@%', ignore_invalid: true))
46
48
  err = assert_raises(ArgumentError) { urldecode('%ff%') }
47
49
  assert_match(/Invalid input to urldecode/, err.message)
48
50
  end
@@ -103,4 +105,11 @@ class FiddlingTest < MiniTest::Test
103
105
  assert_equal('test', b64d('dGVzdA=='))
104
106
  assert_equal("\xb2\x18\xa4" * 100, b64d('shik' * 100))
105
107
  end
108
+
109
+ def test_xor
110
+ assert_equal('happy', xor("\xE8\xE1\xF0\xF0\xF9", "\x80"))
111
+ assert_equal('happy', xor("\x80", "\xE8\xE1\xF0\xF0\xF9"))
112
+ assert_equal("\x04\x04\x04\x02\v\r\x11\x10\x11", xor('plaintext', 'thekey'))
113
+ assert_equal('2172172172', xor('217', "\x00" * 10))
114
+ end
106
115
  end