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.
- checksums.yaml +4 -4
- data/lib/undll32.rb +149 -21
- data/lib/undll32/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc86272423576ea01bf2666535b63302cfabd49e12b672c168d49b84fadaa814
|
4
|
+
data.tar.gz: 1f92550e71c6429d1fdd4ce75fffd759888fddd1a9f127c93424605fd38de2ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a9bc8bbbd5a4e597ce2847892552b4dc3a7b149aac05658bf0d68c9270e4d151a6af4f6557a314682ae90c5c9d11fa07b013dc067b0b8bb9b5ddc03d9192c02
|
7
|
+
data.tar.gz: '0692dddf565e76242e9c4bcb5e18d6f4bac407fe9bfb33ac1565e8fe9dfb87de6fb707cd7621f5695feae8eb24998d9e7205ae77235b41cc75c265feb8b91d0e'
|
data/lib/undll32.rb
CHANGED
@@ -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
|
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
|
-
|
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 #{
|
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 #{
|
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!
|
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
|
-
|
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 +
|
254
|
+
undll32 user32,GetCursorPos +x,y
|
130
255
|
undll32 user32,GetCursorPos +:8 # will be converted to string
|
131
256
|
|
132
|
-
|
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
|
data/lib/undll32/version.rb
CHANGED
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.
|
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-
|
11
|
+
date: 2018-12-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|