pwntools 1.0.0 → 1.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e8617d0c3ce0deb5ba38b0f4c2b4d11c26ff2c48
4
- data.tar.gz: 22a859a445f8fb1fa84c9c164f2f093ccaf81bcb
3
+ metadata.gz: d329dcead1dc5c93633effddf3c627f5071cce80
4
+ data.tar.gz: b5bf6ed6299056cbd1fd93ad6a37e04a992ce3e1
5
5
  SHA512:
6
- metadata.gz: dec0121c94efbe114141de88e820e7ab64c25e64938e44413293a9b61d325ac6dcd0239588b930326a7c7da49378deebcbf94154cc59411e22f8926b95954668
7
- data.tar.gz: 34f90a6171b82df95d5c5a78252ae370cc6251da6deeac65f2bbd011efa251ebf65e7435046cb159e42740c2f072ac6dc5de80f429496ed7f3cd2afe0978b020
6
+ metadata.gz: 71594da6ddc2572a11e2d41c641f04d494d1ea2d3e81ef1a6fd82d92edb3af3599e7099bbdc3393d56a5955fcfd983416dd8be787087fb06d3a586286eb13079
7
+ data.tar.gz: b7cfba8de4134ea156f58244dff5d1a4e7431b376d1a75d9713503552c11911fb103187249e063baef93cac1f1ce651864f64815e5e2105fc539a6d8ef491df8
@@ -80,11 +80,19 @@ module Pwnlib
80
80
  # We use Logger#const_defined for pwnlib logger.
81
81
  LOG_LEVELS = %w(DEBUG INFO WARN ERROR FATAL UNKNOWN).freeze
82
82
 
83
+ # Instantiate a {Pwnlib::Context::ContextType} object.
83
84
  def initialize(**kwargs)
84
85
  @attrs = DEFAULT.dup
85
86
  update(**kwargs)
86
87
  end
87
88
 
89
+ # Convenience function, which is shorthand for setting multiple variables at once.
90
+ #
91
+ # @param [Hash] kwargs
92
+ # Variables to be assigned in the environment.
93
+ #
94
+ # @example
95
+ # context.update(arch: 'amd64', os: :linux)
88
96
  def update(**kwargs)
89
97
  kwargs.each do |k, v|
90
98
  next if v.nil?
@@ -96,12 +104,23 @@ module Pwnlib
96
104
  alias [] update
97
105
  alias call update
98
106
 
107
+ # Create a string representation of self.
99
108
  def to_s
100
109
  vals = @attrs.map { |k, v| "#{k} = #{v.inspect}" }
101
110
  "#{self.class}(#{vals.join(', ')})"
102
111
  end
103
112
 
104
- # This would return what the block return.
113
+ # Create a context manager for a block.
114
+ #
115
+ # @param [Hash] kwargs
116
+ # Variables to be assigned in the environment.
117
+ #
118
+ # @return
119
+ # This would return what the block returned.
120
+ #
121
+ # @example
122
+ # context.local(arch: 'amd64') { puts context.endian }
123
+ # # little
105
124
  def local(**kwargs)
106
125
  raise ArgumentError, "Need a block for #{self.class}##{__callee__}" unless block_given?
107
126
  # XXX(Darkpi):
@@ -116,6 +135,13 @@ module Pwnlib
116
135
  end
117
136
  end
118
137
 
138
+ # Clear the contents of the context, which will set all values to their defaults.
139
+ #
140
+ # @example
141
+ # context.arch = 'amd64'
142
+ # context.clear
143
+ # context.bits == 32
144
+ # #=> true
119
145
  def clear
120
146
  @attrs = DEFAULT.dup
121
147
  end
@@ -125,42 +151,84 @@ module Pwnlib
125
151
  define_method(k) { @attrs[k] }
126
152
  end
127
153
 
154
+ # Set the newline.
155
+ #
156
+ # @param [String] newline
157
+ # The newline.
158
+ #
159
+ # @example
160
+ # context.newline = "\r\n"
128
161
  def newline=(newline)
129
162
  @attrs[:newline] = newline
130
163
  end
131
164
 
165
+ # Set the default amount of time to wait for a blocking operation before it times out.
166
+ #
167
+ # @param [Float, :forever] timeout
168
+ # Any positive floating number, indicates timeout in seconds.
169
+ #
170
+ # @example
171
+ # context.timeout = 5.14
132
172
  def timeout=(timeout)
133
173
  @attrs[:timeout] = timeout
134
174
  end
135
175
 
176
+ # Set the architecture of the target binary.
177
+ #
178
+ # @param [String, Symbol] arch
179
+ # The architecture. Only values in {Pwnlib::Context::ContextType::ARCHS} are available.
180
+ #
136
181
  # @diff We always change +bits+ and +endian+ field whether user have already changed them.
137
182
  def arch=(arch)
138
- arch = arch.downcase.gsub(/[[:punct:]]/, '')
183
+ arch = arch.to_s.downcase.gsub(/[[:punct:]]/, '')
139
184
  defaults = ARCHS[arch]
140
185
  raise ArgumentError, "arch must be one of #{ARCHS.keys.sort.inspect}" unless defaults
141
186
  defaults.each { |k, v| @attrs[k] = v }
142
187
  @attrs[:arch] = arch
143
188
  end
144
189
 
190
+ # Set the word size of the target machine in bits (i.e. the size of general purpose registers).
191
+ #
192
+ # @param [Integer] bits
193
+ # The word size.
145
194
  def bits=(bits)
146
195
  raise ArgumentError, "bits must be > 0 (#{bits} given)" unless bits > 0
147
196
  @attrs[:bits] = bits
148
197
  end
149
198
 
199
+ # The word size of the target machine.
150
200
  def bytes
151
201
  bits / 8
152
202
  end
153
203
 
204
+ # Set the word size of the target machine in bytes (i.e. the size of general purpose registers).
205
+ #
206
+ # @param [Integer] bytes
207
+ # The word size.
154
208
  def bytes=(bytes)
155
209
  self.bits = bytes * 8
156
210
  end
157
211
 
212
+ # The endianness of the target machine.
213
+ #
214
+ # @param [String, Symbol] endian
215
+ # The endianness. Only values in {Pwnlib::Context::ContextType::ENDIANNESSES} are available.
216
+ #
217
+ # @example
218
+ # context.endian = :big
158
219
  def endian=(endian)
159
- endian = ENDIANNESSES[endian.downcase]
220
+ endian = ENDIANNESSES[endian.to_s.downcase]
160
221
  raise ArgumentError, "endian must be one of #{ENDIANNESSES.sort.inspect}" if endian.nil?
161
222
  @attrs[:endian] = endian
162
223
  end
163
224
 
225
+ # Set the verbosity of the logger in +Pwnlib+.
226
+ #
227
+ # @param [String, Symbol] value
228
+ # The verbosity. Only values in {Pwnlib::Context::ContextType::LOG_LEVELS} are available.
229
+ #
230
+ # @example
231
+ # context.log_level = :debug
164
232
  def log_level=(value)
165
233
  log_level = nil
166
234
  case value
@@ -174,17 +242,35 @@ module Pwnlib
174
242
  @attrs[:log_level] = log_level
175
243
  end
176
244
 
245
+ # Set the operating system of the target machine.
246
+ #
247
+ # @param [String, Symbol] os
248
+ # The name of the os. Only values in {Pwnlib::Context::ContextType::OSES} are available.
249
+ #
250
+ # @example
251
+ # context.os = :windows
177
252
  def os=(os)
178
- os = os.downcase
253
+ os = os.to_s.downcase
179
254
  raise ArgumentError, "os must be one of #{OSES.sort.inspect}" unless OSES.include?(os)
180
255
  @attrs[:os] = os
181
256
  end
182
257
 
258
+ # Set the signedness for packing opreation.
259
+ #
260
+ # @param [String, Symbol, true, false] value
261
+ # The signedness. Only values in {Pwnlib::Context::ContextType::SIGNEDNESSES} are available.
262
+ #
263
+ # @example
264
+ # context.signed == false
265
+ # #=> true
266
+ # context.signed = 'signed'
267
+ # context.signed == true
268
+ # #=> true
183
269
  def signed=(value)
184
270
  signed = nil
185
271
  case value
186
- when String
187
- signed = SIGNEDNESSES[value.downcase]
272
+ when String, Symbol
273
+ signed = SIGNEDNESSES[value.to_s.downcase]
188
274
  when true, false
189
275
  signed = value
190
276
  end
@@ -115,7 +115,7 @@ module Pwnlib
115
115
  #
116
116
  # @return [Boolean] Yes or not.
117
117
  def canary?
118
- @got.respond_to?('__stack_chk_fail')
118
+ @got.respond_to?('__stack_chk_fail') || @symbols.respond_to?('__stack_chk_fail')
119
119
  end
120
120
 
121
121
  # Is stack executable?
@@ -133,9 +133,9 @@ module Pwnlib
133
133
  end
134
134
 
135
135
  # There's too many objects inside, let pry not so verbose.
136
- # @return [nil]
136
+ # @return [String]
137
137
  def inspect
138
- nil
138
+ "#<Pwnlib::ELF::ELF:#{::Pwnlib::Util::Fiddling.hex(__id__)}>"
139
139
  end
140
140
 
141
141
  # Yields the ELF's virtual address space for the specified string or regexp.
@@ -191,7 +191,7 @@ module Pwnlib
191
191
  # Get the dynamic tag with +type+.
192
192
  # @return [ELFTools::Dynamic::Tag, nil]
193
193
  def dynamic_tag(type)
194
- dynamic = @elf_file.segment_by_type(:dynamic) || @elf.section_by_name('.dynamic')
194
+ dynamic = @elf_file.segment_by_type(:dynamic) || @elf_file.section_by_name('.dynamic')
195
195
  return nil if dynamic.nil? # No dynamic present, might be static-linked.
196
196
  dynamic.tag_by_type(type)
197
197
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Pwnlib
4
4
  # version of pwntools-ruby
5
- VERSION = '1.0.0'.freeze
5
+ VERSION = '1.0.1'.freeze
6
6
  end
@@ -8,7 +8,7 @@ class ContextTest < MiniTest::Test
8
8
  include ::Pwnlib::Context
9
9
 
10
10
  def test_update
11
- context.update(arch: 'arm', os: 'windows')
11
+ context.update(arch: :arm, os: 'windows')
12
12
  assert_equal('arm', context.arch)
13
13
  assert_equal('windows', context.os)
14
14
  end
@@ -49,7 +49,7 @@ class ContextTest < MiniTest::Test
49
49
 
50
50
  context.clear
51
51
  assert_equal(32, context.bits)
52
- context.arch = 'powerpc64'
52
+ context.arch = :powerpc64
53
53
  assert_equal(64, context.bits)
54
54
  assert_equal('big', context.endian)
55
55
  end
@@ -75,7 +75,7 @@ class ContextTest < MiniTest::Test
75
75
  context.endian = 'le'
76
76
  assert_equal('little', context.endian)
77
77
 
78
- context.endian = 'big'
78
+ context.endian = :big
79
79
  assert_equal('big', context.endian)
80
80
 
81
81
  err = assert_raises(ArgumentError) { context.endian = 'SUPERBIG' }
@@ -86,6 +86,9 @@ class ContextTest < MiniTest::Test
86
86
  context.log_level = 'error'
87
87
  assert_equal(Logger::ERROR, context.log_level)
88
88
 
89
+ context.log_level = :fatal
90
+ assert_equal(Logger::FATAL, context.log_level)
91
+
89
92
  context.log_level = 514
90
93
  assert_equal(514, context.log_level)
91
94
 
@@ -97,6 +100,9 @@ class ContextTest < MiniTest::Test
97
100
  context.os = 'windows'
98
101
  assert_equal('windows', context.os)
99
102
 
103
+ context.os = :freebsd
104
+ assert_equal('freebsd', context.os)
105
+
100
106
  err = assert_raises(ArgumentError) { context.os = 'deepblue' }
101
107
  assert_match(/os must be one of/, err.message)
102
108
  end
@@ -108,6 +114,9 @@ class ContextTest < MiniTest::Test
108
114
  context.signed = 'unsigned'
109
115
  assert_equal(false, context.signed)
110
116
 
117
+ context.signed = :yes
118
+ assert_equal(true, context.signed)
119
+
111
120
  err = assert_raises(ArgumentError) { context.signed = 'partial' }
112
121
  assert_match(/signed must be boolean or one of/, err.message)
113
122
  end
@@ -5,6 +5,7 @@ NOPIE_FLAGS=-no-pie
5
5
  FULL_RELRO_FLAGS=-Wl,-z,relro,-z,now
6
6
  PARTIAL_RELRO_FLAGS=-Wl,-z,relro
7
7
  NO_RELRO_FLAGS=-Wl,-z,norelro
8
+ STATIC_FLAGS=-static
8
9
  TARGETS=amd64 i386
9
10
  .PHONY: clean
10
11
  all: ${TARGETS}
@@ -14,6 +15,7 @@ amd64: ${source}
14
15
  g++ -m64 ${source} -o amd64.frelro.pie.elf ${FLAGS} ${FULL_RELRO_FLAGS} ${PIE_FLAGS}
15
16
  g++ -m64 ${source} -o amd64.prelro.elf ${FLAGS} ${PARTIAL_RELRO_FLAGS} ${NOPIE_FLAGS}
16
17
  g++ -m64 ${source} -o amd64.nrelro.elf ${FLAGS} ${NO_RELRO_FLAGS} ${NOPIE_FLAGS}
18
+ g++ -m64 ${source} -o amd64.static.elf ${FLAGS} ${STATIC_FLAGS} ${NOPIE_FLAGS}
17
19
  i386: ${source}
18
20
  g++ -m32 ${source} -o i386.prelro.elf ${FLAGS} ${PARTIAL_RELRO_FLAGS} ${NOPIE_FLAGS}
19
21
  g++ -m32 ${source} -o i386.frelro.pie.elf ${FLAGS} ${FULL_RELRO_FLAGS} ${PIE_FLAGS}
@@ -60,6 +60,10 @@ PIE: No PIE (0x400000)
60
60
  EOS
61
61
  end
62
62
 
63
+ def test_inspect
64
+ assert_match(/#<Pwnlib::ELF::ELF:0x[0-9a-f]+>/, @elf.inspect)
65
+ end
66
+
63
67
  def test_got
64
68
  assert_same(8, @elf.got.to_h.size)
65
69
  assert_same(0x8049ff8, @elf.got['__gmon_start__'])
@@ -94,6 +98,16 @@ PIE: No PIE (0x400000)
94
98
  assert_equal(0xdeadbeef06c2, elf.symbols.main)
95
99
  end
96
100
 
101
+ def test_static
102
+ elf = ::Pwnlib::ELF::ELF.new(@path_of.call('amd64.static.elf'), checksec: false)
103
+ assert_equal(<<-EOS.strip, elf.checksec)
104
+ RELRO: Partial RELRO
105
+ Stack: Canary found
106
+ NX: NX enabled
107
+ PIE: No PIE (0x400000)
108
+ EOS
109
+ end
110
+
97
111
  def test_search
98
112
  elf = ::Pwnlib::ELF::ELF.new(File.join(__dir__, '..', 'data', 'lib32', 'libc.so.6'), checksec: false)
99
113
  assert_equal([0x1, 0x15e613], elf.search('ELF').to_a)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pwntools
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - peter50216@gmail.com
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2017-10-17 00:00:00.000000000 Z
13
+ date: 2017-11-02 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: crabstone
@@ -291,6 +291,7 @@ files:
291
291
  - test/data/elfs/amd64.frelro.pie.elf
292
292
  - test/data/elfs/amd64.nrelro.elf
293
293
  - test/data/elfs/amd64.prelro.elf
294
+ - test/data/elfs/amd64.static.elf
294
295
  - test/data/elfs/i386.frelro.pie.elf
295
296
  - test/data/elfs/i386.prelro.elf
296
297
  - test/data/elfs/source.cpp
@@ -368,6 +369,7 @@ test_files:
368
369
  - test/data/elfs/i386.frelro.pie.elf
369
370
  - test/data/elfs/amd64.nrelro.elf
370
371
  - test/data/elfs/i386.prelro.elf
372
+ - test/data/elfs/amd64.static.elf
371
373
  - test/data/elfs/amd64.prelro.elf
372
374
  - test/data/elfs/source.cpp
373
375
  - test/data/victim32