one_gadget 1.9.0 → 1.10.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/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
|

|
@@ -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
|

|
@@ -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
|