undll32 0.2.0 → 0.3.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 (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/undll32.rb +149 -21
  3. data/lib/undll32/version.rb +1 -1
  4. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 79d24bcf938e3a23a7e87f932a6189c7248b690a1fc5766e7907cf056b0967e6
4
- data.tar.gz: 29faa69356a53024534261b815fa3f7c3bfd5d01f429877fe5c6f1f5da273572
3
+ metadata.gz: dc86272423576ea01bf2666535b63302cfabd49e12b672c168d49b84fadaa814
4
+ data.tar.gz: 1f92550e71c6429d1fdd4ce75fffd759888fddd1a9f127c93424605fd38de2ce
5
5
  SHA512:
6
- metadata.gz: f336b0b7936b6e1dd2d744126263e00869a68500e8346ce971393f8dfbc7520d4068b70cc7c3c3cc3187a5ae809b9b934f2a6c56724fcf6919284ae046736230
7
- data.tar.gz: 490a671e93edc615934ae0372731aebec5d6978c54d2e4ffba85cfd978ab7f5ccf562e42d0ac9c44b15aada37e34c24bf6ec9c455039266de5f58f19d9956c82
6
+ metadata.gz: 4a9bc8bbbd5a4e597ce2847892552b4dc3a7b149aac05658bf0d68c9270e4d151a6af4f6557a314682ae90c5c9d11fa07b013dc067b0b8bb9b5ddc03d9192c02
7
+ data.tar.gz: '0692dddf565e76242e9c4bcb5e18d6f4bac407fe9bfb33ac1565e8fe9dfb87de6fb707cd7621f5695feae8eb24998d9e7205ae77235b41cc75c265feb8b91d0e'
@@ -15,6 +15,8 @@ module Undll32
15
15
  # buffer.buffer => "\0\0\0\0"
16
16
  # buffer.unpack => 0
17
17
  class Buffer
18
+ attr_accessor :struct
19
+
18
20
  def initialize struct
19
21
  case struct
20
22
  when Hash, Array, Symbol, Integer
@@ -33,22 +35,63 @@ module Undll32
33
35
  _unpack @struct
34
36
  end
35
37
 
36
- def _unpack x
38
+ def load v
39
+ @_i = 0
40
+ _load @struct, v
41
+ unpack
42
+ end
43
+
44
+ def _load x, v
37
45
  case x
38
46
  when Integer
39
- buffer[(@_i += x) - x, x].sub(/\0+$/, '')
47
+ return @_i += x if v.nil?
48
+ unless String === v
49
+ raise ArgumentError, "expected str, got #{v}"
50
+ end
51
+ x = [x, v.length].min
52
+ buffer[(@_i += x) - x, x] = v[0, x]
40
53
  when Symbol
41
54
  n = { C: 1, S: 2, L: 4, Q: 8 }[x]
42
55
  if n.nil?
43
56
  raise ArgumentError, "expected CSLQ, got #{x}"
44
57
  end
58
+ return @_i += n if v.nil?
59
+ unless Integer === v
60
+ raise ArgumentError, "expected int, got #{v}"
61
+ end
62
+ buffer[(@_i += n) - n, n] = [v].pack("#{x}")
63
+ when Array
64
+ return x.each { |a| _load a, nil } if v.nil?
65
+ unless Array === v and v.size == x.size
66
+ raise ArgumentError, "expected array[#{x.size}], got #{v}"
67
+ end
68
+ x.zip(v) { |a, b| _load a, b }
69
+ when Hash
70
+ return x.each { |k, y| _load y, nil } if v.nil?
71
+ unless Hash === v
72
+ raise ArgumentError, "expected hash, got #{v}"
73
+ end
74
+ x.each { |k, y| _load y, v[k] }
75
+ else
76
+ raise ArgumentError, "expected hash, array, sym, int, got #{x}"
77
+ end
78
+ ensure
79
+ $@.shift if $@
80
+ end
81
+
82
+ def _unpack x
83
+ case x
84
+ when Integer
85
+ buffer[(@_i += x) - x, x].sub(/\0+$/, '')
86
+ when Symbol
87
+ n = { C: 1, S: 2, L: 4, Q: 8 }[x]
45
88
  buffer[(@_i += n) - n, n].unpack1("#{x}")
46
89
  when Array
47
90
  x.map { |e| _unpack e }
48
91
  when Hash
49
92
  Hash[x.map { |k, v| [k, _unpack(v)] }]
50
93
  else
51
- raise ArgumentError, "expected hash, array, sym, int, got #{struct}"
94
+ raise ArgumentError, "expected hash, array, sym, int, got #{x}"
52
95
  end
53
96
  ensure
54
97
  $@.shift if $@
@@ -69,50 +112,132 @@ module Undll32
69
112
  when Hash
70
113
  _buffer x.values
71
114
  else
72
- raise ArgumentError, "expected hash, array, sym, int, got #{struct}"
115
+ raise ArgumentError, "expected hash, array, sym, int, got #{x}"
73
116
  end
74
117
  ensure
75
118
  $@.shift if $@
76
119
  end
120
+
121
+ def self.from_array code
122
+ unless code =~ /^\[[CSLQ]+\]$/
123
+ raise ArgumentError, "expected [CSLQ], got #{code}"
124
+ end
125
+ return new(code[1..-2].chars.map(&:to_sym))
126
+ end
127
+
128
+ def self.from_size code
129
+ m = code.match(/^\:(?<size>[^=]+)=?(?<value>.+)?$/)
130
+ if m.nil?
131
+ raise ArgumentError, "expected <number> or CSLQ, got #{code}"
132
+ end
133
+ if m[:size] =~ /^[CSLQ]+$/
134
+ s = m[:size].chars.map(&:to_sym)
135
+ if s.size == 1
136
+ return new(s[0]).tap { |b| b.load(m[:value].to_i) if m[:value] }
137
+ else
138
+ b = new(s)
139
+ b.load(m[:value].split(':').map(&:to_i)) if m[:value]
140
+ return b
141
+ end
142
+ end
143
+ if (n = m[:size].to_i)
144
+ return new(n).tap { |b| b.load(m[:value]) if m[:value] }
145
+ end
146
+ raise ArgumentError, "expected <number> or CSLQ, got #{code}"
147
+ end
148
+
149
+ def self.next_placeholder
150
+ @_placeholder_counter ||= 0
151
+ "__#{@_placeholder_counter += 1}__"
152
+ end
153
+
154
+ def self.from_struct code
155
+ default = {}
156
+ # code := '{' [name] [:type] [=value] [,...] '}'
157
+ env, keys, key = [], [], ''
158
+ seq = code.scan /\w+|\:[[:digit:]]+|\:[CSLQ:]+|=[^,\}]+|./
159
+ ret = while (token = seq.shift)
160
+ case token[0]
161
+ when '{'
162
+ keys.push(key.to_sym) unless key.empty?
163
+ env.push({})
164
+ key = ''
165
+ when '}'
166
+ env[-1][key.to_sym] = :L unless key.empty?
167
+ x = env.pop
168
+ break x if env.empty?
169
+ env[-1][keys.pop] = x
170
+ key = ''
171
+ when ':'
172
+ token << seq.shift if seq.first&.start_with?('=')
173
+ b = from_size(token)
174
+ key = next_placeholder if key.empty?
175
+ env[-1][key.to_sym] = b.struct
176
+ d = default
177
+ keys.each { |k| d[k] ||= {}; d = d[k] }
178
+ d[key.to_sym] = b.unpack
179
+ key = ''
180
+ when '='
181
+ e = token[1..-1]
182
+ e = Integer(e) rescue nil
183
+ type = Integer === e ? :L : (e.length + 1)
184
+ env[-1][key.to_sym] = type
185
+ d = default
186
+ keys.each { |k| d[k] ||= {}; d = d[k] }
187
+ if Integer === type
188
+ e = "\"#{e}\"".undump rescue e.undump
189
+ end
190
+ d[key.to_sym] = e
191
+ key = ''
192
+ when ','
193
+ next if key.empty?
194
+ env[-1][key.to_sym] = :L
195
+ key = ''
196
+ else
197
+ key << token
198
+ end
199
+ end
200
+ if ret.nil?
201
+ raise ArgumentError, 'expected }, got end-of-input'
202
+ end
203
+ new(ret).tap { |b| b.load(default) }
204
+ end
205
+
206
+ def self.from code
207
+ return from_array(code) if code.start_with?('[')
208
+ return from_size(code) if code.start_with?(':')
209
+ code = "{#{code}}" unless code.start_with?('{')
210
+ return from_struct(code)
211
+ end
77
212
  end
78
213
 
79
214
  # Undll32.run 'user32', 'MessageBox', 0, 'hello', 'world', 0
215
+ # Undll32.run 'user32', 'GetCursorPos', Buffer.new({:x => :L, :y => :L})
216
+ # Undll32.run 'user32', 'GetCursorPos', Buffer.from('x,y')
80
217
  def self.run(dll, func, *args)
81
218
  types = args.map { |e| Integer === e ? 'L' : 'p' }
82
219
  input = args.map { |e| Buffer === e ? e.buffer : e }
83
220
  Win32API.new(dll, func, types, 'i').call(*input)
84
221
  end
85
222
 
86
- def self.parse xs
87
- case x = xs.shift
88
- when ':' then Buffer.new xs.shift.to_i
89
- when '[' then Buffer.new xs.shift.chars.map(&:to_sym)
90
- when '{'
91
- x = Hash[xs.each_slice(4).map { |k, _, v, _| [k.to_sym, v.to_sym] }]
92
- Buffer.new x
93
- else
94
- raise ArgumentError, "expected : [ {, got #{x}"
95
- end
96
- end
97
-
98
223
  def self.exe(argv=ARGV)
99
224
  return help if ARGV.include? '-h' or ARGV.include? '--help'
100
225
  dllfunc, *args = argv
101
226
  return help if dllfunc.nil?
102
227
  dll, func = dllfunc.split(',')
103
228
  return help if func.nil?
104
- args.map! { |e|
229
+ args.map! do |e|
105
230
  e = e.dup
106
231
  if e.start_with?('+')
107
232
  e.slice!(0)
108
233
  next e if e.start_with?('+')
109
- parse e.scan(/\w+|./)
234
+ Buffer.from(e)
110
235
  else
111
236
  n = Integer(e) rescue nil
112
237
  next n if n
113
238
  e
114
239
  end
115
- }
240
+ end
116
241
  ret = run(dll, func, *args)
117
242
  args.each { |e| pp e.unpack if Buffer === e }
118
243
  ret
@@ -126,10 +251,10 @@ module Undll32
126
251
  EXAMPLE
127
252
  undll32 user32,MessageBox 0 hello world 0
128
253
  undll32 user32,GetCursorPos +[LL]
129
- undll32 user32,GetCursorPos +{x:L,y:L}
254
+ undll32 user32,GetCursorPos +x,y
130
255
  undll32 user32,GetCursorPos +:8 # will be converted to string
131
256
 
132
- EXPLAIN
257
+ ARGUMENTS
133
258
  0 => (Integer) 0
134
259
  str => 'str'
135
260
  +0 => '0'
@@ -138,6 +263,9 @@ module Undll32
138
263
  +{x:L,y:L} => Buffer.new({:x => :L, :y => :L})
139
264
  +:256 => Buffer.new(256)
140
265
 
266
+ VERSION
267
+ #{VERSION}
268
+
141
269
  USAGE
142
270
  end
143
271
  end
@@ -1,3 +1,3 @@
1
1
  module Undll32
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: undll32
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - hyrious
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-12-01 00:00:00.000000000 Z
11
+ date: 2018-12-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler