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/tubes/sock.rb
CHANGED
@@ -2,30 +2,30 @@
|
|
2
2
|
|
3
3
|
require 'socket'
|
4
4
|
|
5
|
+
require 'pwnlib/errors'
|
5
6
|
require 'pwnlib/tubes/tube'
|
6
7
|
|
7
8
|
module Pwnlib
|
8
9
|
module Tubes
|
9
10
|
# Socket!
|
10
11
|
class Sock < Tube
|
12
|
+
attr_reader :sock # @return [TCPSocket] The socket object.
|
13
|
+
|
11
14
|
# Instantiate a {Pwnlib::Tubes::Sock} object.
|
12
15
|
#
|
13
16
|
# @param [String] host
|
14
17
|
# The host to connect.
|
15
18
|
# @param [Integer] port
|
16
19
|
# The port to connect.
|
17
|
-
|
18
|
-
|
20
|
+
# @param [Float?] timeout
|
21
|
+
# See {Pwnlib::Tubes::Tube#initialize}.
|
22
|
+
def initialize(host, port, timeout: nil)
|
23
|
+
super(timeout: timeout)
|
19
24
|
@sock = TCPSocket.new(host, port)
|
20
25
|
@sock.binmode
|
21
26
|
@timeout = nil
|
22
|
-
@closed = {
|
23
|
-
end
|
24
|
-
|
25
|
-
def io
|
26
|
-
@sock
|
27
|
+
@closed = { read: false, write: false }
|
27
28
|
end
|
28
|
-
alias sock io
|
29
29
|
|
30
30
|
# Close the TCPSocket if no arguments passed.
|
31
31
|
# Or close the direction in +sock+.
|
@@ -35,59 +35,58 @@ module Pwnlib
|
|
35
35
|
# * Disallow further read in +sock+ if +:recv+ or +:read+ passed.
|
36
36
|
# * Disallow further write in +sock+ if +:send+ or +:write+ passed.
|
37
37
|
#
|
38
|
+
# @return [void]
|
39
|
+
#
|
38
40
|
# @diff In pwntools-python, method +shutdown(direction)+ is for closing socket one side,
|
39
41
|
# +close()+ is for closing both side. We merge these two methods into one here.
|
40
42
|
def close(direction = :both)
|
41
|
-
|
42
|
-
when :both
|
43
|
+
if direction == :both
|
43
44
|
return if @sock.closed?
|
44
|
-
@closed[:
|
45
|
+
@closed[:read] = @closed[:write] = true
|
45
46
|
@sock.close
|
46
|
-
when :recv, :read
|
47
|
-
shutdown(:recv)
|
48
|
-
when :send, :write
|
49
|
-
shutdown(:send)
|
50
47
|
else
|
51
|
-
|
48
|
+
shutdown(*normalize_direction(direction))
|
52
49
|
end
|
53
50
|
end
|
54
51
|
|
55
52
|
private
|
56
53
|
|
54
|
+
alias io_out sock
|
55
|
+
|
57
56
|
def shutdown(direction)
|
58
57
|
return if @closed[direction]
|
59
58
|
@closed[direction] = true
|
60
59
|
|
61
|
-
if direction.equal?(:
|
60
|
+
if direction.equal?(:read)
|
62
61
|
@sock.close_read
|
63
|
-
elsif direction.equal?(:
|
62
|
+
elsif direction.equal?(:write)
|
64
63
|
@sock.close_write
|
65
64
|
end
|
66
65
|
end
|
67
66
|
|
68
67
|
def timeout_raw=(timeout)
|
69
|
-
@timeout = timeout
|
68
|
+
@timeout = timeout
|
70
69
|
end
|
71
70
|
|
72
71
|
def send_raw(data)
|
73
|
-
raise
|
72
|
+
raise ::Pwnlib::Errors::EndOfTubeError if @closed[:write]
|
74
73
|
begin
|
75
74
|
@sock.write(data)
|
76
75
|
rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ECONNREFUSED
|
77
|
-
shutdown(:
|
78
|
-
raise
|
76
|
+
shutdown(:write)
|
77
|
+
raise ::Pwnlib::Errors::EndOfTubeError
|
79
78
|
end
|
80
79
|
end
|
81
80
|
|
82
81
|
def recv_raw(size)
|
83
|
-
raise
|
82
|
+
raise ::Pwnlib::Errors::EndOfTubeError if @closed[:read]
|
84
83
|
begin
|
85
84
|
rs, = IO.select([@sock], [], [], @timeout)
|
86
85
|
return if rs.nil?
|
87
86
|
return @sock.readpartial(size)
|
88
87
|
rescue Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ECONNABORTED, EOFError
|
89
|
-
shutdown(:
|
90
|
-
raise
|
88
|
+
shutdown(:read)
|
89
|
+
raise ::Pwnlib::Errors::EndOfTubeError
|
91
90
|
end
|
92
91
|
end
|
93
92
|
end
|
data/lib/pwnlib/tubes/tube.rb
CHANGED
@@ -1,19 +1,39 @@
|
|
1
1
|
# encoding: ASCII-8BIT
|
2
2
|
|
3
3
|
require 'pwnlib/context'
|
4
|
+
require 'pwnlib/errors'
|
4
5
|
require 'pwnlib/logger'
|
5
6
|
require 'pwnlib/timer'
|
6
7
|
require 'pwnlib/tubes/buffer'
|
7
8
|
require 'pwnlib/util/hexdump'
|
8
9
|
|
9
10
|
module Pwnlib
|
11
|
+
# Module that contains all kinds of tubes.
|
10
12
|
module Tubes
|
11
|
-
#
|
13
|
+
# @!macro [new] drop_definition
|
14
|
+
# @param [Boolean] drop
|
15
|
+
# Whether drop the ending.
|
16
|
+
#
|
12
17
|
# @!macro [new] timeout_definition
|
13
18
|
# @param [Float] timeout
|
14
19
|
# Any positive floating number, indicates timeout in seconds.
|
15
20
|
# Using +context.timeout+ if +timeout+ equals to +nil+.
|
21
|
+
#
|
22
|
+
# @!macro [new] send_return_definition
|
23
|
+
# @return [Integer]
|
24
|
+
# Returns the number of bytes had been sent.
|
25
|
+
#
|
26
|
+
# @!macro [new] raise_eof
|
27
|
+
# @raise [Pwnlib::Errors::EndOfTubeError]
|
28
|
+
# If the request is not satisfied when all data is received.
|
29
|
+
#
|
30
|
+
# @!macro [new] raise_timeout
|
31
|
+
# @raise [Pwnlib::Errors::TimeoutError]
|
32
|
+
# If the request is not satisfied when timeout exceeded.
|
33
|
+
|
34
|
+
# Things common to all tubes (sockets, tty, ...)
|
16
35
|
class Tube
|
36
|
+
# Receive 4096 bytes each time.
|
17
37
|
BUFSIZE = 4096
|
18
38
|
|
19
39
|
# Instantiate a {Pwnlib::Tubes::Tube} object.
|
@@ -34,6 +54,9 @@ module Pwnlib
|
|
34
54
|
# @return [String]
|
35
55
|
# A string contains bytes received from the tube, or +''+ if a timeout occurred while
|
36
56
|
# waiting.
|
57
|
+
#
|
58
|
+
# @!macro raise_eof
|
59
|
+
# @!macro raise_timeout
|
37
60
|
def recv(num_bytes = nil, timeout: nil)
|
38
61
|
return '' if @buffer.empty? && !fillbuffer(timeout: timeout)
|
39
62
|
@buffer.get(num_bytes)
|
@@ -44,8 +67,12 @@ module Pwnlib
|
|
44
67
|
#
|
45
68
|
# @param [String] data
|
46
69
|
# A string to put back.
|
70
|
+
#
|
71
|
+
# @return [Integer]
|
72
|
+
# The length of the put back data.
|
47
73
|
def unrecv(data)
|
48
74
|
@buffer.unget(data)
|
75
|
+
data.size
|
49
76
|
end
|
50
77
|
|
51
78
|
# Receives one byte at a time from the tube, until the predicate evaluates to +true+.
|
@@ -67,6 +94,9 @@ module Pwnlib
|
|
67
94
|
#
|
68
95
|
# @raise [ArgumentError]
|
69
96
|
# If the block is not given.
|
97
|
+
#
|
98
|
+
# @!macro raise_eof
|
99
|
+
# @!macro raise_timeout
|
70
100
|
def recvpred(timeout: nil)
|
71
101
|
raise ArgumentError, 'Need a block for recvpred' unless block_given?
|
72
102
|
@timer.countdown(timeout) do
|
@@ -75,12 +105,7 @@ module Pwnlib
|
|
75
105
|
until yield(data)
|
76
106
|
return '' unless @timer.active?
|
77
107
|
|
78
|
-
|
79
|
-
# TODO(Darkpi): Some form of binary search to speed up?
|
80
|
-
c = recv(1)
|
81
|
-
rescue
|
82
|
-
return ''
|
83
|
-
end
|
108
|
+
c = recv(1)
|
84
109
|
|
85
110
|
return '' if c.empty?
|
86
111
|
data << c
|
@@ -103,25 +128,31 @@ module Pwnlib
|
|
103
128
|
# @return [String]
|
104
129
|
# A string contains bytes received from the tube, or +''+ if a timeout occurred while
|
105
130
|
# waiting.
|
131
|
+
#
|
132
|
+
# @!macro raise_eof
|
133
|
+
# @!macro raise_timeout
|
106
134
|
def recvn(num_bytes, timeout: nil)
|
107
135
|
@timer.countdown(timeout) do
|
108
136
|
fillbuffer while @timer.active? && @buffer.size < num_bytes
|
109
137
|
@buffer.size >= num_bytes ? @buffer.get(num_bytes) : ''
|
110
138
|
end
|
111
139
|
end
|
140
|
+
alias readn recvn
|
112
141
|
|
113
|
-
#
|
142
|
+
# Receives data until one of +delims+ is encountered. If the request is not satisfied before
|
114
143
|
# +timeout+ seconds pass, all data is buffered and an empty string is returned.
|
115
144
|
#
|
116
145
|
# @param [Array<String>] delims
|
117
146
|
# String of delimiters characters, or list of delimiter strings.
|
118
|
-
#
|
119
|
-
# Whether drop the ending.
|
147
|
+
# @!macro drop_definition
|
120
148
|
# @!macro timeout_definition
|
121
149
|
#
|
122
150
|
# @return [String]
|
123
151
|
# A string contains bytes, which ends string in +delims+, received from the tube.
|
124
152
|
#
|
153
|
+
# @!macro raise_eof
|
154
|
+
# @!macro raise_timeout
|
155
|
+
#
|
125
156
|
# @diff We return the string that ends the earliest, rather then starts the earliest,
|
126
157
|
# since the latter can't be done greedly. Still, it would be bad to call this
|
127
158
|
# for case with ambiguity.
|
@@ -133,11 +164,7 @@ module Pwnlib
|
|
133
164
|
matching = ''
|
134
165
|
begin
|
135
166
|
while @timer.active?
|
136
|
-
|
137
|
-
s = recv(1)
|
138
|
-
rescue # TODO(Darkpi): QQ
|
139
|
-
return ''
|
140
|
-
end
|
167
|
+
s = recv(1)
|
141
168
|
|
142
169
|
return '' if s.empty?
|
143
170
|
matching << s
|
@@ -169,12 +196,11 @@ module Pwnlib
|
|
169
196
|
end
|
170
197
|
end
|
171
198
|
|
172
|
-
#
|
199
|
+
# Receives a single line from the tube.
|
173
200
|
# A "line" is any sequence of bytes terminated by the byte sequence set in +context.newline+,
|
174
|
-
# which defaults to +"
|
201
|
+
# which defaults to +"\\n"+.
|
175
202
|
#
|
176
|
-
#
|
177
|
-
# Whether drop the line ending.
|
203
|
+
# @!macro drop_definition
|
178
204
|
# @!macro timeout_definition
|
179
205
|
#
|
180
206
|
# @return [String]
|
@@ -183,7 +209,48 @@ module Pwnlib
|
|
183
209
|
def recvline(drop: false, timeout: nil)
|
184
210
|
recvuntil(context.newline, drop: drop, timeout: timeout)
|
185
211
|
end
|
186
|
-
|
212
|
+
|
213
|
+
# Receives the next "line" from the tube; lines are separated by +sep+.
|
214
|
+
# The difference with +IO#gets+ is using +context.newline+ as default newline.
|
215
|
+
#
|
216
|
+
# @param [String, Integer] sep
|
217
|
+
# If +String+ is given, use +sep+ as the separator.
|
218
|
+
# If +Integer+ is given, receive exactly +sep+ bytes.
|
219
|
+
# @!macro drop_definition
|
220
|
+
# @!macro timeout_definition
|
221
|
+
#
|
222
|
+
# @return [String]
|
223
|
+
# The next "line".
|
224
|
+
#
|
225
|
+
# @raise [Pwnlib::Errors::EndOfTubeError]
|
226
|
+
# When the remaining data does not contain +sep+.
|
227
|
+
# When the size of the remaining data is less than +sep+.
|
228
|
+
#
|
229
|
+
# @example
|
230
|
+
# Sock.new('127.0.0.1', 1337).gets
|
231
|
+
# #=> "This is line one\n"
|
232
|
+
#
|
233
|
+
# Sock.new('127.0.0.1', 1337).gets(drop: true)
|
234
|
+
# #=> "This is line one"
|
235
|
+
#
|
236
|
+
# Sock.new('127.0.0.1', 1337).gets 'line'
|
237
|
+
# #=> "This is line"
|
238
|
+
#
|
239
|
+
# Sock.new('127.0.0.1', 1337).gets ''
|
240
|
+
# #=> "This is line"
|
241
|
+
#
|
242
|
+
# Sock.new('127.0.0.1', 1337).gets(4)
|
243
|
+
# #=> "This"
|
244
|
+
def gets(sep = context.newline, drop: false, timeout: nil)
|
245
|
+
case sep
|
246
|
+
when Integer
|
247
|
+
recvn(sep, timeout: timeout)
|
248
|
+
when String
|
249
|
+
recvuntil(sep, drop: drop, timeout: timeout)
|
250
|
+
else
|
251
|
+
raise ArgumentError, 'only Integer and String are supported'
|
252
|
+
end
|
253
|
+
end
|
187
254
|
|
188
255
|
# Wrapper around +recvpred+, which will return when a regex matches the string in the buffer.
|
189
256
|
#
|
@@ -198,73 +265,158 @@ module Pwnlib
|
|
198
265
|
recvpred(timeout: timeout) { |data| data =~ regex }
|
199
266
|
end
|
200
267
|
|
201
|
-
# Sends data
|
268
|
+
# Sends data.
|
202
269
|
#
|
203
270
|
# @param [String] data
|
204
|
-
# The +data+ string to
|
271
|
+
# The +data+ string to be sent.
|
272
|
+
#
|
273
|
+
# @!macro send_return_definition
|
205
274
|
def send(data)
|
206
275
|
data = data.to_s
|
207
276
|
log.debug(format('Sent %#x bytes:', data.size))
|
208
|
-
log.indented(hexdump(data), level: DEBUG)
|
277
|
+
log.indented(::Pwnlib::Util::HexDump.hexdump(data), level: DEBUG)
|
209
278
|
send_raw(data)
|
279
|
+
data.size
|
210
280
|
end
|
211
281
|
alias write send
|
212
282
|
|
213
|
-
# Sends
|
283
|
+
# Sends the given object with +context.newline+.
|
214
284
|
#
|
215
|
-
# @param [
|
216
|
-
# The
|
217
|
-
|
218
|
-
|
219
|
-
|
285
|
+
# @param [Object] obj
|
286
|
+
# The object to be sent.
|
287
|
+
#
|
288
|
+
# @!macro send_return_definition
|
289
|
+
def sendline(obj)
|
290
|
+
s = obj.to_s + context.newline
|
291
|
+
write(s)
|
292
|
+
end
|
293
|
+
|
294
|
+
# Sends the given object(s).
|
295
|
+
# The difference with +IO#puts+ is using +context.newline+ as default newline.
|
296
|
+
#
|
297
|
+
# @param [Array<Object>] objs
|
298
|
+
# The objects to be sent.
|
299
|
+
#
|
300
|
+
# @!macro send_return_definition
|
301
|
+
#
|
302
|
+
# @example
|
303
|
+
# s.puts
|
304
|
+
# puts client.recv
|
305
|
+
# #
|
306
|
+
# #=> nil
|
307
|
+
#
|
308
|
+
# @example
|
309
|
+
# s.puts('shik', "hao\n", 123)
|
310
|
+
# puts client.recv
|
311
|
+
# # shik
|
312
|
+
# # hao
|
313
|
+
# # 123
|
314
|
+
# #=> nil
|
315
|
+
#
|
316
|
+
# @example
|
317
|
+
# s.puts(["darkhh\n\n", 'wei shi', 360])
|
318
|
+
# puts client.recv
|
319
|
+
# # darkhh
|
320
|
+
# #
|
321
|
+
# # wei shi
|
322
|
+
# # 360
|
323
|
+
# #=> nil
|
324
|
+
def puts(*objs)
|
325
|
+
return write(context.newline) if objs.empty?
|
326
|
+
objs = *objs.flatten
|
327
|
+
s = ''
|
328
|
+
objs.map(&:to_s).each do |elem|
|
329
|
+
s << elem
|
330
|
+
s << context.newline unless elem.end_with?(context.newline)
|
331
|
+
end
|
332
|
+
write(s)
|
220
333
|
end
|
221
|
-
alias puts sendline
|
222
334
|
|
223
335
|
# Does simultaneous reading and writing to the tube. In principle this just connects the tube
|
224
336
|
# to standard in and standard out.
|
225
337
|
def interact
|
226
338
|
log.info('Switching to interactive mode')
|
227
339
|
$stdout.write(@buffer.get)
|
228
|
-
until
|
229
|
-
rs, = IO.select([$stdin,
|
340
|
+
until io_out.closed?
|
341
|
+
rs, = IO.select([$stdin, io_out])
|
230
342
|
if rs.include?($stdin)
|
231
343
|
s = $stdin.readpartial(BUFSIZE)
|
232
344
|
write(s)
|
233
345
|
end
|
234
|
-
if rs.include?(
|
346
|
+
if rs.include?(io_out)
|
235
347
|
s = recv
|
236
348
|
$stdout.write(s)
|
237
349
|
end
|
238
350
|
end
|
351
|
+
rescue ::Pwnlib::Errors::EndOfTubeError
|
352
|
+
log.info('Got EOF in interactive mode')
|
239
353
|
end
|
240
354
|
|
241
355
|
private
|
242
356
|
|
357
|
+
# Normalize direction.
|
358
|
+
#
|
359
|
+
# @param [Symbol] direction
|
360
|
+
#
|
361
|
+
# @return [Array<Symbol>]
|
362
|
+
# If +direction+ equals to
|
363
|
+
# * +:both+, returns +[:read, :write]+
|
364
|
+
# * +:read+ or +:recv+, returns [:read]
|
365
|
+
# * +:write+ or +:send+, returns [:write]
|
366
|
+
# Otherwise, raise +ArgumentError+.
|
367
|
+
def normalize_direction(direction)
|
368
|
+
case direction
|
369
|
+
when :both then %i[read write]
|
370
|
+
when :read, :recv then [:read]
|
371
|
+
when :write, :send then [:write]
|
372
|
+
else
|
373
|
+
raise ArgumentError, 'Only allow :both, :recv, :read, :send and :write passed'
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
243
377
|
def fillbuffer(timeout: nil)
|
244
378
|
data = @timer.countdown(timeout) do
|
245
|
-
self.timeout_raw = @timer.timeout
|
379
|
+
self.timeout_raw = (@timer.timeout == :forever ? nil : @timer.timeout)
|
246
380
|
recv_raw(BUFSIZE)
|
247
381
|
end
|
248
382
|
if data
|
249
383
|
@buffer << data
|
250
384
|
log.debug(format('Received %#x bytes:', data.size))
|
251
|
-
log.indented(hexdump(data), level: DEBUG)
|
385
|
+
log.indented(::Pwnlib::Util::HexDump.hexdump(data), level: DEBUG)
|
252
386
|
end
|
253
387
|
data
|
254
388
|
end
|
255
389
|
|
256
|
-
|
390
|
+
# The IO object of output, will be used for IO.select([io_out]) in interactive mode.
|
391
|
+
#
|
392
|
+
# @return [IO]
|
393
|
+
def io_out
|
394
|
+
raise NotImplementedError, 'Not implemented'
|
257
395
|
end
|
258
396
|
|
259
|
-
|
397
|
+
# @param [String] _data
|
398
|
+
#
|
399
|
+
# @return [void]
|
400
|
+
def send_raw(_data)
|
401
|
+
raise NotImplementedError, 'Not implemented'
|
260
402
|
end
|
261
403
|
|
262
|
-
|
404
|
+
# @param [Integer] _size
|
405
|
+
#
|
406
|
+
# @return [String]
|
407
|
+
def recv_raw(_size)
|
408
|
+
raise NotImplementedError, 'Not implemented'
|
409
|
+
end
|
410
|
+
|
411
|
+
# @param [Float?] _timeout
|
412
|
+
#
|
413
|
+
# @return [void]
|
414
|
+
def timeout_raw=(_timeout)
|
415
|
+
raise NotImplementedError, 'Not implemented'
|
263
416
|
end
|
264
417
|
|
265
418
|
include ::Pwnlib::Context
|
266
419
|
include ::Pwnlib::Logger
|
267
|
-
include ::Pwnlib::Util::HexDump
|
268
420
|
end
|
269
421
|
end
|
270
422
|
end
|