pwntools 1.1.0 → 1.2.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 (153) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -3
  3. data/lib/pwn.rb +1 -0
  4. data/lib/pwnlib/abi.rb +1 -0
  5. data/lib/pwnlib/asm.rb +83 -42
  6. data/lib/pwnlib/constants/constant.rb +4 -1
  7. data/lib/pwnlib/constants/constants.rb +3 -0
  8. data/lib/pwnlib/constants/linux/amd64.rb +2 -0
  9. data/lib/pwnlib/constants/linux/i386.rb +2 -0
  10. data/lib/pwnlib/context.rb +10 -1
  11. data/lib/pwnlib/dynelf.rb +7 -2
  12. data/lib/pwnlib/elf/elf.rb +79 -6
  13. data/lib/pwnlib/errors.rb +3 -2
  14. data/lib/pwnlib/ext/array.rb +2 -1
  15. data/lib/pwnlib/ext/helper.rb +3 -2
  16. data/lib/pwnlib/ext/integer.rb +2 -1
  17. data/lib/pwnlib/ext/string.rb +3 -2
  18. data/lib/pwnlib/logger.rb +21 -1
  19. data/lib/pwnlib/memleak.rb +1 -0
  20. data/lib/pwnlib/pwn.rb +5 -1
  21. data/lib/pwnlib/reg_sort.rb +5 -0
  22. data/lib/pwnlib/runner.rb +53 -0
  23. data/lib/pwnlib/shellcraft/generators/amd64/common/common.rb +2 -0
  24. data/lib/pwnlib/shellcraft/generators/amd64/common/infloop.rb +1 -0
  25. data/lib/pwnlib/shellcraft/generators/amd64/common/memcpy.rb +5 -1
  26. data/lib/pwnlib/shellcraft/generators/amd64/common/mov.rb +4 -0
  27. data/lib/pwnlib/shellcraft/generators/amd64/common/nop.rb +2 -0
  28. data/lib/pwnlib/shellcraft/generators/amd64/common/popad.rb +1 -0
  29. data/lib/pwnlib/shellcraft/generators/amd64/common/pushstr.rb +3 -1
  30. data/lib/pwnlib/shellcraft/generators/amd64/common/pushstr_array.rb +1 -0
  31. data/lib/pwnlib/shellcraft/generators/amd64/common/ret.rb +1 -0
  32. data/lib/pwnlib/shellcraft/generators/amd64/common/setregs.rb +3 -2
  33. data/lib/pwnlib/shellcraft/generators/amd64/linux/cat.rb +3 -2
  34. data/lib/pwnlib/shellcraft/generators/amd64/linux/execve.rb +1 -0
  35. data/lib/pwnlib/shellcraft/generators/amd64/linux/exit.rb +1 -0
  36. data/lib/pwnlib/shellcraft/generators/amd64/linux/linux.rb +2 -0
  37. data/lib/pwnlib/shellcraft/generators/amd64/linux/ls.rb +1 -0
  38. data/lib/pwnlib/shellcraft/generators/amd64/linux/open.rb +1 -0
  39. data/lib/pwnlib/shellcraft/generators/amd64/linux/sh.rb +3 -2
  40. data/lib/pwnlib/shellcraft/generators/amd64/linux/sleep.rb +24 -0
  41. data/lib/pwnlib/shellcraft/generators/amd64/linux/syscall.rb +1 -0
  42. data/lib/pwnlib/shellcraft/generators/helper.rb +11 -2
  43. data/lib/pwnlib/shellcraft/generators/i386/common/common.rb +2 -0
  44. data/lib/pwnlib/shellcraft/generators/i386/common/infloop.rb +1 -0
  45. data/lib/pwnlib/shellcraft/generators/i386/common/memcpy.rb +34 -0
  46. data/lib/pwnlib/shellcraft/generators/i386/common/mov.rb +3 -0
  47. data/lib/pwnlib/shellcraft/generators/i386/common/nop.rb +2 -0
  48. data/lib/pwnlib/shellcraft/generators/i386/common/pushstr.rb +2 -0
  49. data/lib/pwnlib/shellcraft/generators/i386/common/pushstr_array.rb +1 -0
  50. data/lib/pwnlib/shellcraft/generators/i386/common/setregs.rb +3 -2
  51. data/lib/pwnlib/shellcraft/generators/i386/linux/cat.rb +3 -2
  52. data/lib/pwnlib/shellcraft/generators/i386/linux/execve.rb +1 -0
  53. data/lib/pwnlib/shellcraft/generators/i386/linux/exit.rb +1 -0
  54. data/lib/pwnlib/shellcraft/generators/i386/linux/linux.rb +2 -0
  55. data/lib/pwnlib/shellcraft/generators/i386/linux/ls.rb +1 -0
  56. data/lib/pwnlib/shellcraft/generators/i386/linux/open.rb +1 -0
  57. data/lib/pwnlib/shellcraft/generators/i386/linux/sh.rb +3 -2
  58. data/lib/pwnlib/shellcraft/generators/i386/linux/sleep.rb +24 -0
  59. data/lib/pwnlib/shellcraft/generators/i386/linux/syscall.rb +1 -0
  60. data/lib/pwnlib/shellcraft/generators/x86/common/common.rb +5 -3
  61. data/lib/pwnlib/shellcraft/generators/x86/common/infloop.rb +2 -0
  62. data/lib/pwnlib/shellcraft/generators/x86/common/memcpy.rb +17 -0
  63. data/lib/pwnlib/shellcraft/generators/x86/common/mov.rb +2 -0
  64. data/lib/pwnlib/shellcraft/generators/x86/common/pushstr.rb +2 -0
  65. data/lib/pwnlib/shellcraft/generators/x86/common/pushstr_array.rb +1 -0
  66. data/lib/pwnlib/shellcraft/generators/x86/common/setregs.rb +8 -6
  67. data/lib/pwnlib/shellcraft/generators/x86/linux/cat.rb +1 -0
  68. data/lib/pwnlib/shellcraft/generators/x86/linux/execve.rb +3 -0
  69. data/lib/pwnlib/shellcraft/generators/x86/linux/exit.rb +1 -0
  70. data/lib/pwnlib/shellcraft/generators/x86/linux/linux.rb +2 -0
  71. data/lib/pwnlib/shellcraft/generators/x86/linux/ls.rb +1 -0
  72. data/lib/pwnlib/shellcraft/generators/x86/linux/open.rb +1 -0
  73. data/lib/pwnlib/shellcraft/generators/x86/linux/sh.rb +1 -0
  74. data/lib/pwnlib/shellcraft/generators/x86/linux/sleep.rb +52 -0
  75. data/lib/pwnlib/shellcraft/generators/x86/linux/syscall.rb +10 -10
  76. data/lib/pwnlib/shellcraft/registers.rb +5 -1
  77. data/lib/pwnlib/shellcraft/shellcraft.rb +8 -3
  78. data/lib/pwnlib/timer.rb +6 -2
  79. data/lib/pwnlib/tubes/buffer.rb +4 -1
  80. data/lib/pwnlib/tubes/process.rb +2 -0
  81. data/lib/pwnlib/tubes/serialtube.rb +3 -1
  82. data/lib/pwnlib/tubes/sock.rb +7 -1
  83. data/lib/pwnlib/tubes/tube.rb +23 -3
  84. data/lib/pwnlib/ui.rb +21 -0
  85. data/lib/pwnlib/util/cyclic.rb +2 -0
  86. data/lib/pwnlib/util/fiddling.rb +37 -5
  87. data/lib/pwnlib/util/getdents.rb +1 -0
  88. data/lib/pwnlib/util/hexdump.rb +8 -5
  89. data/lib/pwnlib/util/lists.rb +3 -0
  90. data/lib/pwnlib/util/packing.rb +5 -2
  91. data/lib/pwnlib/util/ruby.rb +1 -0
  92. data/lib/pwnlib/version.rb +2 -1
  93. data/test/abi_test.rb +1 -0
  94. data/test/asm_test.rb +75 -85
  95. data/test/constants/constant_test.rb +1 -0
  96. data/test/constants/constants_test.rb +1 -0
  97. data/test/context_test.rb +1 -0
  98. data/test/data/assembly/aarch64.s +19 -0
  99. data/test/data/assembly/amd64.s +21 -0
  100. data/test/data/assembly/arm.s +9 -0
  101. data/test/data/assembly/i386.s +21 -0
  102. data/test/data/assembly/mips.s +16 -0
  103. data/test/data/assembly/mips64.s +6 -0
  104. data/test/data/assembly/powerpc.s +18 -0
  105. data/test/data/assembly/powerpc64.s +36 -0
  106. data/test/data/assembly/sparc.s +33 -0
  107. data/test/data/assembly/sparc64.s +5 -0
  108. data/test/data/assembly/thumb.s +37 -0
  109. data/test/data/echo.rb +1 -0
  110. data/test/dynelf_test.rb +3 -1
  111. data/test/elf/elf_test.rb +18 -0
  112. data/test/ext_test.rb +1 -0
  113. data/test/files/use_pwn.rb +1 -0
  114. data/test/files/use_pwnlib.rb +1 -0
  115. data/test/full_file_test.rb +6 -0
  116. data/test/logger_test.rb +24 -3
  117. data/test/memleak_test.rb +1 -0
  118. data/test/reg_sort_test.rb +1 -0
  119. data/test/runner_test.rb +32 -0
  120. data/test/shellcraft/infloop_test.rb +1 -0
  121. data/test/shellcraft/linux/cat_test.rb +1 -0
  122. data/test/shellcraft/linux/ls_test.rb +1 -0
  123. data/test/shellcraft/linux/sh_test.rb +1 -0
  124. data/test/shellcraft/linux/sleep_test.rb +68 -0
  125. data/test/shellcraft/linux/syscalls/execve_test.rb +1 -0
  126. data/test/shellcraft/linux/syscalls/exit_test.rb +1 -0
  127. data/test/shellcraft/linux/syscalls/open_test.rb +1 -0
  128. data/test/shellcraft/linux/syscalls/syscall_test.rb +1 -0
  129. data/test/shellcraft/memcpy_test.rb +20 -5
  130. data/test/shellcraft/mov_test.rb +1 -0
  131. data/test/shellcraft/nop_test.rb +1 -0
  132. data/test/shellcraft/popad_test.rb +1 -0
  133. data/test/shellcraft/pushstr_array_test.rb +1 -0
  134. data/test/shellcraft/pushstr_test.rb +1 -0
  135. data/test/shellcraft/registers_test.rb +1 -0
  136. data/test/shellcraft/ret_test.rb +1 -0
  137. data/test/shellcraft/setregs_test.rb +9 -8
  138. data/test/shellcraft/shellcraft_test.rb +1 -0
  139. data/test/test_helper.rb +28 -0
  140. data/test/timer_test.rb +2 -1
  141. data/test/tubes/buffer_test.rb +1 -0
  142. data/test/tubes/process_test.rb +8 -2
  143. data/test/tubes/serialtube_test.rb +1 -4
  144. data/test/tubes/sock_test.rb +1 -0
  145. data/test/tubes/tube_test.rb +10 -1
  146. data/test/ui_test.rb +18 -0
  147. data/test/util/cyclic_test.rb +1 -0
  148. data/test/util/fiddling_test.rb +8 -0
  149. data/test/util/getdents_test.rb +1 -0
  150. data/test/util/hexdump_test.rb +2 -1
  151. data/test/util/lists_test.rb +1 -0
  152. data/test/util/packing_test.rb +3 -2
  153. metadata +119 -59
@@ -1,11 +1,12 @@
1
1
  # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
 
3
4
  module Pwnlib
4
5
  # Generic {Pwnlib} exception class.
5
6
  class Error < StandardError
6
7
  end
7
8
 
8
- # Pnwlib Errors
9
+ # {Pwnlib} Errors.
9
10
  module Errors
10
11
  # Raised by some IO operations in tubes.
11
12
  class EndOfTubeError < ::Pwnlib::Error
@@ -23,7 +24,7 @@ module Pwnlib
23
24
  class TimeoutError < ::Pwnlib::Error
24
25
  end
25
26
 
26
- # Raised when method doesn't support under current architecture.
27
+ # Raised when a method is not supported under current architecture.
27
28
  class UnsupportedArchError < ::Pwnlib::Error
28
29
  end
29
30
  end
@@ -1,4 +1,5 @@
1
1
  # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pwnlib/ext/helper'
4
5
  require 'pwnlib/util/fiddling'
@@ -18,4 +19,4 @@ module Pwnlib
18
19
  end
19
20
  end
20
21
 
21
- ::Array.public_send(:include, ::Pwnlib::Ext::Array::InstanceMethods)
22
+ ::Array.include ::Pwnlib::Ext::Array::InstanceMethods
@@ -1,4 +1,5 @@
1
1
  # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
 
3
4
  module Pwnlib
4
5
  module Ext
@@ -10,8 +11,8 @@ module Pwnlib
10
11
  .concat(m2.to_a)
11
12
  .each do |method, proxy_to|
12
13
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
13
- def #{method}(*args, &block)
14
- #{mod}.#{proxy_to}(self, *args, &block)
14
+ def #{method}(*args, **kwargs, &block)
15
+ #{mod}.#{proxy_to}(self, *args, **kwargs, &block)
15
16
  end
16
17
  EOS
17
18
  end
@@ -1,4 +1,5 @@
1
1
  # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pwnlib/ext/helper'
4
5
  require 'pwnlib/util/packing'
@@ -18,4 +19,4 @@ module Pwnlib
18
19
  end
19
20
  end
20
21
 
21
- ::Integer.public_send(:include, ::Pwnlib::Ext::Integer::InstanceMethods)
22
+ ::Integer.include ::Pwnlib::Ext::Integer::InstanceMethods
@@ -1,4 +1,5 @@
1
1
  # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pwnlib/ext/helper'
4
5
  require 'pwnlib/util/fiddling'
@@ -13,11 +14,11 @@ module Pwnlib
13
14
 
14
15
  def_proxy_method ::Pwnlib::Util::Packing, %w(unpack unpack_many u8 u16 u32 u64)
15
16
  def_proxy_method ::Pwnlib::Util::Fiddling, %w(
16
- enhex unhex urlencode urldecode bits bits_str unbits bitswap b64e b64d
17
+ enhex unhex urlencode urldecode bits bits_str unbits bitswap b64e b64d xor
17
18
  )
18
19
  end
19
20
  end
20
21
  end
21
22
  end
22
23
 
23
- ::String.public_send(:include, ::Pwnlib::Ext::String::InstanceMethods)
24
+ ::String.include ::Pwnlib::Ext::String::InstanceMethods
@@ -1,4 +1,5 @@
1
1
  # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'logger'
4
5
 
@@ -37,6 +38,19 @@ module Pwnlib
37
38
  @formatter = proc do |severity, _datetime, progname, msg|
38
39
  format("[%s] %s\n", Rainbow(progname || severity).color(SEV_COLOR[severity]), msg)
39
40
  end
41
+
42
+ # Cache the file content so we can modify the file when it's running.
43
+ # If the source is modified before the first call, parsing source file
44
+ # might still fail.
45
+ @source_of_file_cache = Hash.new do |h, key|
46
+ next if key.nil?
47
+
48
+ h[key] = IO.read(key)
49
+ end
50
+
51
+ # As a naive heuristic for the most common single file use case, adding
52
+ # the last file from the execution stack.
53
+ @source_of_file_cache[caller_locations.last.absolute_path]
40
54
  end
41
55
 
42
56
  # Log the message with indent.
@@ -47,6 +61,7 @@ module Pwnlib
47
61
  # The severity of the message.
48
62
  def indented(message, level: DEBUG)
49
63
  return if @logdev.nil? || level < context.log_level
64
+
50
65
  @logdev.write(
51
66
  message.lines.map { |s| ' ' + s }.join + "\n"
52
67
  )
@@ -108,6 +123,7 @@ module Pwnlib
108
123
  severity = INFO
109
124
  # Don't invoke the block if it's unnecessary.
110
125
  return true if severity < context.log_level
126
+
111
127
  caller_ = caller_locations(1, 1).first
112
128
  src = source_of(caller_.absolute_path, caller_.lineno)
113
129
  results = args.empty? ? [[yield, source_of_block(src)]] : args.zip(source_of_args(src))
@@ -122,11 +138,12 @@ module Pwnlib
122
138
  def add(severity, message = nil, progname = nil)
123
139
  severity ||= UNKNOWN
124
140
  return true if severity < context.log_level
141
+
125
142
  super(severity, message, progname)
126
143
  end
127
144
 
128
145
  def source_of(path, line_number)
129
- File.open(path) { |f| LoggerType.expression_at(f, line_number) }
146
+ LoggerType.expression_at(@source_of_file_cache[path], line_number)
130
147
  end
131
148
 
132
149
  # Find the content of block that invoked by log.dump { ... }.
@@ -168,6 +185,7 @@ module Pwnlib
168
185
  sexp = ::RubyParser.new.process(source)
169
186
  sexp = search_sexp(sexp, target)
170
187
  return nil if sexp.nil?
188
+
171
189
  yield sexp
172
190
  end
173
191
 
@@ -175,6 +193,7 @@ module Pwnlib
175
193
  def search_sexp(sexp, target)
176
194
  return nil unless sexp.is_a?(::Sexp)
177
195
  return sexp if match_sexp?(sexp, target)
196
+
178
197
  sexp.find do |e|
179
198
  f = search_sexp(e, target)
180
199
  break f if f
@@ -185,6 +204,7 @@ module Pwnlib
185
204
  target.zip(sexp.entries).all? do |t, s|
186
205
  next true if t.nil?
187
206
  next match_sexp?(s, t) if t.is_a?(Array)
207
+
188
208
  s == t
189
209
  end
190
210
  end
@@ -1,4 +1,5 @@
1
1
  # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pwnlib/util/packing'
4
5
 
@@ -1,4 +1,5 @@
1
1
  # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
 
3
4
  # require this file would also require all things in pwnlib, but would not pollute anything.
4
5
 
@@ -11,11 +12,12 @@ require 'pwnlib/elf/elf'
11
12
  require 'pwnlib/errors'
12
13
  require 'pwnlib/logger'
13
14
  require 'pwnlib/reg_sort'
15
+ require 'pwnlib/runner'
14
16
  require 'pwnlib/shellcraft/shellcraft'
15
17
  require 'pwnlib/tubes/process'
16
18
  require 'pwnlib/tubes/serialtube'
17
19
  require 'pwnlib/tubes/sock'
18
-
20
+ require 'pwnlib/ui'
19
21
  require 'pwnlib/util/cyclic'
20
22
  require 'pwnlib/util/fiddling'
21
23
  require 'pwnlib/util/getdents'
@@ -28,6 +30,8 @@ module Pwn
28
30
  include ::Pwnlib::Asm
29
31
  include ::Pwnlib::Context
30
32
  include ::Pwnlib::Logger
33
+ include ::Pwnlib::Runner
34
+ include ::Pwnlib::UI
31
35
  include ::Pwnlib::Util::Cyclic
32
36
  include ::Pwnlib::Util::Fiddling
33
37
  include ::Pwnlib::Util::HexDump
@@ -1,4 +1,5 @@
1
1
  # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pwnlib/context'
4
5
  require 'pwnlib/util/ruby'
@@ -70,6 +71,7 @@ module Pwnlib
70
71
  first_reg, val = list.shift
71
72
  # Special case for val.zero? because zeroify registers is cheaper than mov.
72
73
  next if list.empty? || all_regs.include?(val) || val.zero?
74
+
73
75
  list.each do |(reg, _)|
74
76
  hash[reg] = first_reg
75
77
  in_out.delete(reg)
@@ -87,11 +89,13 @@ module Pwnlib
87
89
  until deg.empty?
88
90
  min_deg = deg.min_by { |_, v| v }[1]
89
91
  break unless min_deg.zero? # remain are all cycles
92
+
90
93
  min_pivs = deg.select { |_, v| v == min_deg }
91
94
  piv = randomize ? min_pivs.sample : min_pivs.first
92
95
  dst = piv.first
93
96
  deg.delete(dst)
94
97
  next unless graph.key?(dst) # Reach an end node.
98
+
95
99
  deg[graph[dst]] -= 1
96
100
  result << ['mov', dst, graph[dst]]
97
101
  graph.delete(dst)
@@ -134,6 +138,7 @@ module Pwnlib
134
138
  return [] unless assignments.key?(target)
135
139
  # Found a cycle.
136
140
  return target == path.first ? path : [] if path.include?(target)
141
+
137
142
  check_cycle_(target, assignments, path)
138
143
  end
139
144
  end
@@ -0,0 +1,53 @@
1
+ # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
3
+
4
+ require 'fileutils'
5
+
6
+ require 'pwnlib/asm'
7
+ require 'pwnlib/tubes/process'
8
+
9
+ module Pwnlib
10
+ # This module collects the methods for executing codes, e.g., assembly code, assembled machine code, etc.
11
+ module Runner
12
+ module_function
13
+
14
+ # Given an assembly listing, assemble and execute it.
15
+ #
16
+ # @param [String] assembly
17
+ # Assembly code.
18
+ #
19
+ # @return [Pwnlib::Tubes::Process]
20
+ # The tube for interacting.
21
+ #
22
+ # @see Runner.run_shellcode
23
+ def run_assembly(assembly)
24
+ run_shellcode(::Pwnlib::Asm.asm(assembly))
25
+ end
26
+
27
+ # Given assembled machine code bytes, execute them.
28
+ #
29
+ # @param [String] bytes
30
+ # Assembled code.
31
+ #
32
+ # @return [Pwnlib::Tubes::Process]
33
+ # The tube for interacting.
34
+ #
35
+ # @example
36
+ # r = run_shellcode(asm(shellcraft.cat('/etc/passwd')))
37
+ # r.interact
38
+ # # [INFO] Switching to interactive mode
39
+ # # root:x:0:0:root:/root:/bin/bash
40
+ # # daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
41
+ # # bin:x:2:2:bin:/bin:/usr/sbin/nologin
42
+ # # sys:x:3:3:sys:/dev:/usr/sbin/nologin
43
+ # # sync:x:4:65534:sync:/bin:/bin/sync
44
+ # # games:x:5:60:games:/usr/games:/usr/sbin/nologin
45
+ # # [INFO] Got EOF in interactive mode
46
+ # #=> true
47
+ def run_shellcode(bytes)
48
+ file = ::Pwnlib::Asm.make_elf(bytes, to_file: true)
49
+ at_exit { FileUtils.rm_f(file) if File.exist?(file) }
50
+ ::Pwnlib::Tubes::Process.new(file)
51
+ end
52
+ end
53
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pwnlib/shellcraft/generators/helper'
2
4
 
3
5
  module Pwnlib
@@ -1,4 +1,5 @@
1
1
  # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pwnlib/shellcraft/generators/amd64/common/common'
4
5
  require 'pwnlib/shellcraft/generators/x86/common/infloop'
@@ -1,4 +1,5 @@
1
1
  # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pwnlib/shellcraft/generators/amd64/common/common'
4
5
  require 'pwnlib/shellcraft/generators/amd64/common/setregs'
@@ -18,10 +19,13 @@ module Pwnlib
18
19
  # Source to be copied.
19
20
  # @param [Integer] n
20
21
  # The number of bytes to be copied.
22
+ #
23
+ # @example
24
+ # shellcraft.memcpy('rax', 'rbx', 0x1000)
21
25
  def memcpy(dst, src, n)
22
26
  cat "/* memcpy(#{pretty(dst)}, #{pretty(src)}, #{pretty(n)}) */"
23
27
  cat 'cld'
24
- cat Common.setregs(rdi: dst, rsi: src, rcx: n)
28
+ cat Common.setregs({ rdi: dst, rsi: src, rcx: n })
25
29
  cat 'rep movsb'
26
30
  end
27
31
  end
@@ -1,4 +1,5 @@
1
1
  # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pwnlib/shellcraft/generators/amd64/common/common'
4
5
 
@@ -36,18 +37,21 @@ module Pwnlib
36
37
  # #=> nil
37
38
  def mov(dst, src, stack_allowed: true)
38
39
  raise ArgumentError, "#{dst} is not a register" unless register?(dst)
40
+
39
41
  dst = get_register(dst)
40
42
  if register?(src)
41
43
  src = get_register(src)
42
44
  if dst.size < src.size && !dst.bigger.include?(src.name)
43
45
  raise ArgumentError, "cannot mov #{dst}, #{src}: dst is smaller than src"
44
46
  end
47
+
45
48
  # Downgrade our register choice if possible.
46
49
  # Opcodes for operating on 32-bit registers are always (?) shorter.
47
50
  dst = get_register(dst.native32) if dst.size == 64 && src.size <= 32
48
51
  else
49
52
  context.local(arch: 'amd64') { src = evaluate(src) }
50
53
  raise ArgumentError, format('cannot mov %s, %d: dst is smaller than src', dst, src) unless dst.fits(src)
54
+
51
55
  orig_dst = dst
52
56
  dst = get_register(dst.native32) if dst.size == 64 && bits_required(src) <= 32
53
57
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pwnlib/shellcraft/generators/amd64/common/common'
2
4
 
3
5
  module Pwnlib
@@ -1,4 +1,5 @@
1
1
  # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pwnlib/shellcraft/generators/amd64/common/common'
4
5
 
@@ -1,4 +1,5 @@
1
1
  # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pwnlib/shellcraft/generators/amd64/common/common'
4
5
 
@@ -27,6 +28,7 @@ module Pwnlib
27
28
  # This will not affect callee's +str+.
28
29
  str += "\x00" if append_null && !str.end_with?("\x00")
29
30
  return if str.empty?
31
+
30
32
  padding = str[-1].ord >= 128 ? "\xff" : "\x00"
31
33
  cat "/* push #{str.inspect} */"
32
34
  group(8, str, underfull_action: :fill, fill_value: padding).reverse_each do |word|
@@ -43,7 +45,7 @@ module Pwnlib
43
45
  elsif okay(word)
44
46
  cat "mov rax, #{pretty(sign)}"
45
47
  cat 'push rax'
46
- elsif sign32 > 0 && word[4, 4] == "\x00" * 4
48
+ elsif sign32.positive? && word[4, 4] == "\x00" * 4
47
49
  # The high 4 byte of word are all zeros, so we can use +xor dword ptr [rsp]+.
48
50
  a = u32(xor_pair(word[0, 4]).first, endian: 'little', signed: true)
49
51
  cat "push #{pretty(a)} ^ #{pretty(sign)}"
@@ -1,4 +1,5 @@
1
1
  # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pwnlib/shellcraft/generators/amd64/common/common'
4
5
  require 'pwnlib/shellcraft/generators/x86/common/pushstr_array'
@@ -1,4 +1,5 @@
1
1
  # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pwnlib/shellcraft/generators/amd64/common/common'
4
5
  require 'pwnlib/shellcraft/generators/amd64/common/mov'
@@ -1,4 +1,5 @@
1
1
  # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pwnlib/shellcraft/generators/amd64/common/common'
4
5
  require 'pwnlib/shellcraft/generators/x86/common/setregs'
@@ -11,9 +12,9 @@ module Pwnlib
11
12
  # @overload setregs(reg_context, stack_allowed: true)
12
13
  #
13
14
  # @see Generators::X86::Common#setregs
14
- def setregs(*args)
15
+ def setregs(*args, **kwargs)
15
16
  context.local(arch: :amd64) do
16
- cat X86::Common.setregs(*args)
17
+ cat X86::Common.setregs(*args, **kwargs)
17
18
  end
18
19
  end
19
20
  end
@@ -1,4 +1,5 @@
1
1
  # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pwnlib/shellcraft/generators/amd64/linux/linux'
4
5
  require 'pwnlib/shellcraft/generators/x86/linux/cat'
@@ -11,9 +12,9 @@ module Pwnlib
11
12
  # @overload cat(filename, fd: 1)
12
13
  #
13
14
  # @see Generators::X86::Linux#cat
14
- def cat(*args)
15
+ def cat(*args, **kwargs)
15
16
  context.local(arch: :amd64) do
16
- cat X86::Linux.cat(*args)
17
+ cat X86::Linux.cat(*args, **kwargs)
17
18
  end
18
19
  end
19
20
  end
@@ -1,4 +1,5 @@
1
1
  # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pwnlib/shellcraft/generators/amd64/linux/linux'
4
5
  require 'pwnlib/shellcraft/generators/x86/linux/execve'
@@ -1,4 +1,5 @@
1
1
  # encoding: ASCII-8BIT
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'pwnlib/shellcraft/generators/amd64/linux/linux'
4
5
  require 'pwnlib/shellcraft/generators/x86/linux/exit'