seccomp-tools 1.1.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +112 -30
- data/bin/seccomp-tools +1 -0
- data/ext/ptrace/extconf.rb +2 -0
- data/ext/ptrace/ptrace.c +107 -5
- data/lib/seccomp-tools.rb +5 -0
- data/lib/seccomp-tools/asm/asm.rb +5 -2
- data/lib/seccomp-tools/asm/compiler.rb +96 -18
- data/lib/seccomp-tools/asm/tokenizer.rb +25 -8
- data/lib/seccomp-tools/bpf.rb +7 -4
- data/lib/seccomp-tools/cli/asm.rb +16 -6
- data/lib/seccomp-tools/cli/base.rb +10 -4
- data/lib/seccomp-tools/cli/cli.rb +9 -6
- data/lib/seccomp-tools/cli/disasm.rb +6 -2
- data/lib/seccomp-tools/cli/dump.rb +37 -6
- data/lib/seccomp-tools/cli/emu.rb +41 -22
- data/lib/seccomp-tools/const.rb +47 -16
- data/lib/seccomp-tools/consts/sys_arg.rb +432 -0
- data/lib/seccomp-tools/consts/sys_nr/aarch64.rb +284 -0
- data/lib/seccomp-tools/consts/{amd64.rb → sys_nr/amd64.rb} +6 -1
- data/lib/seccomp-tools/consts/{i386.rb → sys_nr/i386.rb} +18 -15
- data/lib/seccomp-tools/disasm/context.rb +125 -34
- data/lib/seccomp-tools/disasm/disasm.rb +5 -2
- data/lib/seccomp-tools/dumper.rb +75 -8
- data/lib/seccomp-tools/emulator.rb +19 -8
- data/lib/seccomp-tools/instruction/alu.rb +7 -2
- data/lib/seccomp-tools/instruction/base.rb +5 -3
- data/lib/seccomp-tools/instruction/instruction.rb +2 -0
- data/lib/seccomp-tools/instruction/jmp.rb +28 -14
- data/lib/seccomp-tools/instruction/ld.rb +28 -12
- data/lib/seccomp-tools/instruction/ldx.rb +2 -0
- data/lib/seccomp-tools/instruction/misc.rb +2 -0
- data/lib/seccomp-tools/instruction/ret.rb +14 -2
- data/lib/seccomp-tools/instruction/st.rb +4 -2
- data/lib/seccomp-tools/instruction/stx.rb +2 -0
- data/lib/seccomp-tools/logger.rb +40 -0
- data/lib/seccomp-tools/syscall.rb +24 -13
- data/lib/seccomp-tools/templates/asm.amd64.asm +26 -0
- data/lib/seccomp-tools/templates/asm.c +17 -0
- data/lib/seccomp-tools/templates/asm.i386.asm +33 -0
- data/lib/seccomp-tools/util.rb +24 -3
- data/lib/seccomp-tools/version.rb +3 -1
- metadata +51 -44
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: fa755fd2e7ed97279b094dfa28bd668aef4ee638005f0b38405066502fc8a30d
|
4
|
+
data.tar.gz: 56b0d51796d97a89f67262c36716833d078ce19ea6b58fbb83c2f8bee88b8685
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 027f57a717cb63fadeefd4a60213115a27ed51bb1eb3e6b58251690ed7c1d42335086ff4448b480296b77d395ba2e8718fa662e227394abfddaf80b19b769b74
|
7
|
+
data.tar.gz: f6aca254b4a43d6c60d5df7e6694b976de1e56fbb6d6585bd46fd17c0849820d76c81f25bbc872dc785576e05eeaaab5d0276a3f065b730988973c5073ace761
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
[![Build Status](https://
|
1
|
+
[![Build Status](https://github.com/david942j/seccomp-tools/workflows/build/badge.svg)](https://github.com/david942j/seccomp-tools/actions)
|
2
|
+
[![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=david942j/seccomp-tools)](https://dependabot.com)
|
2
3
|
[![Code Climate](https://codeclimate.com/github/david942j/seccomp-tools/badges/gpa.svg)](https://codeclimate.com/github/david942j/seccomp-tools)
|
3
4
|
[![Issue Count](https://codeclimate.com/github/david942j/seccomp-tools/badges/issue_count.svg)](https://codeclimate.com/github/david942j/seccomp-tools)
|
4
5
|
[![Test Coverage](https://codeclimate.com/github/david942j/seccomp-tools/badges/coverage.svg)](https://codeclimate.com/github/david942j/seccomp-tools/coverage)
|
@@ -6,20 +7,20 @@
|
|
6
7
|
[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](http://choosealicense.com/licenses/mit/)
|
7
8
|
|
8
9
|
# Seccomp Tools
|
9
|
-
|
10
|
+
Provide powerful tools for seccomp analysis.
|
10
11
|
|
11
12
|
This project is targeted to (but not limited to) analyze seccomp sandbox in CTF pwn challenges.
|
12
|
-
Some features might be CTF-specific, but still useful for
|
13
|
+
Some features might be CTF-specific, but still useful for analyzing seccomp in real-case.
|
13
14
|
|
14
15
|
## Features
|
15
|
-
* Dump - Automatically
|
16
|
-
* Disasm -
|
16
|
+
* Dump - Automatically dumps seccomp-bpf from execution file(s).
|
17
|
+
* Disasm - Converts bpf to human readable format.
|
17
18
|
- Simple decompile.
|
18
|
-
-
|
19
|
+
- Display syscall names and arguments when possible.
|
20
|
+
- Colorful!
|
19
21
|
* Asm - Write seccomp rules is so easy!
|
20
|
-
* Emu -
|
21
|
-
*
|
22
|
-
* Support multi-architectures.
|
22
|
+
* Emu - Emulates seccomp rules.
|
23
|
+
* Supports multi-architectures.
|
23
24
|
|
24
25
|
## Installation
|
25
26
|
|
@@ -28,6 +29,12 @@ Available on RubyGems.org!
|
|
28
29
|
$ gem install seccomp-tools
|
29
30
|
```
|
30
31
|
|
32
|
+
If you failed when compiling, try:
|
33
|
+
```
|
34
|
+
sudo apt install gcc ruby-dev
|
35
|
+
```
|
36
|
+
and install seccomp-tools again.
|
37
|
+
|
31
38
|
## Command Line Interface
|
32
39
|
|
33
40
|
### seccomp-tools
|
@@ -38,19 +45,21 @@ $ seccomp-tools --help
|
|
38
45
|
#
|
39
46
|
# List of commands:
|
40
47
|
#
|
41
|
-
# dump Automatically dump seccomp bpf from execution file.
|
42
|
-
# disasm Disassemble seccomp bpf.
|
43
48
|
# asm Seccomp bpf assembler.
|
49
|
+
# disasm Disassemble seccomp bpf.
|
50
|
+
# dump Automatically dump seccomp bpf from execution file(s).
|
44
51
|
# emu Emulate seccomp rules.
|
45
52
|
#
|
46
|
-
# See 'seccomp-tools
|
53
|
+
# See 'seccomp-tools <command> --help' to read about a specific subcommand.
|
47
54
|
|
48
|
-
$ seccomp-tools --help
|
49
|
-
# dump - Automatically dump seccomp bpf from execution file.
|
55
|
+
$ seccomp-tools dump --help
|
56
|
+
# dump - Automatically dump seccomp bpf from execution file(s).
|
57
|
+
# NOTE : This function is only available on Linux.
|
50
58
|
#
|
51
59
|
# Usage: seccomp-tools dump [exec] [options]
|
52
60
|
# -c, --sh-exec <command> Executes the given command (via sh).
|
53
61
|
# Use this option if want to pass arguments or do pipe things to the execution file.
|
62
|
+
# e.g. use `-c "./bin > /dev/null"` to dump seccomp without being mixed with stdout.
|
54
63
|
# -f, --format FORMAT Output format. FORMAT can only be one of <disasm|raw|inspect>.
|
55
64
|
# Default: disasm
|
56
65
|
# -l, --limit LIMIT Limit the number of calling "prctl(PR_SET_SECCOMP)".
|
@@ -60,12 +69,14 @@ $ seccomp-tools --help dump
|
|
60
69
|
# If multiple seccomp syscalls have been invoked (see --limit),
|
61
70
|
# results will be written to FILE, FILE_1, FILE_2.. etc.
|
62
71
|
# For example, "--output out.bpf" and the output files are out.bpf, out_1.bpf, ...
|
72
|
+
# -p, --pid PID Dump installed seccomp filters of the existing process.
|
73
|
+
# You must have CAP_SYS_ADMIN (e.g. be root) in order to use this option.
|
63
74
|
|
64
75
|
```
|
65
76
|
|
66
77
|
### dump
|
67
78
|
|
68
|
-
|
79
|
+
Dumps the seccomp bpf from an execution file.
|
69
80
|
This work is done by the `ptrace` syscall.
|
70
81
|
|
71
82
|
NOTICE: beware of the execution file will be executed.
|
@@ -113,7 +124,7 @@ $ seccomp-tools dump spec/binary/twctf-2016-diary -f raw | xxd
|
|
113
124
|
|
114
125
|
### disasm
|
115
126
|
|
116
|
-
|
127
|
+
Disassembles the seccomp from raw bpf.
|
117
128
|
```bash
|
118
129
|
$ xxd spec/data/twctf-2016-diary.bpf | head -n 3
|
119
130
|
# 00000000: 2000 0000 0000 0000 1500 0001 0200 0000 ...............
|
@@ -146,26 +157,27 @@ $ seccomp-tools disasm spec/data/twctf-2016-diary.bpf
|
|
146
157
|
|
147
158
|
### asm
|
148
159
|
|
149
|
-
|
150
|
-
|
160
|
+
Assembles the seccomp rules into raw bytes.
|
161
|
+
It's very useful when one wants to write custom seccomp rules.
|
151
162
|
|
152
|
-
Supports labels for jumping and
|
163
|
+
Supports labels for jumping and uses syscall names directly. See examples below.
|
153
164
|
```bash
|
154
165
|
$ seccomp-tools asm
|
155
166
|
# asm - Seccomp bpf assembler.
|
156
167
|
#
|
157
168
|
# Usage: seccomp-tools asm IN_FILE [options]
|
158
169
|
# -o, --output FILE Output result into FILE instead of stdout.
|
159
|
-
# -f, --format FORMAT Output format. FORMAT can only be one of <inspect|raw|
|
170
|
+
# -f, --format FORMAT Output format. FORMAT can only be one of <inspect|raw|c_array|c_source|assembly>.
|
160
171
|
# Default: inspect
|
161
172
|
# -a, --arch ARCH Specify architecture.
|
162
|
-
# Supported architectures are <amd64|i386>.
|
173
|
+
# Supported architectures are <aarch64|amd64|i386>.
|
174
|
+
# Default: amd64
|
163
175
|
|
164
176
|
# Input file for asm
|
165
177
|
$ cat spec/data/libseccomp.asm
|
166
178
|
# # check if arch is X86_64
|
167
179
|
# A = arch
|
168
|
-
# A ==
|
180
|
+
# A == ARCH_X86_64 ? next : dead
|
169
181
|
# A = sys_number
|
170
182
|
# A >= 0x40000000 ? dead : next
|
171
183
|
# A == write ? ok : next
|
@@ -181,8 +193,52 @@ $ cat spec/data/libseccomp.asm
|
|
181
193
|
$ seccomp-tools asm spec/data/libseccomp.asm
|
182
194
|
# " \x00\x00\x00\x04\x00\x00\x00\x15\x00\x00\b>\x00\x00\xC0 \x00\x00\x00\x00\x00\x00\x005\x00\x06\x00\x00\x00\x00@\x15\x00\x04\x00\x01\x00\x00\x00\x15\x00\x03\x00\x03\x00\x00\x00\x15\x00\x02\x00 \x00\x00\x00\x15\x00\x01\x00<\x00\x00\x00\x06\x00\x00\x00\x05\x00\x05\x00\x06\x00\x00\x00\x00\x00\xFF\x7F\x06\x00\x00\x00\x00\x00\x00\x00"
|
183
195
|
|
184
|
-
$ seccomp-tools asm spec/data/libseccomp.asm -f
|
185
|
-
#
|
196
|
+
$ seccomp-tools asm spec/data/libseccomp.asm -f c_source
|
197
|
+
# #include <linux/seccomp.h>
|
198
|
+
# #include <stdio.h>
|
199
|
+
# #include <stdlib.h>
|
200
|
+
# #include <sys/prctl.h>
|
201
|
+
#
|
202
|
+
# static void install_seccomp() {
|
203
|
+
# static unsigned char filter[] = {32,0,0,0,4,0,0,0,21,0,0,8,62,0,0,192,32,0,0,0,0,0,0,0,53,0,6,0,0,0,0,64,21,0,4,0,1,0,0,0,21,0,3,0,3,0,0,0,21,0,2,0,32,0,0,0,21,0,1,0,60,0,0,0,6,0,0,0,5,0,5,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0};
|
204
|
+
# struct prog {
|
205
|
+
# unsigned short len;
|
206
|
+
# unsigned char *filter;
|
207
|
+
# } rule = {
|
208
|
+
# .len = sizeof(filter) >> 3,
|
209
|
+
# .filter = filter
|
210
|
+
# };
|
211
|
+
# if(prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) { perror("prctl(PR_SET_NO_NEW_PRIVS)"); exit(2); }
|
212
|
+
# if(prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &rule) < 0) { perror("prctl(PR_SET_SECCOMP)"); exit(2); }
|
213
|
+
# }
|
214
|
+
|
215
|
+
$ seccomp-tools asm spec/data/libseccomp.asm -f assembly
|
216
|
+
# install_seccomp:
|
217
|
+
# push rbp
|
218
|
+
# mov rbp, rsp
|
219
|
+
# push 38
|
220
|
+
# pop rdi
|
221
|
+
# push 0x1
|
222
|
+
# pop rsi
|
223
|
+
# xor eax, eax
|
224
|
+
# mov al, 0x9d
|
225
|
+
# syscall
|
226
|
+
# push 22
|
227
|
+
# pop rdi
|
228
|
+
# lea rdx, [rip + _filter]
|
229
|
+
# push rdx /* .filter */
|
230
|
+
# push _filter_end - _filter >> 3 /* .len */
|
231
|
+
# mov rdx, rsp
|
232
|
+
# push 0x2
|
233
|
+
# pop rsi
|
234
|
+
# xor eax, eax
|
235
|
+
# mov al, 0x9d
|
236
|
+
# syscall
|
237
|
+
# leave
|
238
|
+
# ret
|
239
|
+
# _filter:
|
240
|
+
# .ascii "\040\000\000\000\004\000\000\000\025\000\000\010\076\000\000\300\040\000\000\000\000\000\000\000\065\000\006\000\000\000\000\100\025\000\004\000\001\000\000\000\025\000\003\000\003\000\000\000\025\000\002\000\040\000\000\000\025\000\001\000\074\000\000\000\006\000\000\000\005\000\005\000\006\000\000\000\000\000\377\177\006\000\000\000\000\000\000\000"
|
241
|
+
# _filter_end:
|
186
242
|
|
187
243
|
|
188
244
|
# let's asm then disasm!
|
@@ -197,7 +253,7 @@ $ seccomp-tools asm spec/data/libseccomp.asm -f raw | seccomp-tools disasm -
|
|
197
253
|
# 0005: 0x15 0x03 0x00 0x00000003 if (A == close) goto 0009
|
198
254
|
# 0006: 0x15 0x02 0x00 0x00000020 if (A == dup) goto 0009
|
199
255
|
# 0007: 0x15 0x01 0x00 0x0000003c if (A == exit) goto 0009
|
200
|
-
# 0008: 0x06 0x00 0x00 0x00050005 return ERRNO
|
256
|
+
# 0008: 0x06 0x00 0x00 0x00050005 return ERRNO(5)
|
201
257
|
# 0009: 0x06 0x00 0x00 0x7fff0000 return ALLOW
|
202
258
|
# 0010: 0x06 0x00 0x00 0x00000000 return KILL
|
203
259
|
|
@@ -205,17 +261,18 @@ $ seccomp-tools asm spec/data/libseccomp.asm -f raw | seccomp-tools disasm -
|
|
205
261
|
|
206
262
|
### Emu
|
207
263
|
|
208
|
-
|
264
|
+
Emulates seccomp given `sys_nr`, `arg0`, `arg1`, etc.
|
209
265
|
```bash
|
210
266
|
$ seccomp-tools emu --help
|
211
267
|
# emu - Emulate seccomp rules.
|
212
268
|
#
|
213
269
|
# Usage: seccomp-tools emu [options] BPF_FILE [sys_nr [arg0 [arg1 ... arg5]]]
|
214
270
|
# -a, --arch ARCH Specify architecture.
|
215
|
-
# Supported architectures are <amd64|i386>.
|
271
|
+
# Supported architectures are <aarch64|amd64|i386>.
|
272
|
+
# Default: amd64
|
216
273
|
# -q, --[no-]quiet Run quietly, only show emulation result.
|
217
274
|
|
218
|
-
$ seccomp-tools emu spec/data/libseccomp.bpf 0x3
|
275
|
+
$ seccomp-tools emu spec/data/libseccomp.bpf write 0x3
|
219
276
|
# line CODE JT JF K
|
220
277
|
# =================================
|
221
278
|
# 0000: 0x20 0x00 0x00 0x00000004 A = arch
|
@@ -226,7 +283,7 @@ $ seccomp-tools emu spec/data/libseccomp.bpf 0x3
|
|
226
283
|
# 0005: 0x15 0x03 0x00 0x00000003 if (A == close) goto 0009
|
227
284
|
# 0006: 0x15 0x02 0x00 0x00000020 if (A == dup) goto 0009
|
228
285
|
# 0007: 0x15 0x01 0x00 0x0000003c if (A == exit) goto 0009
|
229
|
-
# 0008: 0x06 0x00 0x00 0x00050005 return ERRNO
|
286
|
+
# 0008: 0x06 0x00 0x00 0x00050005 return ERRNO(5)
|
230
287
|
# 0009: 0x06 0x00 0x00 0x7fff0000 return ALLOW
|
231
288
|
# 0010: 0x06 0x00 0x00 0x00000000 return KILL
|
232
289
|
#
|
@@ -244,7 +301,32 @@ $ seccomp-tools emu spec/data/libseccomp.bpf 0x3
|
|
244
301
|
|
245
302
|
![emu](https://github.com/david942j/seccomp-tools/blob/master/examples/emu-amigo.png?raw=true)
|
246
303
|
|
304
|
+
## Architecture Supported
|
305
|
+
|
306
|
+
- [x] x86_64
|
307
|
+
- [x] x32
|
308
|
+
- [x] x86
|
309
|
+
- [x] arm64 (Thanks to @saagarjha!)
|
310
|
+
|
311
|
+
## Development
|
312
|
+
|
313
|
+
I recommend to use [rbenv](https://github.com/rbenv/rbenv) for your Ruby environment.
|
314
|
+
|
315
|
+
### Setup
|
316
|
+
|
317
|
+
- Install bundler
|
318
|
+
- `$ gem install bundler`
|
319
|
+
- Clone the source
|
320
|
+
- `$ git clone https://github.com/david942j/seccomp-tools && cd seccomp-tools`
|
321
|
+
- Install dependencies
|
322
|
+
- `$ bundle install`
|
323
|
+
|
324
|
+
### Run tests
|
325
|
+
|
326
|
+
`$ bundle exec rake`
|
327
|
+
|
247
328
|
## I Need You
|
329
|
+
|
248
330
|
Any suggestion or feature request is welcome!
|
249
331
|
Feel free to file an issue or send a pull request.
|
250
|
-
And, if you like this work, I'll be happy to be [
|
332
|
+
And, if you like this work, I'll be happy to be [starred](https://github.com/david942j/seccomp-tools/stargazers) :grimacing:
|
data/bin/seccomp-tools
CHANGED
data/ext/ptrace/extconf.rb
CHANGED
data/ext/ptrace/ptrace.c
CHANGED
@@ -1,5 +1,16 @@
|
|
1
|
+
// ptrace is only available on Linux, therefore let this file be an empty
|
2
|
+
// object when installing on other platforms.
|
3
|
+
#if __linux__
|
4
|
+
|
5
|
+
#include <assert.h>
|
6
|
+
#include <errno.h>
|
7
|
+
#include <linux/elf.h>
|
8
|
+
#include <linux/filter.h>
|
9
|
+
#include <stdint.h>
|
1
10
|
#include <sys/ptrace.h>
|
2
11
|
#include <sys/signal.h>
|
12
|
+
#include <sys/uio.h>
|
13
|
+
#include <sys/wait.h>
|
3
14
|
|
4
15
|
#include "ruby.h"
|
5
16
|
|
@@ -16,10 +27,53 @@ ptrace_peekdata(VALUE _mod, VALUE pid, VALUE addr, VALUE _data) {
|
|
16
27
|
return LONG2NUM(val);
|
17
28
|
}
|
18
29
|
|
30
|
+
// aarch64 doesn't support PTRACE_PEEKUSER, but it does support
|
31
|
+
// PTRACE_GETREGSET which is fairly similar. Since i386 and x86_64 support it
|
32
|
+
// too, just use that unconditionally to present the same API for the registers
|
33
|
+
// we care about.
|
19
34
|
static VALUE
|
20
|
-
ptrace_peekuser(VALUE _mod, VALUE pid, VALUE off, VALUE _data) {
|
21
|
-
|
22
|
-
|
35
|
+
ptrace_peekuser(VALUE _mod, VALUE pid, VALUE off, VALUE _data, VALUE bits) {
|
36
|
+
size_t offset = NUM2LONG(off);
|
37
|
+
// Unless your registers fill an entire page, an offset greater than this is
|
38
|
+
// probably wrong.
|
39
|
+
if (offset >= 4096) {
|
40
|
+
return LONG2NUM(-1);
|
41
|
+
}
|
42
|
+
size_t width = NUM2LONG(bits);
|
43
|
+
if (width != 32 && width != 64) {
|
44
|
+
return LONG2NUM(-1);
|
45
|
+
}
|
46
|
+
width /= 8;
|
47
|
+
union {
|
48
|
+
uint32_t val32;
|
49
|
+
uint64_t val64;
|
50
|
+
} val;
|
51
|
+
// Dynamically allocate a buffer to store registers-well, at least enough
|
52
|
+
// registers to reach the offset we want. Normally we'd want to use
|
53
|
+
// user_pt_regs or similar, but it's difficult to find it available in the
|
54
|
+
// the same header across different versions of Linux or libcs, or even with
|
55
|
+
// the same *name*, so this is the compromise.
|
56
|
+
size_t size = offset + width;
|
57
|
+
char *regs = malloc(size);
|
58
|
+
if (!regs) {
|
59
|
+
return LONG2NUM(-1);
|
60
|
+
}
|
61
|
+
struct iovec vec = { regs, size };
|
62
|
+
if (ptrace(PTRACE_GETREGSET, NUM2LONG(pid), NT_PRSTATUS, &vec) != -1 && vec.iov_len >= size) {
|
63
|
+
memcpy(&val, regs + offset, width);
|
64
|
+
} else {
|
65
|
+
free(regs);
|
66
|
+
return LONG2NUM(-1);
|
67
|
+
}
|
68
|
+
free(regs);
|
69
|
+
if (width == sizeof(val.val32)) {
|
70
|
+
return LONG2NUM(val.val32);
|
71
|
+
} else if (width == sizeof(val.val64)) {
|
72
|
+
return LONG2NUM(val.val64);
|
73
|
+
} else {
|
74
|
+
assert(!"Unreachable");
|
75
|
+
return LONG2NUM(-1);
|
76
|
+
}
|
23
77
|
}
|
24
78
|
|
25
79
|
static VALUE
|
@@ -50,9 +104,44 @@ ptrace_traceme_and_stop(VALUE mod) {
|
|
50
104
|
return Qnil;
|
51
105
|
}
|
52
106
|
|
107
|
+
static VALUE
|
108
|
+
ptrace_attach_and_wait(VALUE _mod, VALUE pid) {
|
109
|
+
long val = ptrace(PTRACE_ATTACH, NUM2LONG(pid), 0, 0);
|
110
|
+
if(val < 0)
|
111
|
+
rb_sys_fail("ptrace attach failed");
|
112
|
+
waitpid(NUM2LONG(pid), NULL, 0);
|
113
|
+
return Qnil;
|
114
|
+
}
|
115
|
+
|
116
|
+
static VALUE
|
117
|
+
ptrace_seccomp_get_filter(VALUE _mod, VALUE pid, VALUE index) {
|
118
|
+
long count = ptrace(PTRACE_SECCOMP_GET_FILTER, NUM2LONG(pid), NUM2LONG(index), NULL);
|
119
|
+
struct sock_filter *filter;
|
120
|
+
VALUE result;
|
121
|
+
if(count < 0)
|
122
|
+
rb_sys_fail("ptrace seccomp_get_filter failed");
|
123
|
+
filter = ALLOC_N(struct sock_filter, count);
|
124
|
+
if(ptrace(PTRACE_SECCOMP_GET_FILTER, NUM2LONG(pid), NUM2LONG(index), filter) != count) {
|
125
|
+
xfree(filter);
|
126
|
+
rb_sys_fail("ptrace seccomp_get_filter failed");
|
127
|
+
}
|
128
|
+
result = rb_str_new((const char *)filter, sizeof(struct sock_filter) * count);
|
129
|
+
xfree(filter);
|
130
|
+
return result;
|
131
|
+
}
|
132
|
+
|
133
|
+
static VALUE
|
134
|
+
ptrace_detach(VALUE _mod, VALUE pid) {
|
135
|
+
long val = ptrace(PTRACE_DETACH, NUM2LONG(pid), 0, 0);
|
136
|
+
if(val < 0)
|
137
|
+
rb_sys_fail(0);
|
138
|
+
return Qnil;
|
139
|
+
}
|
140
|
+
|
53
141
|
|
54
142
|
void Init_ptrace(void) {
|
55
143
|
VALUE mSeccompTools = rb_define_module("SeccompTools");
|
144
|
+
/* The module to wrap ptrace syscall */
|
56
145
|
VALUE mPtrace = rb_define_module_under(mSeccompTools, "Ptrace");
|
57
146
|
|
58
147
|
/* consts */
|
@@ -64,13 +153,26 @@ void Init_ptrace(void) {
|
|
64
153
|
rb_define_const(mPtrace, "O_TRACESYSGOOD", UINT2NUM(PTRACE_O_TRACESYSGOOD));
|
65
154
|
rb_define_const(mPtrace, "O_TRACEVFORK", UINT2NUM(PTRACE_O_TRACEVFORK));
|
66
155
|
|
67
|
-
/*
|
156
|
+
/* geteventmsg */
|
68
157
|
rb_define_module_function(mPtrace, "geteventmsg", ptrace_geteventmsg, 1);
|
158
|
+
/* get data */
|
69
159
|
rb_define_module_function(mPtrace, "peekdata", ptrace_peekdata, 3);
|
70
|
-
|
160
|
+
/* get registers */
|
161
|
+
rb_define_module_function(mPtrace, "peekuser", ptrace_peekuser, 4);
|
162
|
+
/* set ptrace options */
|
71
163
|
rb_define_module_function(mPtrace, "setoptions", ptrace_setoptions, 3);
|
164
|
+
/* wait for syscall */
|
72
165
|
rb_define_module_function(mPtrace, "syscall", ptrace_syscall, 3);
|
166
|
+
/* wait for its parent to attach */
|
73
167
|
rb_define_module_function(mPtrace, "traceme", ptrace_traceme, 0);
|
168
|
+
/* stop itself before parent attaching */
|
74
169
|
rb_define_module_function(mPtrace, "traceme_and_stop", ptrace_traceme_and_stop, 0);
|
170
|
+
/* attach to an existing process */
|
171
|
+
rb_define_module_function(mPtrace, "attach_and_wait", ptrace_attach_and_wait, 1);
|
172
|
+
/* retrieve seccomp filter */
|
173
|
+
rb_define_module_function(mPtrace, "seccomp_get_filter", ptrace_seccomp_get_filter, 2);
|
174
|
+
/* detach from an existing process */
|
175
|
+
rb_define_module_function(mPtrace, "detach", ptrace_detach, 1);
|
75
176
|
}
|
76
177
|
|
178
|
+
#endif /* __linux__ */
|
data/lib/seccomp-tools.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# @author david942j
|
2
4
|
|
3
5
|
# Main module.
|
4
6
|
module SeccompTools
|
5
7
|
end
|
6
8
|
|
9
|
+
require 'seccomp-tools/asm/asm'
|
10
|
+
require 'seccomp-tools/disasm/disasm'
|
7
11
|
require 'seccomp-tools/dumper'
|
12
|
+
require 'seccomp-tools/emulator'
|
8
13
|
require 'seccomp-tools/version'
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'seccomp-tools/asm/compiler'
|
2
4
|
require 'seccomp-tools/util'
|
3
5
|
|
@@ -8,10 +10,11 @@ module SeccompTools
|
|
8
10
|
|
9
11
|
# Assembler of seccomp bpf.
|
10
12
|
# @param [String] str
|
13
|
+
# @param [:amd64, :i386] arch
|
11
14
|
# @return [String]
|
12
15
|
# Raw bpf bytes.
|
13
16
|
# @example
|
14
|
-
# asm(
|
17
|
+
# SeccompTools::Asm.asm(<<-EOS)
|
15
18
|
# # lines start with '#' are comments
|
16
19
|
# A = sys_number # here's a comment, too
|
17
20
|
# A >= 0x40000000 ? dead : next # 'next' is a keyword, denote the next instruction
|
@@ -25,7 +28,7 @@ module SeccompTools
|
|
25
28
|
# EOS
|
26
29
|
# #=> <raw binary bytes>
|
27
30
|
def asm(str, arch: nil)
|
28
|
-
arch = Util.system_arch if arch.nil?
|
31
|
+
arch = Util.system_arch if arch.nil?
|
29
32
|
compiler = Compiler.new(arch)
|
30
33
|
str.lines.each { |l| compiler.process(l) }
|
31
34
|
compiler.compile!.map(&:asm).join
|