seccomp-tools 1.1.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +112 -30
  3. data/bin/seccomp-tools +1 -0
  4. data/ext/ptrace/extconf.rb +2 -0
  5. data/ext/ptrace/ptrace.c +107 -5
  6. data/lib/seccomp-tools.rb +5 -0
  7. data/lib/seccomp-tools/asm/asm.rb +5 -2
  8. data/lib/seccomp-tools/asm/compiler.rb +96 -18
  9. data/lib/seccomp-tools/asm/tokenizer.rb +25 -8
  10. data/lib/seccomp-tools/bpf.rb +7 -4
  11. data/lib/seccomp-tools/cli/asm.rb +16 -6
  12. data/lib/seccomp-tools/cli/base.rb +10 -4
  13. data/lib/seccomp-tools/cli/cli.rb +9 -6
  14. data/lib/seccomp-tools/cli/disasm.rb +6 -2
  15. data/lib/seccomp-tools/cli/dump.rb +37 -6
  16. data/lib/seccomp-tools/cli/emu.rb +41 -22
  17. data/lib/seccomp-tools/const.rb +47 -16
  18. data/lib/seccomp-tools/consts/sys_arg.rb +432 -0
  19. data/lib/seccomp-tools/consts/sys_nr/aarch64.rb +284 -0
  20. data/lib/seccomp-tools/consts/{amd64.rb → sys_nr/amd64.rb} +6 -1
  21. data/lib/seccomp-tools/consts/{i386.rb → sys_nr/i386.rb} +18 -15
  22. data/lib/seccomp-tools/disasm/context.rb +125 -34
  23. data/lib/seccomp-tools/disasm/disasm.rb +5 -2
  24. data/lib/seccomp-tools/dumper.rb +75 -8
  25. data/lib/seccomp-tools/emulator.rb +19 -8
  26. data/lib/seccomp-tools/instruction/alu.rb +7 -2
  27. data/lib/seccomp-tools/instruction/base.rb +5 -3
  28. data/lib/seccomp-tools/instruction/instruction.rb +2 -0
  29. data/lib/seccomp-tools/instruction/jmp.rb +28 -14
  30. data/lib/seccomp-tools/instruction/ld.rb +28 -12
  31. data/lib/seccomp-tools/instruction/ldx.rb +2 -0
  32. data/lib/seccomp-tools/instruction/misc.rb +2 -0
  33. data/lib/seccomp-tools/instruction/ret.rb +14 -2
  34. data/lib/seccomp-tools/instruction/st.rb +4 -2
  35. data/lib/seccomp-tools/instruction/stx.rb +2 -0
  36. data/lib/seccomp-tools/logger.rb +40 -0
  37. data/lib/seccomp-tools/syscall.rb +24 -13
  38. data/lib/seccomp-tools/templates/asm.amd64.asm +26 -0
  39. data/lib/seccomp-tools/templates/asm.c +17 -0
  40. data/lib/seccomp-tools/templates/asm.i386.asm +33 -0
  41. data/lib/seccomp-tools/util.rb +24 -3
  42. data/lib/seccomp-tools/version.rb +3 -1
  43. metadata +51 -44
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 52d71ec73ddfa5dab7d22d982b27b2d4c3610080
4
- data.tar.gz: '08439390a2e4a08d8619eba08b7b66a2814372b1'
2
+ SHA256:
3
+ metadata.gz: fa755fd2e7ed97279b094dfa28bd668aef4ee638005f0b38405066502fc8a30d
4
+ data.tar.gz: 56b0d51796d97a89f67262c36716833d078ce19ea6b58fbb83c2f8bee88b8685
5
5
  SHA512:
6
- metadata.gz: c69c741edae030e7a775dcad768fa983c627cda1d849947c079d45148453a018cbba249abd18faced059b4c4cdc793e746d707e178b2e845804e7bb9a4c70437
7
- data.tar.gz: fc8cc5926cba54d561822b3a75b57c8721b1113ef16117f455c8a91f651dbad16ced7f6e09209d2adcd7a8183f4a1f8d327aa490652fe5f8ee7a3be187fe361a
6
+ metadata.gz: 027f57a717cb63fadeefd4a60213115a27ed51bb1eb3e6b58251690ed7c1d42335086ff4448b480296b77d395ba2e8718fa662e227394abfddaf80b19b769b74
7
+ data.tar.gz: f6aca254b4a43d6c60d5df7e6694b976de1e56fbb6d6585bd46fd17c0849820d76c81f25bbc872dc785576e05eeaaab5d0276a3f065b730988973c5073ace761
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
- [![Build Status](https://travis-ci.org/david942j/seccomp-tools.svg?branch=master)](https://travis-ci.org/david942j/seccomp-tools)
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
- Provides powerful tools for seccomp analysis.
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 analysis of seccomp in real-case.
13
+ Some features might be CTF-specific, but still useful for analyzing seccomp in real-case.
13
14
 
14
15
  ## Features
15
- * Dump - Automatically dump seccomp-bpf from binary.
16
- * Disasm - Convert bpf to human readable format.
16
+ * Dump - Automatically dumps seccomp-bpf from execution file(s).
17
+ * Disasm - Converts bpf to human readable format.
17
18
  - Simple decompile.
18
- - Show syscall names.
19
+ - Display syscall names and arguments when possible.
20
+ - Colorful!
19
21
  * Asm - Write seccomp rules is so easy!
20
- * Emu - Emulate seccomp rules.
21
- * (TODO) Solve constraints for executing syscalls (e.g. `execve/open/read/write`).
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 --help <command>' to read about a specific subcommand.
53
+ # See 'seccomp-tools <command> --help' to read about a specific subcommand.
47
54
 
48
- $ seccomp-tools --help dump
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
- Dump the seccomp bpf from an execution file.
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
- Disassemble the seccomp from raw bpf.
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
- Assemble the seccomp rules into raw bytes.
150
- Very useful when want to write custom seccomp rules.
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 use syscall names directly. See example below.
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|carray>.
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 == 0xc000003e ? next : dead
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 carray
185
- # unsigned char bpf[] = {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};
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
- Emulate seccomp given `sys_nr`, `arg0`, `arg1`, etc.
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 [stared](https://github.com/david942j/seccomp-tools/stargazers) :grimacing:
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
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'seccomp-tools/cli/cli'
4
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'mkmf'
2
4
 
3
5
  extension_name = 'seccomp-tools/ptrace'
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
- long val = ptrace(PTRACE_PEEKUSER, NUM2LONG(pid), NUM2LONG(off), NULL);
22
- return LONG2NUM(val);
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
- /* ptrace wrapper */
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
- rb_define_module_function(mPtrace, "peekuser", ptrace_peekuser, 3);
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(<<EOS)
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? # TODO: show warning
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