pwntools 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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