one_gadget 1.9.0 → 1.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +299 -100
- data/lib/one_gadget/cli.rb +37 -18
- data/lib/one_gadget/emulators/aarch64.rb +2 -2
- data/lib/one_gadget/emulators/instruction.rb +1 -1
- data/lib/one_gadget/emulators/lambda.rb +3 -3
- data/lib/one_gadget/emulators/processor.rb +1 -1
- data/lib/one_gadget/emulators/x86.rb +1 -1
- data/lib/one_gadget/fetcher.rb +1 -1
- data/lib/one_gadget/fetchers/base.rb +7 -6
- data/lib/one_gadget/gadget.rb +22 -6
- data/lib/one_gadget/helper.rb +2 -2
- data/lib/one_gadget/update.rb +2 -2
- data/lib/one_gadget/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 115a1008facd6ff265526eb0be8392bca7cd4eab161b549ead9ab6f34a0050b2
|
4
|
+
data.tar.gz: 56f21220b1a65fe15ac51b682f95ba52fb108084912570f8208f1ef40eafda52
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5c5714e03eda9a982d9d1510ad5f0465e3f11e55155507910df4302e039d92a3a5c35cf5be45c0a8f30709b491fcb301d00e8e9d57638610c1e0042282e87a02
|
7
|
+
data.tar.gz: 21ac5b3a5cc316c92e90741bcec4e5efbdc8d97183c3810eba356216c636a9d4d59c3a62784e2395731d72a3c716fa8c10eec8697f04437e3da2a1c41a292c0c
|
data/README.md
CHANGED
@@ -64,18 +64,20 @@ $ one_gadget
|
|
64
64
|
|
65
65
|
```bash
|
66
66
|
$ one_gadget /lib/x86_64-linux-gnu/libc.so.6
|
67
|
-
#
|
67
|
+
# 0xe3afe execve("/bin/sh", r15, r12)
|
68
68
|
# constraints:
|
69
|
-
#
|
70
|
-
#
|
69
|
+
# [r15] == NULL || r15 == NULL || r15 is a valid argv
|
70
|
+
# [r12] == NULL || r12 == NULL || r12 is a valid envp
|
71
71
|
#
|
72
|
-
#
|
72
|
+
# 0xe3b01 execve("/bin/sh", r15, rdx)
|
73
73
|
# constraints:
|
74
|
-
# [
|
74
|
+
# [r15] == NULL || r15 == NULL || r15 is a valid argv
|
75
|
+
# [rdx] == NULL || rdx == NULL || rdx is a valid envp
|
75
76
|
#
|
76
|
-
#
|
77
|
+
# 0xe3b04 execve("/bin/sh", rsi, rdx)
|
77
78
|
# constraints:
|
78
|
-
# [
|
79
|
+
# [rsi] == NULL || rsi == NULL || rsi is a valid argv
|
80
|
+
# [rdx] == NULL || rdx == NULL || rdx is a valid envp
|
79
81
|
|
80
82
|
```
|
81
83
|
![x86_64](https://github.com/david942j/one_gadget/blob/master/examples/x86_64.png?raw=true)
|
@@ -83,21 +85,17 @@ $ one_gadget /lib/x86_64-linux-gnu/libc.so.6
|
|
83
85
|
#### Given BuildID
|
84
86
|
```bash
|
85
87
|
$ one_gadget -b aad7dbe330f23ea00ca63daf793b766b51aceb5d
|
86
|
-
# 0x45526 execve("/bin/sh", rsp+0x30, environ)
|
87
|
-
# constraints:
|
88
|
-
# rax == NULL
|
89
|
-
#
|
90
88
|
# 0x4557a execve("/bin/sh", rsp+0x30, environ)
|
91
89
|
# constraints:
|
92
|
-
# [rsp+0x30] == NULL
|
90
|
+
# [rsp+0x30] == NULL || {[rsp+0x30], [rsp+0x38], [rsp+0x40], [rsp+0x48], ...} is a valid argv
|
93
91
|
#
|
94
92
|
# 0xf1651 execve("/bin/sh", rsp+0x40, environ)
|
95
93
|
# constraints:
|
96
|
-
# [rsp+0x40] == NULL
|
94
|
+
# [rsp+0x40] == NULL || {[rsp+0x40], [rsp+0x48], [rsp+0x50], [rsp+0x58], ...} is a valid argv
|
97
95
|
#
|
98
96
|
# 0xf24cb execve("/bin/sh", rsp+0x60, environ)
|
99
97
|
# constraints:
|
100
|
-
# [rsp+0x60] == NULL
|
98
|
+
# [rsp+0x60] == NULL || {[rsp+0x60], [rsp+0x68], [rsp+0x70], [rsp+0x78], ...} is a valid argv
|
101
99
|
|
102
100
|
```
|
103
101
|
![build id](https://github.com/david942j/one_gadget/blob/master/examples/from_build_id.png?raw=true)
|
@@ -120,33 +118,37 @@ Reorder gadgets according to the distance of given functions.
|
|
120
118
|
|
121
119
|
```bash
|
122
120
|
$ one_gadget /lib/x86_64-linux-gnu/libc.so.6 --near exit,mkdir
|
123
|
-
# [OneGadget] Gadgets near exit(
|
124
|
-
#
|
121
|
+
# [OneGadget] Gadgets near exit(0x46a40):
|
122
|
+
# 0xe3afe execve("/bin/sh", r15, r12)
|
125
123
|
# constraints:
|
126
|
-
#
|
127
|
-
#
|
124
|
+
# [r15] == NULL || r15 == NULL || r15 is a valid argv
|
125
|
+
# [r12] == NULL || r12 == NULL || r12 is a valid envp
|
128
126
|
#
|
129
|
-
#
|
127
|
+
# 0xe3b01 execve("/bin/sh", r15, rdx)
|
130
128
|
# constraints:
|
131
|
-
# [
|
129
|
+
# [r15] == NULL || r15 == NULL || r15 is a valid argv
|
130
|
+
# [rdx] == NULL || rdx == NULL || rdx is a valid envp
|
132
131
|
#
|
133
|
-
#
|
132
|
+
# 0xe3b04 execve("/bin/sh", rsi, rdx)
|
134
133
|
# constraints:
|
135
|
-
# [
|
134
|
+
# [rsi] == NULL || rsi == NULL || rsi is a valid argv
|
135
|
+
# [rdx] == NULL || rdx == NULL || rdx is a valid envp
|
136
136
|
#
|
137
|
-
# [OneGadget] Gadgets near mkdir(
|
138
|
-
#
|
137
|
+
# [OneGadget] Gadgets near mkdir(0x10de70):
|
138
|
+
# 0xe3b04 execve("/bin/sh", rsi, rdx)
|
139
139
|
# constraints:
|
140
|
-
# [
|
140
|
+
# [rsi] == NULL || rsi == NULL || rsi is a valid argv
|
141
|
+
# [rdx] == NULL || rdx == NULL || rdx is a valid envp
|
141
142
|
#
|
142
|
-
#
|
143
|
+
# 0xe3b01 execve("/bin/sh", r15, rdx)
|
143
144
|
# constraints:
|
144
|
-
# [
|
145
|
+
# [r15] == NULL || r15 == NULL || r15 is a valid argv
|
146
|
+
# [rdx] == NULL || rdx == NULL || rdx is a valid envp
|
145
147
|
#
|
146
|
-
#
|
148
|
+
# 0xe3afe execve("/bin/sh", r15, r12)
|
147
149
|
# constraints:
|
148
|
-
#
|
149
|
-
#
|
150
|
+
# [r15] == NULL || r15 == NULL || r15 is a valid argv
|
151
|
+
# [r12] == NULL || r12 == NULL || r12 is a valid envp
|
150
152
|
#
|
151
153
|
|
152
154
|
```
|
@@ -155,11 +157,11 @@ $ one_gadget /lib/x86_64-linux-gnu/libc.so.6 --near exit,mkdir
|
|
155
157
|
Regular expression is acceptable.
|
156
158
|
```bash
|
157
159
|
$ one_gadget /lib/x86_64-linux-gnu/libc.so.6 --near 'write.*' --raw
|
158
|
-
# [OneGadget] Gadgets near writev(
|
159
|
-
#
|
160
|
+
# [OneGadget] Gadgets near writev(0x114690):
|
161
|
+
# 932612 932609 932606
|
160
162
|
#
|
161
|
-
# [OneGadget] Gadgets near write(
|
162
|
-
#
|
163
|
+
# [OneGadget] Gadgets near write(0x10e280):
|
164
|
+
# 932612 932609 932606
|
163
165
|
#
|
164
166
|
|
165
167
|
```
|
@@ -167,23 +169,23 @@ $ one_gadget /lib/x86_64-linux-gnu/libc.so.6 --near 'write.*' --raw
|
|
167
169
|
Pass an ELF file as the argument, OneGadget will take all GOT functions for processing.
|
168
170
|
```bash
|
169
171
|
$ one_gadget /lib/x86_64-linux-gnu/libc.so.6 --near spec/data/test_near_file.elf --raw
|
170
|
-
# [OneGadget] Gadgets near exit(
|
171
|
-
#
|
172
|
+
# [OneGadget] Gadgets near exit(0x46a40):
|
173
|
+
# 932606 932609 932612
|
172
174
|
#
|
173
|
-
# [OneGadget] Gadgets near puts(
|
174
|
-
#
|
175
|
+
# [OneGadget] Gadgets near puts(0x84420):
|
176
|
+
# 932606 932609 932612
|
175
177
|
#
|
176
|
-
# [OneGadget] Gadgets near printf(
|
177
|
-
#
|
178
|
+
# [OneGadget] Gadgets near printf(0x61c90):
|
179
|
+
# 932606 932609 932612
|
178
180
|
#
|
179
|
-
# [OneGadget] Gadgets near strlen(
|
180
|
-
#
|
181
|
+
# [OneGadget] Gadgets near strlen(0x9f630):
|
182
|
+
# 932606 932609 932612
|
181
183
|
#
|
182
|
-
# [OneGadget] Gadgets near __cxa_finalize(
|
183
|
-
#
|
184
|
+
# [OneGadget] Gadgets near __cxa_finalize(0x46f10):
|
185
|
+
# 932606 932609 932612
|
184
186
|
#
|
185
|
-
# [OneGadget] Gadgets near __libc_start_main(
|
186
|
-
#
|
187
|
+
# [OneGadget] Gadgets near __libc_start_main(0x23f90):
|
188
|
+
# 932606 932609 932612
|
187
189
|
#
|
188
190
|
|
189
191
|
```
|
@@ -197,89 +199,286 @@ Use option `--level 1` to show all gadgets found instead of only those with high
|
|
197
199
|
|
198
200
|
```bash
|
199
201
|
$ one_gadget /lib/x86_64-linux-gnu/libc.so.6 --level 1
|
200
|
-
#
|
202
|
+
# 0x51dfb posix_spawn(rsp+0xc, "/bin/sh", 0, rbp, rsp+0x50, environ)
|
201
203
|
# constraints:
|
204
|
+
# address rsp+0x60 is writable
|
202
205
|
# rsp & 0xf == 0
|
203
|
-
#
|
206
|
+
# {"sh", "-c", rbx, NULL} is a valid argv
|
207
|
+
# rbp == NULL || (u16)[rbp] == NULL
|
204
208
|
#
|
205
|
-
#
|
209
|
+
# 0x51e02 posix_spawn(rsp+0xc, "/bin/sh", 0, rbp, rsp+0x50, environ)
|
206
210
|
# constraints:
|
207
|
-
#
|
211
|
+
# address rsp+0x60 is writable
|
212
|
+
# rsp & 0xf == 0
|
213
|
+
# rax == NULL || {"sh", rax, rbx, NULL} is a valid argv
|
214
|
+
# rbp == NULL || (u16)[rbp] == NULL
|
208
215
|
#
|
209
|
-
#
|
216
|
+
# 0x51e09 posix_spawn(rsp+0xc, "/bin/sh", 0, rbp, rsp+0x50, environ)
|
210
217
|
# constraints:
|
211
|
-
#
|
212
|
-
#
|
218
|
+
# address rsp+0x60 is writable
|
219
|
+
# rsp & 0xf == 0
|
220
|
+
# rcx == NULL || {rcx, rax, rbx, NULL} is a valid argv
|
221
|
+
# rbp == NULL || (u16)[rbp] == NULL
|
213
222
|
#
|
214
|
-
#
|
223
|
+
# 0x51e10 posix_spawn(rsp+0xc, "/bin/sh", rdx, rbp, rsp+0x50, environ)
|
215
224
|
# constraints:
|
216
|
-
#
|
217
|
-
#
|
225
|
+
# address rsp+0x60 is writable
|
226
|
+
# rsp & 0xf == 0
|
227
|
+
# rcx == NULL || {rcx, (u64)xmm1, rbx, NULL} is a valid argv
|
228
|
+
# rdx == NULL || (s32)[rdx+0x4] <= 0
|
229
|
+
# rbp == NULL || (u16)[rbp] == NULL
|
218
230
|
#
|
219
|
-
#
|
231
|
+
# 0x51e15 posix_spawn(rsp+0xc, "/bin/sh", rdx, rbp, rsp+0x50, environ)
|
220
232
|
# constraints:
|
221
|
-
#
|
222
|
-
#
|
233
|
+
# address rsp+0x60 is writable
|
234
|
+
# rsp & 0xf == 0
|
235
|
+
# (u64)xmm0 == NULL || {(u64)xmm0, (u64)xmm1, rbx, NULL} is a valid argv
|
236
|
+
# rdx == NULL || (s32)[rdx+0x4] <= 0
|
237
|
+
# rbp == NULL || (u16)[rbp] == NULL
|
223
238
|
#
|
224
|
-
#
|
239
|
+
# 0x51e25 posix_spawn(rdi, "/bin/sh", rdx, rbp, rsp+0x50, [rax])
|
225
240
|
# constraints:
|
226
|
-
#
|
227
|
-
#
|
241
|
+
# address rsp+0x60 is writable
|
242
|
+
# rsp & 0xf == 0
|
243
|
+
# (u64)xmm0 == NULL || {(u64)xmm0, (u64)(xmm0 >> 64), rbx, NULL} is a valid argv
|
244
|
+
# [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp
|
245
|
+
# rdi == NULL || writable: rdi
|
246
|
+
# rdx == NULL || (s32)[rdx+0x4] <= 0
|
247
|
+
# rbp == NULL || (u16)[rbp] == NULL
|
228
248
|
#
|
229
|
-
#
|
249
|
+
# 0x51e2a posix_spawn(rdi, "/bin/sh", rdx, rbp, r8, [rax])
|
230
250
|
# constraints:
|
231
|
-
#
|
251
|
+
# address rsp+0x60 is writable
|
252
|
+
# rsp & 0xf == 0
|
253
|
+
# [r8] == NULL || r8 is a valid argv
|
254
|
+
# [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp
|
255
|
+
# rdi == NULL || writable: rdi
|
256
|
+
# rdx == NULL || (s32)[rdx+0x4] <= 0
|
257
|
+
# rbp == NULL || (u16)[rbp] == NULL
|
232
258
|
#
|
233
|
-
#
|
259
|
+
# 0x51e2d posix_spawn(rdi, "/bin/sh", rdx, rcx, r8, [rax])
|
234
260
|
# constraints:
|
235
|
-
#
|
236
|
-
#
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
$ one_gadget /lib32/libc.so.6
|
245
|
-
# 0x3cbea execve("/bin/sh", esp+0x34, environ)
|
261
|
+
# address rsp+0x60 is writable
|
262
|
+
# rsp & 0xf == 0
|
263
|
+
# [r8] == NULL || r8 is a valid argv
|
264
|
+
# [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp
|
265
|
+
# rdi == NULL || writable: rdi
|
266
|
+
# rdx == NULL || (s32)[rdx+0x4] <= 0
|
267
|
+
# rcx == NULL || (u16)[rcx] == NULL
|
268
|
+
#
|
269
|
+
# 0x51e32 posix_spawn(rdi, "/bin/sh", rdx, rcx, r8, [rax])
|
246
270
|
# constraints:
|
247
|
-
#
|
248
|
-
#
|
271
|
+
# address rsp+0x68 is writable
|
272
|
+
# rsp & 0xf == 0
|
273
|
+
# [r8] == NULL || r8 is a valid argv
|
274
|
+
# [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp
|
275
|
+
# rdi == NULL || writable: rdi
|
276
|
+
# rdx == NULL || (s32)[rdx+0x4] <= 0
|
277
|
+
# rcx == NULL || (u16)[rcx] == NULL
|
249
278
|
#
|
250
|
-
#
|
279
|
+
# 0x84135 posix_spawn(rbx+0xe0, "/bin/sh", r12, 0, rsp+0x60, environ)
|
251
280
|
# constraints:
|
252
|
-
#
|
253
|
-
#
|
281
|
+
# address rsp+0x70 is writable
|
282
|
+
# rsp & 0xf == 0
|
283
|
+
# {"sh", "-c", rbp, NULL} is a valid argv
|
284
|
+
# rbx+0xe0 == NULL || writable: rbx+0xe0
|
285
|
+
# r12 == NULL || (s32)[r12+0x4] <= 0
|
254
286
|
#
|
255
|
-
#
|
287
|
+
# 0x8413c posix_spawn(rbx+0xe0, "/bin/sh", r12, 0, rsp+0x60, environ)
|
256
288
|
# constraints:
|
257
|
-
#
|
258
|
-
#
|
289
|
+
# address rsp+0x70 is writable
|
290
|
+
# rsp & 0xf == 0
|
291
|
+
# rax == NULL || {"sh", rax, rbp, NULL} is a valid argv
|
292
|
+
# rbx+0xe0 == NULL || writable: rbx+0xe0
|
293
|
+
# r12 == NULL || (s32)[r12+0x4] <= 0
|
259
294
|
#
|
260
|
-
#
|
295
|
+
# 0x84143 posix_spawn(rbx+0xe0, "/bin/sh", r12, 0, rsp+0x60, environ)
|
261
296
|
# constraints:
|
262
|
-
#
|
263
|
-
#
|
297
|
+
# address rsp+0x70 is writable
|
298
|
+
# rsp & 0xf == 0
|
299
|
+
# rcx == NULL || {rcx, rax, rbp, NULL} is a valid argv
|
300
|
+
# rbx+0xe0 == NULL || writable: rbx+0xe0
|
301
|
+
# r12 == NULL || (s32)[r12+0x4] <= 0
|
264
302
|
#
|
265
|
-
#
|
303
|
+
# 0x84146 posix_spawn(rbx+0xe0, "/bin/sh", rdx, 0, rsp+0x60, environ)
|
266
304
|
# constraints:
|
267
|
-
#
|
268
|
-
#
|
305
|
+
# address rsp+0x70 is writable
|
306
|
+
# rsp & 0xf == 0
|
307
|
+
# rcx == NULL || {rcx, rax, rbp, NULL} is a valid argv
|
308
|
+
# rbx+0xe0 == NULL || writable: rbx+0xe0
|
309
|
+
# rdx == NULL || (s32)[rdx+0x4] <= 0
|
269
310
|
#
|
270
|
-
#
|
311
|
+
# 0x8414b posix_spawn(rbx+0xe0, "/bin/sh", rdx, 0, rsp+0x60, environ)
|
271
312
|
# constraints:
|
272
|
-
#
|
273
|
-
#
|
313
|
+
# address rsp+0x78 is writable
|
314
|
+
# rsp & 0xf == 0
|
315
|
+
# rcx == NULL || {rcx, rax, [rsp+0x70], NULL} is a valid argv
|
316
|
+
# rbx+0xe0 == NULL || writable: rbx+0xe0
|
317
|
+
# rdx == NULL || (s32)[rdx+0x4] <= 0
|
318
|
+
#
|
319
|
+
# 0x84150 posix_spawn(rbx+0xe0, "/bin/sh", rdx, 0, rsp+0x60, environ)
|
320
|
+
# constraints:
|
321
|
+
# address rsp+0x78 is writable
|
322
|
+
# rsp & 0xf == 0
|
323
|
+
# rcx == NULL || {rcx, (u64)xmm1, [rsp+0x70], NULL} is a valid argv
|
324
|
+
# rbx+0xe0 == NULL || writable: rbx+0xe0
|
325
|
+
# rdx == NULL || (s32)[rdx+0x4] <= 0
|
326
|
+
#
|
327
|
+
# 0x8415c posix_spawn(rbx+0xe0, "/bin/sh", rdx, 0, rsp+0x60, [rax])
|
328
|
+
# constraints:
|
329
|
+
# address rsp+0x78 is writable
|
330
|
+
# rsp & 0xf == 0
|
331
|
+
# (u64)xmm0 == NULL || {(u64)xmm0, (u64)xmm1, [rsp+0x70], NULL} is a valid argv
|
332
|
+
# [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp
|
333
|
+
# rbx+0xe0 == NULL || writable: rbx+0xe0
|
334
|
+
# rdx == NULL || (s32)[rdx+0x4] <= 0
|
335
|
+
#
|
336
|
+
# 0x84162 posix_spawn(rbx+0xe0, "/bin/sh", rdx, rcx, rsp+0x60, [rax])
|
337
|
+
# constraints:
|
338
|
+
# address rsp+0x78 is writable
|
339
|
+
# rsp & 0xf == 0
|
340
|
+
# (u64)xmm0 == NULL || {(u64)xmm0, (u64)(xmm0 >> 64), [rsp+0x70], NULL} is a valid argv
|
341
|
+
# [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp
|
342
|
+
# rbx+0xe0 == NULL || writable: rbx+0xe0
|
343
|
+
# rdx == NULL || (s32)[rdx+0x4] <= 0
|
344
|
+
# rcx == NULL || (u16)[rcx] == NULL
|
345
|
+
#
|
346
|
+
# 0x84169 posix_spawn(rdi, "/bin/sh", rdx, rcx, rsp+0x60, [rax])
|
347
|
+
# constraints:
|
348
|
+
# address rsp+0x78 is writable
|
349
|
+
# rsp & 0xf == 0
|
350
|
+
# (u64)xmm0 == NULL || {(u64)xmm0, (u64)(xmm0 >> 64), [rsp+0x70], NULL} is a valid argv
|
351
|
+
# [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp
|
352
|
+
# rdi == NULL || writable: rdi
|
353
|
+
# rdx == NULL || (s32)[rdx+0x4] <= 0
|
354
|
+
# rcx == NULL || (u16)[rcx] == NULL
|
355
|
+
#
|
356
|
+
# 0x84170 posix_spawn(rdi, "/bin/sh", rdx, rcx, r8, [rax])
|
357
|
+
# constraints:
|
358
|
+
# address rsp+0x78 is writable
|
359
|
+
# rsp & 0xf == 0
|
360
|
+
# [r8] == NULL || r8 is a valid argv
|
361
|
+
# [[rax]] == NULL || [rax] == NULL || [rax] is a valid envp
|
362
|
+
# rdi == NULL || writable: rdi
|
363
|
+
# rdx == NULL || (s32)[rdx+0x4] <= 0
|
364
|
+
# rcx == NULL || (u16)[rcx] == NULL
|
365
|
+
#
|
366
|
+
# 0xe3afe execve("/bin/sh", r15, r12)
|
367
|
+
# constraints:
|
368
|
+
# [r15] == NULL || r15 == NULL || r15 is a valid argv
|
369
|
+
# [r12] == NULL || r12 == NULL || r12 is a valid envp
|
370
|
+
#
|
371
|
+
# 0xe3b01 execve("/bin/sh", r15, rdx)
|
372
|
+
# constraints:
|
373
|
+
# [r15] == NULL || r15 == NULL || r15 is a valid argv
|
374
|
+
# [rdx] == NULL || rdx == NULL || rdx is a valid envp
|
375
|
+
#
|
376
|
+
# 0xe3b04 execve("/bin/sh", rsi, rdx)
|
377
|
+
# constraints:
|
378
|
+
# [rsi] == NULL || rsi == NULL || rsi is a valid argv
|
379
|
+
# [rdx] == NULL || rdx == NULL || rdx is a valid envp
|
380
|
+
#
|
381
|
+
# 0xe3cf3 execve("/bin/sh", r10, r12)
|
382
|
+
# constraints:
|
383
|
+
# address rbp-0x78 is writable
|
384
|
+
# [r10] == NULL || r10 == NULL || r10 is a valid argv
|
385
|
+
# [r12] == NULL || r12 == NULL || r12 is a valid envp
|
386
|
+
#
|
387
|
+
# 0xe3cf6 execve("/bin/sh", r10, rdx)
|
388
|
+
# constraints:
|
389
|
+
# address rbp-0x78 is writable
|
390
|
+
# [r10] == NULL || r10 == NULL || r10 is a valid argv
|
391
|
+
# [rdx] == NULL || rdx == NULL || rdx is a valid envp
|
274
392
|
#
|
275
|
-
#
|
393
|
+
# 0xe3d62 execve("/bin/sh", rbp-0x50, r12)
|
276
394
|
# constraints:
|
395
|
+
# address rbp-0x48 is writable
|
396
|
+
# r13 == NULL || {"/bin/sh", r13, NULL} is a valid argv
|
397
|
+
# [r12] == NULL || r12 == NULL || r12 is a valid envp
|
398
|
+
#
|
399
|
+
# 0xe3d69 execve("/bin/sh", rbp-0x50, r12)
|
400
|
+
# constraints:
|
401
|
+
# address rbp-0x48 is writable
|
402
|
+
# rax == NULL || {rax, r13, NULL} is a valid argv
|
403
|
+
# [r12] == NULL || r12 == NULL || r12 is a valid envp
|
404
|
+
#
|
405
|
+
# 0xe3d70 execve("/bin/sh", rbp-0x50, r12)
|
406
|
+
# constraints:
|
407
|
+
# address rbp-0x50 is writable
|
408
|
+
# rax == NULL || {rax, [rbp-0x48], NULL} is a valid argv
|
409
|
+
# [r12] == NULL || r12 == NULL || r12 is a valid envp
|
410
|
+
#
|
411
|
+
# 0xe3da7 execve("/bin/sh", rbp-0x50, r12)
|
412
|
+
# constraints:
|
413
|
+
# address rbp-0x50 is writable
|
414
|
+
# [rbp-0x68] == NULL || {"/bin/sh", [rbp-0x68], NULL} is a valid argv
|
415
|
+
# [r12] == NULL || r12 == NULL || r12 is a valid envp
|
416
|
+
#
|
417
|
+
# 0xe3db1 execve("/bin/sh", rbp-0x50, r12)
|
418
|
+
# constraints:
|
419
|
+
# address rbp-0x50 is writable
|
420
|
+
# rax == NULL || {rax, [rbp-0x68], NULL} is a valid argv
|
421
|
+
# [r12] == NULL || r12 == NULL || r12 is a valid envp
|
422
|
+
#
|
423
|
+
# 0xe3db5 execve("/bin/sh", r10, r12)
|
424
|
+
# constraints:
|
425
|
+
# addresses r10+0x10, rbp-0x50 are writable
|
426
|
+
# [r10] == NULL || r10 == NULL || r10 is a valid argv
|
427
|
+
# [r12] == NULL || r12 == NULL || r12 is a valid envp
|
428
|
+
#
|
429
|
+
# 0xe3dbd execve("/bin/sh", r10, r12)
|
430
|
+
# constraints:
|
431
|
+
# addresses r10+0x10, rbp-0x48 are writable
|
432
|
+
# [r10] == NULL || r10 == NULL || r10 is a valid argv
|
433
|
+
# [r12] == NULL || r12 == NULL || r12 is a valid envp
|
434
|
+
#
|
435
|
+
# 0x1077ca posix_spawn(rsp+0x64, "/bin/sh", [rsp+0x38], 0, rsp+0x70, [rsp+0xf0])
|
436
|
+
# constraints:
|
437
|
+
# [rsp+0x70] == NULL || {[rsp+0x70], [rsp+0x78], [rsp+0x80], [rsp+0x88], ...} is a valid argv
|
438
|
+
# [[rsp+0xf0]] == NULL || [rsp+0xf0] == NULL || [rsp+0xf0] is a valid envp
|
439
|
+
# [rsp+0x38] == NULL || (s32)[[rsp+0x38]+0x4] <= 0
|
440
|
+
#
|
441
|
+
# 0x1077d2 posix_spawn(rsp+0x64, "/bin/sh", [rsp+0x38], 0, rsp+0x70, r9)
|
442
|
+
# constraints:
|
443
|
+
# [rsp+0x70] == NULL || {[rsp+0x70], [rsp+0x78], [rsp+0x80], [rsp+0x88], ...} is a valid argv
|
444
|
+
# [r9] == NULL || r9 == NULL || r9 is a valid envp
|
445
|
+
# [rsp+0x38] == NULL || (s32)[[rsp+0x38]+0x4] <= 0
|
446
|
+
#
|
447
|
+
# 0x1077d7 posix_spawn(rsp+0x64, "/bin/sh", rdx, 0, rsp+0x70, r9)
|
448
|
+
# constraints:
|
449
|
+
# [rsp+0x70] == NULL || {[rsp+0x70], [rsp+0x78], [rsp+0x80], [rsp+0x88], ...} is a valid argv
|
450
|
+
# [r9] == NULL || r9 == NULL || r9 is a valid envp
|
451
|
+
# rdx == NULL || (s32)[rdx+0x4] <= 0
|
452
|
+
#
|
453
|
+
# 0x1077e1 posix_spawn(rdi, "/bin/sh", rdx, 0, r8, r9)
|
454
|
+
# constraints:
|
455
|
+
# [r8] == NULL || r8 is a valid argv
|
456
|
+
# [r9] == NULL || r9 == NULL || r9 is a valid envp
|
457
|
+
# rdi == NULL || writable: rdi
|
458
|
+
# rdx == NULL || (s32)[rdx+0x4] <= 0
|
459
|
+
|
460
|
+
```
|
461
|
+
|
462
|
+
#### Other Architectures
|
463
|
+
|
464
|
+
##### i386
|
465
|
+
```bash
|
466
|
+
$ one_gadget /lib32/libc.so.6
|
467
|
+
# 0xc890b execve("/bin/sh", [ebp-0x2c], esi)
|
468
|
+
# constraints:
|
469
|
+
# address ebp-0x20 is writable
|
277
470
|
# ebx is the GOT address of libc
|
471
|
+
# [[ebp-0x2c]] == NULL || [ebp-0x2c] == NULL || [ebp-0x2c] is a valid argv
|
472
|
+
# [esi] == NULL || esi == NULL || esi is a valid envp
|
473
|
+
#
|
474
|
+
# 0x1421b3 execl("/bin/sh", eax)
|
475
|
+
# constraints:
|
476
|
+
# ebp is the GOT address of libc
|
278
477
|
# eax == NULL
|
279
478
|
#
|
280
|
-
#
|
479
|
+
# 0x1421b4 execl("/bin/sh", [esp])
|
281
480
|
# constraints:
|
282
|
-
#
|
481
|
+
# ebp is the GOT address of libc
|
283
482
|
# [esp] == NULL
|
284
483
|
|
285
484
|
```
|
@@ -324,15 +523,15 @@ $ one_gadget ./spec/data/libc-2.19.so -s 'echo "offset ->"'
|
|
324
523
|
```ruby
|
325
524
|
require 'one_gadget'
|
326
525
|
OneGadget.gadgets(file: '/lib/x86_64-linux-gnu/libc.so.6')
|
327
|
-
#=> [
|
526
|
+
#=> [932606, 932609, 932612]
|
328
527
|
|
329
528
|
# or in shorter way
|
330
529
|
one_gadget('/lib/x86_64-linux-gnu/libc.so.6', level: 1)
|
331
|
-
#=> [
|
530
|
+
#=> [335355, 335362, 335369, 335376, 335381, 335397, 335402, 335405, 335410, 540981, 540988, 540995, 540998, 541003, 541008, 541020, 541026, 541033, 541040, 932606, 932609, 932612, 933107, 933110, 933218, 933225, 933232, 933287, 933297, 933301, 933309, 1079242, 1079250, 1079255, 1079265]
|
332
531
|
|
333
532
|
# from build id
|
334
533
|
one_gadget('b417c0ba7cc5cf06d1d1bed6652cedb9253c60d0')
|
335
|
-
#=> [324293, 324386, 1090444]
|
534
|
+
#=> [324286, 324293, 324386, 1090444]
|
336
535
|
|
337
536
|
```
|
338
537
|
|
@@ -343,7 +542,7 @@ def one_gadget(filename):
|
|
343
542
|
return [int(i) for i in subprocess.check_output(['one_gadget', '--raw', filename]).decode().split(' ')]
|
344
543
|
|
345
544
|
one_gadget('/lib/x86_64-linux-gnu/libc.so.6')
|
346
|
-
#=> [
|
545
|
+
#=> [932606, 932609, 932612]
|
347
546
|
|
348
547
|
```
|
349
548
|
|
data/lib/one_gadget/cli.rb
CHANGED
@@ -12,7 +12,7 @@ module OneGadget
|
|
12
12
|
# Help message.
|
13
13
|
USAGE = 'Usage: one_gadget <FILE|-b BuildID> [options]'
|
14
14
|
# Default options.
|
15
|
-
DEFAULT_OPTIONS = {
|
15
|
+
DEFAULT_OPTIONS = { format: :pretty, force_file: false, level: 0, base: 0 }.freeze
|
16
16
|
|
17
17
|
module_function
|
18
18
|
|
@@ -49,9 +49,9 @@ module OneGadget
|
|
49
49
|
return show(parser.help) && false unless build_id || libc_file
|
50
50
|
|
51
51
|
gadgets = if build_id
|
52
|
-
OneGadget.gadgets(build_id
|
52
|
+
OneGadget.gadgets(build_id:, details: true, level:)
|
53
53
|
else # libc_file
|
54
|
-
OneGadget.gadgets(file: libc_file, details: true, force_file: @options[:force_file], level:
|
54
|
+
OneGadget.gadgets(file: libc_file, details: true, force_file: @options[:force_file], level:)
|
55
55
|
end
|
56
56
|
gadgets.each { |g| g.base = @options[:base] }
|
57
57
|
handle_gadgets(gadgets, libc_file)
|
@@ -66,7 +66,7 @@ module OneGadget
|
|
66
66
|
return handle_script(gadgets, @options[:script]) if @options[:script]
|
67
67
|
return handle_near(libc_file, gadgets, @options[:near]) if @options[:near]
|
68
68
|
|
69
|
-
display_gadgets(gadgets, @options[:
|
69
|
+
display_gadgets(gadgets, @options[:format])
|
70
70
|
end
|
71
71
|
|
72
72
|
# Displays libc information given BuildID.
|
@@ -119,13 +119,18 @@ module OneGadget
|
|
119
119
|
@options[:level] = l
|
120
120
|
end
|
121
121
|
|
122
|
-
opts.on('-n', '--near FUNCTIONS/FILE', 'Order gadgets by their distance to the given functions'\
|
123
|
-
'
|
122
|
+
opts.on('-n', '--near FUNCTIONS/FILE', 'Order gadgets by their distance to the given functions ' \
|
123
|
+
'or to the GOT functions of the given file.') do |n|
|
124
124
|
@options[:near] = n
|
125
125
|
end
|
126
126
|
|
127
|
-
opts.on('-
|
128
|
-
|
127
|
+
opts.on('-o FORMAT', '--output-format FORMAT', %i[pretty raw json],
|
128
|
+
'Output format. FORMAT should be one of <pretty|raw|json>.', 'Default: pretty') do |o|
|
129
|
+
@options[:format] = o
|
130
|
+
end
|
131
|
+
|
132
|
+
opts.on('-r', '--raw', 'Alias of -o raw. Output gadgets offset only, split with one space.') do |_|
|
133
|
+
@options[:format] = :raw
|
129
134
|
end
|
130
135
|
|
131
136
|
opts.on('-s', '--script exploit-script', 'Run exploit script with all possible gadgets.',
|
@@ -176,14 +181,19 @@ module OneGadget
|
|
176
181
|
|
177
182
|
# Writes gadgets to stdout.
|
178
183
|
# @param [Array<OneGadget::Gadget::Gadget>] gadgets
|
179
|
-
# @param [
|
180
|
-
#
|
184
|
+
# @param [Symbol] format
|
185
|
+
# :raw - Only the offset of gadgets are printed.
|
186
|
+
# :pretty - Colorful and human-readable format.
|
187
|
+
# :json - In JSON format.
|
181
188
|
# @return [true]
|
182
|
-
def display_gadgets(gadgets,
|
183
|
-
|
189
|
+
def display_gadgets(gadgets, format)
|
190
|
+
case format
|
191
|
+
when :raw
|
184
192
|
show(gadgets.map(&:value).join(' '))
|
185
|
-
|
193
|
+
when :pretty
|
186
194
|
show(gadgets.map(&:inspect).join("\n"))
|
195
|
+
when :json
|
196
|
+
show(gadgets.to_json)
|
187
197
|
end
|
188
198
|
end
|
189
199
|
|
@@ -199,7 +209,7 @@ module OneGadget
|
|
199
209
|
# @param [String] libc_file
|
200
210
|
# @param [Array<OneGadget::Gadget::Gadget>] gadgets
|
201
211
|
# @param [String] near
|
202
|
-
#
|
212
|
+
# Either name of functions or path to an ELF file.
|
203
213
|
# - Use one comma without spaces to specify a list of functions: +printf,scanf,free+.
|
204
214
|
# - Path to an ELF file and take its GOT functions to process: +/bin/ls+
|
205
215
|
def handle_near(libc_file, gadgets, near)
|
@@ -213,10 +223,19 @@ module OneGadget
|
|
213
223
|
function_offsets = OneGadget::Helper.function_offsets(libc_file, functions)
|
214
224
|
return error('No functions for processing') if function_offsets.empty?
|
215
225
|
|
216
|
-
function_offsets.
|
217
|
-
|
218
|
-
|
219
|
-
|
226
|
+
collection = function_offsets.map do |function, offset|
|
227
|
+
{
|
228
|
+
near: function,
|
229
|
+
near_offset: offset,
|
230
|
+
gadgets: gadgets.sort_by { |gadget| (gadget.offset - offset).abs }
|
231
|
+
}
|
232
|
+
end
|
233
|
+
return show(collection.to_json) if @options[:format] == :json
|
234
|
+
|
235
|
+
collection.each do |c|
|
236
|
+
colored_offset = OneGadget::Helper.colored_hex(c[:near_offset])
|
237
|
+
OneGadget::Logger.warn("Gadgets near #{OneGadget::Helper.colorize(c[:near])}(#{colored_offset}):")
|
238
|
+
display_gadgets(c[:gadgets], @options[:format])
|
220
239
|
show("\n")
|
221
240
|
end
|
222
241
|
true
|
@@ -18,8 +18,8 @@ module OneGadget
|
|
18
18
|
|
19
19
|
# @see OneGadget::Emulators::X86#process!
|
20
20
|
def process!(cmd)
|
21
|
-
inst, args = parse(cmd.gsub(/#-?(0x)?[0-9a-f]+/) { |v| v[1
|
22
|
-
sym = "inst_#{inst.inst}"
|
21
|
+
inst, args = parse(cmd.gsub(/#-?(0x)?[0-9a-f]+/) { |v| v[1..] })
|
22
|
+
sym = :"inst_#{inst.inst}"
|
23
23
|
__send__(sym, *args) != :fail
|
24
24
|
end
|
25
25
|
|
@@ -31,7 +31,7 @@ module OneGadget
|
|
31
31
|
idx = cmd.index(inst)
|
32
32
|
cmd = cmd[0...cmd.rindex('//')] if cmd.rindex('//')
|
33
33
|
cmd = cmd[0...cmd.rindex('#')] if cmd.rindex('#')
|
34
|
-
args = parse_args(cmd[idx + inst.size
|
34
|
+
args = parse_args(cmd[idx + inst.size..])
|
35
35
|
unless argc.include?(args.size)
|
36
36
|
raise OneGadget::Error::InstructionArgumentError, "Incorrect argument number in #{cmd}, expect: #{argc}"
|
37
37
|
end
|
@@ -43,7 +43,7 @@ module OneGadget
|
|
43
43
|
# @param [Numeric] other Value to substract.
|
44
44
|
# @return [Lambda] The result.
|
45
45
|
def -(other)
|
46
|
-
self
|
46
|
+
self + -other
|
47
47
|
end
|
48
48
|
|
49
49
|
# Increase dereference count by 1.
|
@@ -123,8 +123,8 @@ module OneGadget
|
|
123
123
|
# nested []
|
124
124
|
if arg[0] == '['
|
125
125
|
ridx = arg.rindex(']')
|
126
|
-
immi = parse(arg[(ridx + 1)
|
127
|
-
lm = parse(arg[1...ridx], predefined:
|
126
|
+
immi = parse(arg[(ridx + 1)..])
|
127
|
+
lm = parse(arg[1...ridx], predefined:).deref
|
128
128
|
lm += immi unless immi.zero?
|
129
129
|
return lm
|
130
130
|
end
|
@@ -19,7 +19,7 @@ module OneGadget
|
|
19
19
|
# @param [String] sp
|
20
20
|
# The stack register.
|
21
21
|
def initialize(registers, sp)
|
22
|
-
@registers = registers.
|
22
|
+
@registers = registers.to_h { |reg| [reg, to_lambda(reg)] }
|
23
23
|
@sp = sp
|
24
24
|
@constraints = []
|
25
25
|
@sp_based_stack = Hash.new do |h, k|
|
@@ -36,7 +36,7 @@ module OneGadget
|
|
36
36
|
# return registers[pc] = args[0] if inst.inst == 'call'
|
37
37
|
return true if inst.inst == 'jmp' # believe the fetcher has handled jmp.
|
38
38
|
|
39
|
-
sym = "inst_#{inst.inst}"
|
39
|
+
sym = :"inst_#{inst.inst}"
|
40
40
|
__send__(sym, *args) != :fail
|
41
41
|
end
|
42
42
|
|
data/lib/one_gadget/fetcher.rb
CHANGED
@@ -20,7 +20,7 @@ module OneGadget
|
|
20
20
|
# +nil+ is returned if cannot find target id in database.
|
21
21
|
def from_build_id(build_id, remote: true)
|
22
22
|
OneGadget::Helper.verify_build_id!(build_id)
|
23
|
-
OneGadget::Gadget.builds(build_id, remote:
|
23
|
+
OneGadget::Gadget.builds(build_id, remote:)
|
24
24
|
end
|
25
25
|
|
26
26
|
# Fetch one-gadget offsets from file.
|
@@ -28,7 +28,7 @@ module OneGadget
|
|
28
28
|
# use processor to find which can lead to a valid one-gadget call.
|
29
29
|
gadgets = []
|
30
30
|
(lines.size - 2).downto(0) do |i|
|
31
|
-
processor = emulate(lines[i
|
31
|
+
processor = emulate(lines[i..])
|
32
32
|
options = resolve(processor)
|
33
33
|
next if options.nil? # impossible to be a gadget
|
34
34
|
|
@@ -48,7 +48,7 @@ module OneGadget
|
|
48
48
|
# True for valid.
|
49
49
|
# @return [Array<String>]
|
50
50
|
# Each +String+ returned is multi-lines of assembly code.
|
51
|
-
def candidates(&
|
51
|
+
def candidates(&)
|
52
52
|
call_regexp = "#{call_str}.*<(exec[^+]*|posix_spawn[^+]*)>$"
|
53
53
|
cands = []
|
54
54
|
`#{@objdump.command}|grep -E '#{call_regexp}' -B 30`.split('--').each do |cand|
|
@@ -63,7 +63,7 @@ module OneGadget
|
|
63
63
|
end
|
64
64
|
# remove all jmps
|
65
65
|
cands = slice_prefix(cands, &method(:branch?))
|
66
|
-
cands.select!(&
|
66
|
+
cands.select!(&) if block_given?
|
67
67
|
cands
|
68
68
|
end
|
69
69
|
|
@@ -81,7 +81,8 @@ module OneGadget
|
|
81
81
|
call = processor.registers[processor.pc].to_s
|
82
82
|
return resolve_posix_spawn(processor) if call.include?('posix_spawn')
|
83
83
|
return resolve_execve(processor) if call.include?('execve')
|
84
|
-
|
84
|
+
|
85
|
+
resolve_execl(processor) if call.include?('execl')
|
85
86
|
end
|
86
87
|
|
87
88
|
def resolve_execve(processor)
|
@@ -110,7 +111,7 @@ module OneGadget
|
|
110
111
|
envp = arg2
|
111
112
|
end
|
112
113
|
|
113
|
-
{ constraints: cons, envp:
|
114
|
+
{ constraints: cons, envp: }
|
114
115
|
end
|
115
116
|
|
116
117
|
def check_argv(processor, arg, allow_null)
|
@@ -282,7 +283,7 @@ module OneGadget
|
|
282
283
|
cands.map do |cand|
|
283
284
|
lines = cand.lines
|
284
285
|
to_rm = lines[0...-1].rindex(&block)
|
285
|
-
lines = lines[to_rm + 1
|
286
|
+
lines = lines[to_rm + 1..] unless to_rm.nil?
|
286
287
|
lines.join
|
287
288
|
end
|
288
289
|
end
|
data/lib/one_gadget/gadget.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'json'
|
4
|
+
|
3
5
|
require 'one_gadget/abi'
|
4
6
|
require 'one_gadget/emulators/lambda'
|
5
7
|
require 'one_gadget/error'
|
@@ -28,13 +30,12 @@ module OneGadget
|
|
28
30
|
@base = 0
|
29
31
|
@offset = offset
|
30
32
|
@constraints = options[:constraints] || []
|
31
|
-
@effect = options[:effect]
|
33
|
+
@effect = options[:effect] || ''
|
32
34
|
end
|
33
35
|
|
34
36
|
# Show gadget in a pretty way.
|
35
37
|
def inspect
|
36
|
-
str = OneGadget::Helper.hex(value)
|
37
|
-
str += effect ? " #{effect}\n" : "\n"
|
38
|
+
str = "#{OneGadget::Helper.hex(value)} #{effect}\n"
|
38
39
|
unless constraints.empty?
|
39
40
|
str += "#{OneGadget::Helper.colorize('constraints')}:\n "
|
40
41
|
str += merge_constraints.join("\n ")
|
@@ -46,6 +47,21 @@ module OneGadget
|
|
46
47
|
"#{str}\n"
|
47
48
|
end
|
48
49
|
|
50
|
+
# @return [Hash]
|
51
|
+
def to_obj
|
52
|
+
{
|
53
|
+
value:,
|
54
|
+
effect:,
|
55
|
+
constraints:
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
# To have this class can be serialized in JSON.
|
60
|
+
# @return [String]
|
61
|
+
def to_json(*)
|
62
|
+
to_obj.to_json
|
63
|
+
end
|
64
|
+
|
49
65
|
# @return [Integer]
|
50
66
|
# Returns +base+ plus +offset+.
|
51
67
|
def value
|
@@ -112,7 +128,7 @@ module OneGadget
|
|
112
128
|
w_cons, normal = constraints.partition { |c| c.start_with?(key) }
|
113
129
|
return normal if w_cons.empty?
|
114
130
|
|
115
|
-
w_cons.map! { |c| c[key.size
|
131
|
+
w_cons.map! { |c| c[key.size..] }
|
116
132
|
["address#{w_cons.size > 1 ? 'es' : ''} #{w_cons.join(', ')} #{w_cons.size > 1 ? 'are' : 'is'} writable"] +
|
117
133
|
normal
|
118
134
|
end
|
@@ -161,7 +177,7 @@ module OneGadget
|
|
161
177
|
def builds_info(build_id)
|
162
178
|
raise Error::ArgumentError, "Invalid BuildID #{build_id.inspect}" if build_id =~ /[^0-9a-f]/
|
163
179
|
|
164
|
-
files = Dir.glob(File.join(BUILDS_PATH, "*-#{build_id}*.rb"))
|
180
|
+
files = Dir.glob(File.join(BUILDS_PATH, "*-#{build_id}*.rb"))
|
165
181
|
return OneGadget::Logger.not_found(build_id) && nil if files.empty?
|
166
182
|
|
167
183
|
if files.size > 1
|
@@ -189,7 +205,7 @@ module OneGadget
|
|
189
205
|
def find_build(id)
|
190
206
|
return BUILDS[id] if BUILDS.key?(id)
|
191
207
|
|
192
|
-
Dir.glob(File.join(BUILDS_PATH, "*-#{id}.rb")).
|
208
|
+
Dir.glob(File.join(BUILDS_PATH, "*-#{id}.rb")).each do |dic|
|
193
209
|
require dic
|
194
210
|
end
|
195
211
|
BUILDS[id] if BUILDS.key?(id)
|
data/lib/one_gadget/helper.rb
CHANGED
@@ -13,7 +13,7 @@ module OneGadget
|
|
13
13
|
# Define some helpful methods here.
|
14
14
|
module Helper
|
15
15
|
# Format of build-id, 40 hex numbers.
|
16
|
-
BUILD_ID_FORMAT = /[0-9a-f]{40}
|
16
|
+
BUILD_ID_FORMAT = /[0-9a-f]{40}/
|
17
17
|
|
18
18
|
module_function
|
19
19
|
|
@@ -35,7 +35,7 @@ module OneGadget
|
|
35
35
|
# @return [Array<String>]
|
36
36
|
# Lines of comments.
|
37
37
|
def comments_of_file(file)
|
38
|
-
File.readlines(file).map { |s| s[2
|
38
|
+
File.readlines(file).map { |s| s[2..].rstrip if s.start_with?('# ') }.compact
|
39
39
|
end
|
40
40
|
|
41
41
|
# Get absolute path from relative path. Support symlink.
|
data/lib/one_gadget/update.rb
CHANGED
@@ -24,14 +24,14 @@ module OneGadget
|
|
24
24
|
FileUtils.touch(cache_file)
|
25
25
|
OneGadget::Logger.info("Checking for new versions of OneGadget\n" \
|
26
26
|
"To disable this functionality, do\n$ echo never > #{CACHE_FILE}\n\n")
|
27
|
-
latest = Helper.latest_tag[1
|
27
|
+
latest = Helper.latest_tag[1..] # remove 'v'
|
28
28
|
if Gem::Version.new(latest) <= Gem::Version.new(OneGadget::VERSION)
|
29
29
|
return OneGadget::Logger.info("You have the latest version of OneGadget (#{latest})!\n\n")
|
30
30
|
end
|
31
31
|
|
32
32
|
# show update message
|
33
33
|
msg = format('A newer version of OneGadget is available (%s --> %s).', OneGadget::VERSION, latest)
|
34
|
-
OneGadget::Logger.ask_update(msg:
|
34
|
+
OneGadget::Logger.ask_update(msg:)
|
35
35
|
end
|
36
36
|
|
37
37
|
private
|
data/lib/one_gadget/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: one_gadget
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- david942j
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-10-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: elftools
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version: 1.0.2
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 1.
|
22
|
+
version: 1.4.0
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,7 +29,7 @@ dependencies:
|
|
29
29
|
version: 1.0.2
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 1.
|
32
|
+
version: 1.4.0
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: rake
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -1014,14 +1014,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
1014
1014
|
requirements:
|
1015
1015
|
- - ">="
|
1016
1016
|
- !ruby/object:Gem::Version
|
1017
|
-
version: '
|
1017
|
+
version: '3.1'
|
1018
1018
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
1019
1019
|
requirements:
|
1020
1020
|
- - ">="
|
1021
1021
|
- !ruby/object:Gem::Version
|
1022
1022
|
version: '0'
|
1023
1023
|
requirements: []
|
1024
|
-
rubygems_version: 3.
|
1024
|
+
rubygems_version: 3.5.3
|
1025
1025
|
signing_key:
|
1026
1026
|
specification_version: 4
|
1027
1027
|
summary: one_gadget
|